src/gui/kernel/qwidget_qws.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/kernel/qwidget_qws.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,1196 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcursor.h"
+#include "qapplication.h"
+#include "qapplication_p.h"
+#include "qpainter.h"
+#include "qbitmap.h"
+#include "qimage.h"
+#include "qhash.h"
+#include "qstack.h"
+#include "qlayout.h"
+#include "qtextcodec.h"
+#include "qinputcontext.h"
+#include "qdesktopwidget.h"
+
+#include "qwsdisplay_qws.h"
+#include "private/qwsdisplay_qws_p.h"
+#include "qscreen_qws.h"
+#include "qwsmanager_qws.h"
+#include <private/qwsmanager_p.h>
+#include <private/qbackingstore_p.h>
+#include <private/qwindowsurface_qws_p.h>
+#include <private/qwslock_p.h>
+#include "qpaintengine.h"
+
+#include "qdebug.h"
+
+#include "qwidget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+extern int *qt_last_x;
+extern int *qt_last_y;
+extern WId qt_last_cursor;
+extern bool qws_overrideCursor;
+extern QWidget *qt_pressGrab;
+extern QWidget *qt_mouseGrb;
+
+static QWidget *keyboardGrb = 0;
+
+static int takeLocalId()
+{
+    static int n=-1000;
+    return --n;
+}
+
+class QWSServer;
+extern QWSServer *qwsServer;
+
+static inline bool isServerProcess()
+{
+    return (qwsServer != 0);
+}
+
+/*****************************************************************************
+  QWidget member functions
+ *****************************************************************************/
+
+void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool /*destroyOldWindow*/)
+{
+    Q_Q(QWidget);
+    Qt::WindowType type = q->windowType();
+
+    // Make sure the WindowTitleHint is on if any of the title bar hints are set
+    // Note: This might be moved to cross-platform QWidgetPrivate::adjustFlags()
+    if (  !(data.window_flags & Qt::CustomizeWindowHint) && (
+           (data.window_flags & Qt::WindowSystemMenuHint) ||
+           (data.window_flags & Qt::WindowContextHelpButtonHint) ||
+           (data.window_flags & Qt::WindowMinimizeButtonHint) ||
+           (data.window_flags & Qt::WindowMaximizeButtonHint) ||
+           (data.window_flags & Qt::WindowCloseButtonHint) ) ) {
+        data.window_flags |= Qt::WindowTitleHint;
+    }
+
+    // Decoration plugins on QWS don't support switching on the close button on its own
+    if (data.window_flags & Qt::WindowCloseButtonHint)
+        data.window_flags |= Qt::WindowSystemMenuHint;
+
+    Qt::WindowFlags flags = data.window_flags;
+
+    data.alloc_region_index = -1;
+
+    // we don't have a "Drawer" window type
+    if (type == Qt::Drawer) {
+        type = Qt::Widget;
+        flags &= ~Qt::WindowType_Mask;
+    }
+
+
+    bool topLevel = (flags & Qt::Window);
+    bool popup = (type == Qt::Popup);
+    bool dialog = (type == Qt::Dialog
+                   || type == Qt::Sheet
+                   || (flags & Qt::MSWindowsFixedSizeDialogHint));
+    bool desktop = (type == Qt::Desktop);
+    bool tool = (type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip);
+
+
+#ifndef QT_NO_WARNING_OUTPUT
+    static bool toolWarningShown = false;
+    if (!toolWarningShown && type == Qt::Tool && !(flags & Qt::FramelessWindowHint)) {
+        qWarning("Qt for Embedded Linux " QT_VERSION_STR " does not support tool windows with frames.\n"
+                 "This behavior will change in a later release. To ensure compatibility with\n"
+                 "future versions, use (Qt::Tool | Qt::FramelessWindowHint).");
+        toolWarningShown = true;
+    }
+#endif
+
+    WId           id;
+    QWSDisplay* dpy = QWidget::qwsDisplay();
+
+    if (!window)                                // always initialize
+        initializeWindow = true;
+
+    // use the size of the primary screen to determine the default window size
+    QList<QScreen *> screens = qt_screen->subScreens();
+    if (screens.isEmpty())
+        screens.append(qt_screen);
+    int sw = screens[0]->width();
+    int sh = screens[0]->height();
+
+    if (desktop) {                                // desktop widget
+        dialog = popup = false;                        // force these flags off
+        data.crect.setRect(0, 0, sw, sh);
+    } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
+        int width = sw / 2;
+        int height = 4 * sh / 10;
+        if (extra) {
+            width = qMax(qMin(width, extra->maxw), extra->minw);
+            height = qMax(qMin(height, extra->maxh), extra->minh);
+        }
+        data.crect.setSize(QSize(width, height));
+    }
+
+    if (window) {                                // override the old window
+        id = window;
+        setWinId(window);
+    } else if (desktop) {                        // desktop widget
+        id = (WId)-2;                                // id = root window
+#if 0
+        QWidget *otherDesktop = q->find(id);        // is there another desktop?
+        if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
+            otherDesktop->d_func()->setWinId(0);        // remove id from widget mapper
+            setWinId(id);                        // make sure otherDesktop is
+            otherDesktop->d_func()->setWinId(id);        //   found first
+        } else
+#endif
+        {
+            setWinId(id);
+        }
+    } else {
+        id = topLevel ? dpy->takeId() : takeLocalId();
+        setWinId(id);                                // set widget id/handle + hd
+    }
+
+
+    bool hasFrame = true;
+    if (topLevel) {
+        if (desktop || popup || tool || q->testAttribute(Qt::WA_DontShowOnScreen))
+            hasFrame = false;
+        else
+            hasFrame = !(flags & Qt::FramelessWindowHint);
+    }
+    if (desktop) {
+        q->setAttribute(Qt::WA_WState_Visible);
+    } else if (topLevel) {                        // set X cursor
+        //QCursor *oc = QApplication::overrideCursor();
+        if (initializeWindow) {
+            //XXX XDefineCursor(dpy, winid, oc ? oc->handle() : cursor().handle());
+        }
+        QWidget::qwsDisplay()->nameRegion(q->internalWinId(), q->objectName(), q->windowTitle());
+    }
+
+    if (topLevel) {
+        createTLExtra();
+        QTLWExtra *topextra = extra->topextra;
+#ifndef QT_NO_QWS_MANAGER
+        if (hasFrame) {
+            // get size of wm decoration and make the old crect the new frect
+            QRect cr = data.crect;
+            QRegion r = QApplication::qwsDecoration().region(q, cr) | cr;
+            QRect br(r.boundingRect());
+            topextra->frameStrut.setCoords(cr.x() - br.x(),
+                                                  cr.y() - br.y(),
+                                                  br.right() - cr.right(),
+                                                  br.bottom() - cr.bottom());
+            if (!q->testAttribute(Qt::WA_Moved) || topextra->posFromMove)
+                data.crect.translate(topextra->frameStrut.left(), topextra->frameStrut.top());
+            if (!topData()->qwsManager) {
+                topData()->qwsManager = new QWSManager(q);
+                if((q->data->window_state & ~Qt::WindowActive) == Qt::WindowMaximized)
+                    topData()->qwsManager->maximize();
+            }
+
+        } else if (topData()->qwsManager) {
+            delete topData()->qwsManager;
+            topData()->qwsManager = 0;
+            data.crect.translate(-topextra->frameStrut.left(), -topextra->frameStrut.top());
+            topextra->frameStrut.setCoords(0, 0, 0, 0);
+        }
+#endif
+        if (!topextra->caption.isEmpty())
+            setWindowTitle_helper(topextra->caption);
+
+        //XXX If we are session managed, inform the window manager about it
+    } else {
+        if (extra && extra->topextra)        { // already allocated due to reparent?
+            extra->topextra->frameStrut.setCoords(0, 0, 0, 0);
+        }
+        //updateRequestedRegion(mapToGlobal(QPoint(0,0)));
+    }
+}
+
+
+void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
+{
+    Q_D(QWidget);
+
+    if (!isWindow() && parentWidget())
+        parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
+
+    d->deactivateWidgetCleanup();
+    if (testAttribute(Qt::WA_WState_Created)) {
+        setAttribute(Qt::WA_WState_Created, false);
+        QObjectList childObjects =  children();
+        for (int i = 0; i < childObjects.size(); ++i) {
+            QObject *obj = childObjects.at(i);
+            if (obj->isWidgetType())
+                static_cast<QWidget*>(obj)->destroy(destroySubWindows,
+                                                     destroySubWindows);
+        }
+        releaseMouse();
+        if (qt_pressGrab == this)
+          qt_pressGrab = 0;
+
+        if (keyboardGrb == this)
+            releaseKeyboard();
+        if (testAttribute(Qt::WA_ShowModal))                // just be sure we leave modal
+            QApplicationPrivate::leaveModal(this);
+        else if ((windowType() == Qt::Popup))
+            qApp->d_func()->closePopup(this);
+
+        if (d->ic) {
+            delete d->ic;
+            d->ic =0;
+        } else {
+            // release previous focus information participating with
+            // preedit preservation of qic -- while we still have a winId
+            QInputContext *qic = inputContext();
+            if (qic)
+                qic->widgetDestroyed(this);
+        }
+
+        if ((windowType() == Qt::Desktop)) {
+        } else {
+            if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
+                d->hide_sys();
+            }
+            if (destroyWindow && isWindow()) {
+                if (d->extra && d->extra->topextra && d->extra->topextra->backingStore)
+                    d->extra->topextra->backingStore->windowSurface->setGeometry(QRect());
+                qwsDisplay()->destroyRegion(internalWinId());
+            }
+        }
+        QT_TRY {
+            d->setWinId(0);
+        } QT_CATCH (const std::bad_alloc &) {
+            // swallow - destructors must not throw
+        }
+    }
+}
+
+
+void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
+{
+    Q_Q(QWidget);
+    bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
+     if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
+        q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+#ifndef QT_NO_CURSOR
+    QCursor oldcurs;
+    bool setcurs=q->testAttribute(Qt::WA_SetCursor);
+    if (setcurs) {
+        oldcurs = q->cursor();
+        q->unsetCursor();
+    }
+#endif
+
+    WId old_winid = data.winid;
+    if ((q->windowType() == Qt::Desktop))
+        old_winid = 0;
+
+    if (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_WState_Created))
+        hide_sys();
+
+    setWinId(0);
+
+    if (parent != newparent) {
+        QWidget *oldparent = q->parentWidget();
+        QObjectPrivate::setParent_helper(newparent);
+        if (oldparent) {
+//            oldparent->d_func()->setChildrenAllocatedDirty();
+//            oldparent->data->paintable_region_dirty = true;
+        }
+        if (newparent) {
+//            newparent->d_func()->setChildrenAllocatedDirty();
+//            newparent->data->paintable_region_dirty = true;
+            //@@@@@@@
+        }
+    }
+    Qt::FocusPolicy fp = q->focusPolicy();
+    QSize    s            = q->size();
+    //QBrush   bgc    = background();                        // save colors
+    bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
+
+    data.window_flags = f;
+    q->setAttribute(Qt::WA_WState_Created, false);
+    q->setAttribute(Qt::WA_WState_Visible, false);
+    q->setAttribute(Qt::WA_WState_Hidden, false);
+    adjustFlags(data.window_flags, q);
+    // keep compatibility with previous versions, we need to preserve the created state
+    // (but we recreate the winId for the widget being reparented, again for compatibility)
+    if (wasCreated || (!q->isWindow() && newparent->testAttribute(Qt::WA_WState_Created)))
+        createWinId();
+    if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
+        q->setAttribute(Qt::WA_WState_Hidden);
+    q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
+
+    if (q->isWindow()) {
+        QRect fs = frameStrut();
+        data.crect = QRect(fs.left(), fs.top(), s.width(), s.height());
+        if ((data.window_flags & Qt::FramelessWindowHint) && extra && extra->topextra)
+            extra->topextra->frameStrut.setCoords(0, 0, 0, 0);
+    } else {
+        data.crect = QRect(0, 0, s.width(), s.height());
+    }
+
+    q->setFocusPolicy(fp);
+    if (extra && !extra->mask.isEmpty()) {
+        QRegion r = extra->mask;
+        extra->mask = QRegion();
+        q->setMask(r);
+    }
+    if ((int)old_winid > 0) {
+        QWidget::qwsDisplay()->destroyRegion(old_winid);
+        extra->topextra->backingStore->windowSurface->setGeometry(QRect());
+    }
+#ifndef QT_NO_CURSOR
+    if (setcurs) {
+        q->setCursor(oldcurs);
+    }
+#endif
+}
+
+
+QPoint QWidget::mapToGlobal(const QPoint &pos) const
+{
+    int           x=pos.x(), y=pos.y();
+    const QWidget* w = this;
+    while (w) {
+        x += w->data->crect.x();
+        y += w->data->crect.y();
+        w = w->isWindow() ? 0 : w->parentWidget();
+    }
+    return QPoint(x, y);
+}
+
+QPoint QWidget::mapFromGlobal(const QPoint &pos) const
+{
+    int           x=pos.x(), y=pos.y();
+    const QWidget* w = this;
+    while (w) {
+        x -= w->data->crect.x();
+        y -= w->data->crect.y();
+        w = w->isWindow() ? 0 : w->parentWidget();
+    }
+    return QPoint(x, y);
+}
+
+#if 0 // #####
+void QWidget::setMicroFocusHint(int x, int y, int width, int height,
+                                 bool text, QFont *)
+{
+    if (QRect(x, y, width, height) != microFocusHint()) {
+        d->createExtra();
+        d->extra->micro_focus_hint.setRect(x, y, width, height);
+    }
+#ifndef QT_NO_QWS_INPUTMETHODS
+    if (text) {
+        QWidget *tlw = window();
+        int winid = tlw->internalWinId();
+        QPoint p(x, y + height);
+        QPoint gp = mapToGlobal(p);
+
+        QRect r = QRect(mapToGlobal(QPoint(0,0)),
+                         size());
+
+        r.setBottom(tlw->geometry().bottom());
+
+        //qDebug("QWidget::setMicroFocusHint %d %d %d %d", r.x(),
+        //        r.y(), r.width(), r.height());
+        QInputContext::setMicroFocusWidget(this);
+
+        qwsDisplay()->setIMInfo(winid, gp.x(), gp.y(), r);
+
+        //send font info,  ###if necessary
+        qwsDisplay()->setInputFont(winid, font());
+    }
+#endif
+}
+#endif
+
+void QWidgetPrivate::updateSystemBackground() {}
+
+#ifndef QT_NO_CURSOR
+void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
+{
+    Q_UNUSED(cursor);
+    Q_Q(QWidget);
+    if (q->isVisible())
+        updateCursor();
+}
+
+void QWidgetPrivate::unsetCursor_sys()
+{
+    Q_Q(QWidget);
+    if (q->isVisible())
+        updateCursor();
+}
+#endif //QT_NO_CURSOR
+
+void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
+{
+    Q_Q(QWidget);
+    QWidget::qwsDisplay()->setWindowCaption(q, caption);
+}
+
+void QWidgetPrivate::setWindowIcon_sys(bool /*forceReset*/)
+{
+#if 0
+     QTLWExtra* x = d->topData();
+     delete x->icon;
+     x->icon = 0;
+    QBitmap mask;
+    if (unscaledPixmap.isNull()) {
+    } else {
+        QImage unscaledIcon = unscaledPixmap.toImage();
+        QPixmap pixmap =
+            QPixmap::fromImage(unscaledIcon.scale(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+        x->icon = new QPixmap(pixmap);
+        mask = pixmap.mask() ? *pixmap.mask() : pixmap.createHeuristicMask();
+    }
+#endif
+}
+
+void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
+{
+    Q_UNUSED(iconText);
+}
+
+void QWidget::grabMouse()
+{
+    if (qt_mouseGrb)
+        qt_mouseGrb->releaseMouse();
+
+    qwsDisplay()->grabMouse(this,true);
+
+    qt_mouseGrb = this;
+    qt_pressGrab = 0;
+}
+
+#ifndef QT_NO_CURSOR
+void QWidget::grabMouse(const QCursor &cursor)
+{
+    if (qt_mouseGrb)
+        qt_mouseGrb->releaseMouse();
+
+    qwsDisplay()->grabMouse(this,true);
+    qwsDisplay()->selectCursor(this, cursor.handle());
+    qt_mouseGrb = this;
+    qt_pressGrab = 0;
+}
+#endif
+
+void QWidget::releaseMouse()
+{
+    if (qt_mouseGrb == this) {
+        qwsDisplay()->grabMouse(this,false);
+        qt_mouseGrb = 0;
+    }
+}
+
+void QWidget::grabKeyboard()
+{
+    if (keyboardGrb)
+        keyboardGrb->releaseKeyboard();
+    qwsDisplay()->grabKeyboard(this, true);
+    keyboardGrb = this;
+}
+
+void QWidget::releaseKeyboard()
+{
+    if (keyboardGrb == this) {
+        qwsDisplay()->grabKeyboard(this, false);
+        keyboardGrb = 0;
+    }
+}
+
+
+QWidget *QWidget::mouseGrabber()
+{
+    if (qt_mouseGrb)
+        return qt_mouseGrb;
+    return qt_pressGrab;
+}
+
+
+QWidget *QWidget::keyboardGrabber()
+{
+    return keyboardGrb;
+}
+
+void QWidget::activateWindow()
+{
+    QWidget *tlw = window();
+    if (tlw->isVisible()) {
+        Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
+        qwsDisplay()->requestFocus(tlw->internalWinId(), true);
+    }
+}
+
+void QWidgetPrivate::show_sys()
+{
+    Q_Q(QWidget);
+    q->setAttribute(Qt::WA_Mapped);
+    if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
+        invalidateBuffer(q->rect());
+        return;
+    }
+
+    if (q->isWindow()) {
+
+
+        if (!q->testAttribute(Qt::WA_ShowWithoutActivating)
+            && q->windowType() != Qt::Popup
+            && q->windowType() != Qt::Tool
+            && q->windowType() != Qt::ToolTip) {
+            QWidget::qwsDisplay()->requestFocus(data.winid,true);
+        }
+
+
+        if (QWindowSurface *surface = q->windowSurface()) {
+            const QRect frameRect = q->frameGeometry();
+            if (surface->geometry() != frameRect)
+                surface->setGeometry(frameRect);
+        }
+
+        QRegion r = localRequestedRegion();
+#ifndef QT_NO_QWS_MANAGER
+        if (extra && extra->topextra && extra->topextra->qwsManager) {
+            r.translate(data.crect.topLeft());
+            r += extra->topextra->qwsManager->region();
+            r.translate(-data.crect.topLeft());
+        }
+#endif
+        data.fstrut_dirty = true;
+        invalidateBuffer(r);
+	bool staysontop =
+            (q->windowFlags() & Qt::WindowStaysOnTopHint)
+            || q->windowType() == Qt::Popup;
+        if (!staysontop && q->parentWidget()) { // if our parent stays on top, so must we
+            QWidget *ptl = q->parentWidget()->window();
+            if (ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
+                staysontop = true;
+        }
+
+        QWSChangeAltitudeCommand::Altitude altitude;
+        altitude = staysontop ? QWSChangeAltitudeCommand::StaysOnTop : QWSChangeAltitudeCommand::Raise;
+        QWidget::qwsDisplay()->setAltitude(data.winid, altitude, true);
+        if (!q->objectName().isEmpty()) {
+            QWidget::qwsDisplay()->setWindowCaption(q, q->windowTitle());
+        }
+    }
+#ifdef Q_BACKINGSTORE_SUBSURFACES
+    else if ( extra && extra->topextra && extra->topextra->windowSurface) {
+        QWSWindowSurface *surface;
+        surface = static_cast<QWSWindowSurface*>(q->windowSurface());
+        const QPoint p = q->mapToGlobal(QPoint());
+        surface->setGeometry(QRect(p, q->size()));
+    }
+#endif
+
+    if (!q->window()->data->in_show) {
+         invalidateBuffer(q->rect());
+    }
+}
+
+
+void QWidgetPrivate::hide_sys()
+{
+    Q_Q(QWidget);
+    deactivateWidgetCleanup();
+
+    if (q->isWindow()) {
+        q->releaseMouse();
+//        requestWindowRegion(QRegion());
+
+        if (extra->topextra->backingStore)
+            extra->topextra->backingStore->releaseBuffer();
+
+
+        QWidget::qwsDisplay()->requestFocus(data.winid,false);
+    } else {
+        QWidget *p = q->parentWidget();
+        if (p &&p->isVisible()) {
+            invalidateBuffer(q->rect());
+        }
+    }
+}
+
+
+
+static Qt::WindowStates effectiveState(Qt::WindowStates state)
+ {
+     if (state & Qt::WindowMinimized)
+         return Qt::WindowMinimized;
+     else if (state & Qt::WindowFullScreen)
+         return Qt::WindowFullScreen;
+     else if (state & Qt::WindowMaximized)
+         return Qt::WindowMaximized;
+     return Qt::WindowNoState;
+ }
+
+void QWidgetPrivate::setMaxWindowState_helper()
+{
+    // in_set_window_state is usually set in setWindowState(), but this
+    // function is used in other functions as well
+    // (e.g QApplicationPrivate::setMaxWindowRect())
+    const uint old_state = data.in_set_window_state;
+    data.in_set_window_state = 1;
+
+#ifndef QT_NO_QWS_MANAGER
+    if (extra && extra->topextra && extra->topextra->qwsManager)
+        extra->topextra->qwsManager->maximize();
+    else
+#endif
+    {
+        Q_Q(QWidget);
+        const QDesktopWidget *desktop = QApplication::desktop();
+        const int screen = desktop->screenNumber(q);
+        const QRect maxWindowRect = desktop->availableGeometry(screen);
+        q->setGeometry(maxWindowRect);
+    }
+    data.in_set_window_state = old_state;
+}
+
+void QWidgetPrivate::setFullScreenSize_helper()
+{
+    Q_Q(QWidget);
+
+    const uint old_state = data.in_set_window_state;
+    data.in_set_window_state = 1;
+
+    const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
+    q->move(screen.topLeft());
+    q->resize(screen.size());
+
+    data.in_set_window_state = old_state;
+}
+
+void QWidget::setWindowState(Qt::WindowStates newstate)
+{
+    Q_D(QWidget);
+    Qt::WindowStates oldstate = windowState();
+    if (oldstate == newstate)
+        return;
+    if (isWindow() && !testAttribute(Qt::WA_WState_Created))
+        create();
+
+    data->window_state = newstate;
+    data->in_set_window_state = 1;
+    bool needShow = false;
+    Qt::WindowStates newEffectiveState = effectiveState(newstate);
+    Qt::WindowStates oldEffectiveState = effectiveState(oldstate);
+    if (isWindow() && newEffectiveState != oldEffectiveState) {
+        d->createTLExtra();
+        if (oldEffectiveState == Qt::WindowNoState) { //normal
+            d->topData()->normalGeometry = geometry();
+        } else if (oldEffectiveState == Qt::WindowFullScreen) {
+            setParent(0, d->topData()->savedFlags);
+            needShow = true;
+        } else if (oldEffectiveState == Qt::WindowMinimized) {
+            needShow = true;
+        }
+
+        if (newEffectiveState == Qt::WindowMinimized) {
+            //### not ideal...
+            hide();
+            needShow = false;
+        } else if (newEffectiveState == Qt::WindowFullScreen) {
+            d->topData()->savedFlags = windowFlags();
+            setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
+            d->setFullScreenSize_helper();
+            raise();
+            needShow = true;
+        } else if (newEffectiveState == Qt::WindowMaximized) {
+            createWinId();
+            d->setMaxWindowState_helper();
+        } else { //normal
+            QRect r = d->topData()->normalGeometry;
+            if (r.width() >= 0) {
+                d->topData()->normalGeometry = QRect(0,0,-1,-1);
+                setGeometry(r);
+            }
+        }
+    }
+    data->in_set_window_state = 0;
+
+    if (needShow)
+        show();
+
+    if (newstate & Qt::WindowActive)
+        activateWindow();
+
+    QWindowStateChangeEvent e(oldstate);
+    QApplication::sendEvent(this, &e);
+}
+
+void QWidgetPrivate::setFocus_sys()
+{
+
+}
+
+void QWidgetPrivate::raise_sys()
+{
+    Q_Q(QWidget);
+    //@@@ transaction
+    if (q->isWindow()) {
+        Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+        QWidget::qwsDisplay()->setAltitude(q->internalWinId(),
+                                           QWSChangeAltitudeCommand::Raise);
+        // XXX: subsurfaces?
+#ifdef QT_NO_WINDOWGROUPHINT
+#else
+        QObjectList childObjects =  q->children();
+        if (!childObjects.isEmpty()) {
+            QWidgetList toraise;
+            for (int i = 0; i < childObjects.size(); ++i) {
+                QObject *obj = childObjects.at(i);
+                if (obj->isWidgetType()) {
+                    QWidget* w = static_cast<QWidget*>(obj);
+                    if (w->isWindow())
+                        toraise.append(w);
+                }
+            }
+
+            for (int i = 0; i < toraise.size(); ++i) {
+                QWidget *w = toraise.at(i);
+                if (w->isVisible())
+                    w->raise();
+            }
+        }
+#endif // QT_NO_WINDOWGROUPHINT
+    }
+}
+
+void QWidgetPrivate::lower_sys()
+{
+    Q_Q(QWidget);
+    if (q->isWindow()) {
+        Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+        QWidget::qwsDisplay()->setAltitude(data.winid,
+                                           QWSChangeAltitudeCommand::Lower);
+    } else if (QWidget *p = q->parentWidget()) {
+        setDirtyOpaqueRegion();
+        p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+    }
+}
+
+void QWidgetPrivate::stackUnder_sys(QWidget*)
+{
+    Q_Q(QWidget);
+    if (QWidget *p = q->parentWidget()) {
+        setDirtyOpaqueRegion();
+        p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+    }
+}
+
+void QWidgetPrivate::moveSurface(QWindowSurface *surface, const QPoint &offset)
+{
+    QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surface);
+    if (!s->move(offset))
+        s->invalidateBuffer();
+
+    QWSDisplay::instance()->moveRegion(s->winId(), offset.x(), offset.y());
+}
+
+void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
+{
+    Q_Q(QWidget);
+    if (extra) {                                // any size restrictions?
+        w = qMin(w,extra->maxw);
+        h = qMin(h,extra->maxh);
+        w = qMax(w,extra->minw);
+        h = qMax(h,extra->minh);
+    }
+
+    QPoint oldp = q->geometry().topLeft();
+    QSize olds = q->size();
+    QRect r(x, y, w, h);
+
+    bool isResize = olds != r.size();
+    isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
+
+    // We only care about stuff that changes the geometry, or may
+    // cause the window manager to change its state
+    if (r.size() == olds && oldp == r.topLeft())
+        return;
+
+    if (!data.in_set_window_state) {
+        q->data->window_state &= ~Qt::WindowMaximized;
+        q->data->window_state &= ~Qt::WindowFullScreen;
+        if (q->isWindow())
+            topData()->normalGeometry = QRect(0, 0, -1, -1);
+    }
+    QPoint oldPos = q->pos();
+    data.crect = r;
+
+    if ((q->windowType() == Qt::Desktop))
+        return;
+
+    if (q->isVisible()) {
+
+        bool toplevelMove = false;
+        QWSWindowSurface *surface = 0;
+
+        if (q->isWindow()) {
+            //### ConfigPending not implemented, do we need it?
+            //setAttribute(Qt::WA_WState_ConfigPending);
+            const QWidgetBackingStore *bs = maybeBackingStore();
+            if (bs)
+                surface = static_cast<QWSWindowSurface*>(bs->windowSurface);
+            if (isMove && !isResize && surface) {
+                const QPoint offset(x - oldp.x(), y - oldp.y());
+                moveSurface(surface, offset);
+                toplevelMove = true; //server moves window, but we must send moveEvent, which might trigger painting
+
+#ifdef Q_BACKINGSTORE_SUBSURFACES
+                QList<QWindowSurface*> surfaces = bs->subSurfaces;
+                for (int i = 0; i < surfaces.size(); ++i)
+                    moveSurface(surfaces.at(i), offset);
+#endif
+            } else {
+                    updateFrameStrut();
+            }
+        }
+
+        if (!toplevelMove) {
+            if (q->isWindow()) {
+                if (surface)
+                    surface->setGeometry(q->frameGeometry());
+                else
+                    invalidateBuffer(q->rect()); //###
+
+#ifdef Q_BACKINGSTORE_SUBSURFACES
+                // XXX: should not resize subsurfaces. Children within a layout
+                // will be resized automatically while children with a static
+                // geometry should get a new clip region instead.
+                const QRect clipRect = q->geometry();
+                QWidgetBackingStore *bs = maybeBackingStore();
+                QList<QWindowSurface*> surfaces = bs->subSurfaces;
+                for (int i = 0; i < surfaces.size(); ++i) {
+                    QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surfaces.at(i));
+                    QRect srect = s->geometry();
+                    s->setGeometry(clipRect & srect);
+                }
+#endif
+            }
+#ifdef Q_BACKINGSTORE_SUBSURFACES
+            // XXX: merge this case with the isWindow() case
+            else if (maybeTopData() && maybeTopData()->windowSurface) {
+                QWSWindowSurface *surface;
+                surface = static_cast<QWSWindowSurface*>(q->windowSurface());
+                if (isMove && !isResize) {
+                    moveSurface(surface, QPoint(x - oldp.x(), y - oldp.y()));
+                } else {
+                    const QPoint p = q->mapToGlobal(QPoint());
+                    surface->setGeometry(QRect(p, QSize(w, h)));
+                }
+            }
+#endif
+            else {
+                if (isMove && !isResize)
+                    moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
+                else
+                    invalidateBuffer_resizeHelper(oldPos, olds);
+            }
+        }
+
+        //### must have frame geometry correct before sending move/resize events
+        if (isMove) {
+            QMoveEvent e(q->pos(), oldPos);
+            QApplication::sendEvent(q, &e);
+        }
+        if (isResize) {
+            QResizeEvent e(r.size(), olds);
+            QApplication::sendEvent(q, &e);
+        }
+
+    } else { // not visible
+        if (isMove && q->pos() != oldPos)
+            q->setAttribute(Qt::WA_PendingMoveEvent, true);
+        if (isResize)
+            q->setAttribute(Qt::WA_PendingResizeEvent, true);
+    }
+}
+
+void QWidgetPrivate::setConstraints_sys()
+{
+}
+
+QScreen* QWidgetPrivate::getScreen() const
+{
+    Q_Q(const QWidget);
+
+    const QList<QScreen*> subScreens = qt_screen->subScreens();
+    if (subScreens.isEmpty() || q->windowType() == Qt::Desktop)
+        return qt_screen;
+
+    const int screen = QApplication::desktop()->screenNumber(q);
+
+    return qt_screen->subScreens().at(screen < 0 ? 0 : screen);
+}
+
+void QWidgetPrivate::scroll_sys(int dx, int dy)
+{
+    Q_Q(QWidget);
+    scrollChildren(dx, dy);
+    scrollRect(q->rect(), dx, dy);
+}
+
+void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
+{
+    scrollRect(r, dx, dy);
+}
+
+int QWidget::metric(PaintDeviceMetric m) const
+{
+    Q_D(const QWidget);
+
+    int val;
+    if (m == PdmWidth) {
+        val = data->crect.width();
+    } else if (m == PdmWidthMM) {
+        const QScreen *screen = d->getScreen();
+        val = data->crect.width() * screen->physicalWidth() / screen->width();
+    } else if (m == PdmHeight) {
+        val = data->crect.height();
+    } else if (m == PdmHeightMM) {
+        const QScreen *screen = d->getScreen();
+        val = data->crect.height() * screen->physicalHeight() / screen->height();
+    } else if (m == PdmDepth) {
+        return qwsDisplay()->depth();
+    } else if (m == PdmDpiX || m == PdmPhysicalDpiX) {
+        if (d->extra && d->extra->customDpiX)
+            return d->extra->customDpiX;
+        else if (d->parent)
+            return static_cast<QWidget *>(d->parent)->metric(m);
+        const QScreen *screen = d->getScreen();
+        return qRound(screen->width() / double(screen->physicalWidth() / 25.4));
+    } else if (m == PdmDpiY || m == PdmPhysicalDpiY) {
+        if (d->extra && d->extra->customDpiY)
+            return d->extra->customDpiY;
+        else if (d->parent)
+            return static_cast<QWidget *>(d->parent)->metric(m);
+        const QScreen *screen = d->getScreen();
+        return qRound(screen->height() / double(screen->physicalHeight() / 25.4));
+    } else {
+        val = QPaintDevice::metric(m);// XXX
+    }
+    return val;
+}
+
+void QWidgetPrivate::createSysExtra()
+{
+}
+
+void QWidgetPrivate::deleteSysExtra()
+{
+}
+
+void QWidgetPrivate::createTLSysExtra()
+{
+#ifndef QT_NO_QWS_MANAGER
+    extra->topextra->qwsManager = 0;
+#endif
+}
+
+void QWidgetPrivate::deleteTLSysExtra()
+{
+}
+
+void QWidgetPrivate::registerDropSite(bool on)
+{
+    Q_UNUSED(on);
+}
+
+QRegion QWidgetPrivate::localRequestedRegion() const
+{
+    Q_Q(const QWidget);
+    QRegion r(q->rect());
+    if (extra && !extra->mask.isEmpty())
+        r &= extra->mask;
+
+    return r;
+}
+
+QRegion QWidgetPrivate::localAllocatedRegion() const
+{
+    Q_Q(const QWidget);
+
+    QWidgetBackingStore *wbs = q->window()->d_func()->maybeBackingStore();
+
+    QWindowSurface *ws = wbs ? wbs->windowSurface : 0;
+    if (!ws)
+        return QRegion();
+    QRegion r = static_cast<QWSWindowSurface*>(ws)->clipRegion();
+    if (!q->isWindow()) {
+        QPoint off = q->mapTo(q->window(), QPoint());
+        r &= localRequestedRegion().translated(off);
+        r.translate(-off);
+    }
+    return r;
+}
+
+inline bool QRect::intersects(const QRect &r) const
+{
+    return (qMax(x1, r.x1) <= qMin(x2, r.x2) &&
+             qMax(y1, r.y1) <= qMin(y2, r.y2));
+}
+
+void QWidgetPrivate::setMask_sys(const QRegion &region)
+{
+    Q_UNUSED(region);
+    Q_Q(QWidget);
+
+    if (!q->isVisible() || !q->isWindow())
+        return;
+
+    data.fstrut_dirty = true;
+    invalidateBuffer(q->rect());
+    QWindowSurface *surface = extra->topextra->backingStore->windowSurface;
+    if (surface) {
+        // QWSWindowSurface::setGeometry() returns without doing anything
+        // if old geom  == new geom. Therefore, we need to reset the old value.
+        surface->QWindowSurface::setGeometry(QRect());
+        surface->setGeometry(q->frameGeometry());
+    }
+}
+
+void QWidgetPrivate::updateFrameStrut()
+{
+    Q_Q(QWidget);
+
+    if(!q->isVisible() || (q->windowType() == Qt::Desktop)) {
+        data.fstrut_dirty = q->isVisible();
+        return;
+    }
+
+#ifndef QT_NO_QWS_MANAGER
+    if (extra && extra->topextra && extra->topextra->qwsManager) {
+        QTLWExtra *topextra = extra->topextra;
+        const QRect oldFrameStrut = topextra->frameStrut;
+        const QRect contents = data.crect;
+        QRegion r = localRequestedRegion().translated(contents.topLeft());
+        r += extra->topextra->qwsManager->region();
+        const QRect frame = r.boundingRect();
+
+        topextra->frameStrut.setCoords(contents.left() - frame.left(),
+                                       contents.top() - frame.top(),
+                                       frame.right() - contents.right(),
+                                       frame.bottom() - contents.bottom());
+        topextra->qwsManager->repaintRegion(QDecoration::All, QDecoration::Normal);
+    }
+#endif
+    data.fstrut_dirty = false;
+}
+
+#ifndef QT_NO_CURSOR
+void QWidgetPrivate::updateCursor() const
+{
+    Q_Q(const QWidget);
+
+    if (QApplication::overrideCursor())
+        return;
+
+    if (qt_last_x
+        && (!QWidget::mouseGrabber() || QWidget::mouseGrabber() == q)
+        && qt_last_cursor != (WId)q->cursor().handle())
+    {
+        const QPoint pos(*qt_last_x, *qt_last_y);
+        const QPoint offset = q->mapToGlobal(QPoint());
+        if (!localAllocatedRegion().contains(pos - offset))
+            return;
+
+        const QWidget *w = q->childAt(q->mapFromGlobal(pos));
+        if (!w || w->cursor().handle() == q->cursor().handle())
+            QWidget::qwsDisplay()->selectCursor(const_cast<QWidget*>(q),
+                                                q->cursor().handle());
+    }
+}
+#endif
+
+void QWidgetPrivate::setWindowOpacity_sys(qreal level)
+{
+    Q_Q(QWidget);
+    Q_UNUSED(level);
+    createWinId();
+    QWidget::qwsDisplay()->setOpacity(q->data->winid, topData()->opacity);
+}
+
+//static QSingleCleanupHandler<QWSPaintEngine> qt_paintengine_cleanup_handler;
+//static QWSPaintEngine *qt_widget_paintengine = 0;
+QPaintEngine *QWidget::paintEngine() const
+{
+    qWarning("QWidget::paintEngine: Should no longer be called");
+    return 0; //##### @@@
+//     if (!qt_widget_paintengine) {
+//         qt_widget_paintengine = new QRasterPaintEngine();
+//         qt_paintengine_cleanup_handler.set(&qt_widget_paintengine);
+//     }
+//     if (qt_widget_paintengine->isActive()) {
+//         if (d->extraPaintEngine)
+//             return d->extraPaintEngine;
+//         const_cast<QWidget *>(this)->d_func()->extraPaintEngine = new QRasterPaintEngine();
+//         return d->extraPaintEngine;
+//     }
+//    return qt_widget_paintengine;
+}
+
+QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
+{
+    Q_Q(QWidget);
+    if (q->windowType() == Qt::Desktop)
+        return 0;
+    q->ensurePolished();
+    return qt_screen->createSurface(q);
+}
+
+void QWidgetPrivate::setModal_sys()
+{
+}
+
+
+QT_END_NAMESPACE