/****************************************************************************
**
** 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 "qevent.h"
#include "qwidget.h"
#include "qdesktopwidget.h"
#include "qapplication.h"
#include "qapplication_p.h"
#include "qnamespace.h"
#include "qpainter.h"
#include "qbitmap.h"
#include "qlayout.h"
#include "qtextcodec.h"
#include "qelapsedtimer.h"
#include "qcursor.h"
#include "qstack.h"
#include "qcolormap.h"
#include "qdebug.h"
#include "qmenu.h"
#include "private/qmenu_p.h"
#include "private/qbackingstore_p.h"
#include "private/qwindowsurface_x11_p.h"

//extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); //qapplication_x11.cpp

#include <private/qpixmap_x11_p.h>
#include <private/qpaintengine_x11_p.h>
#include "qt_x11_p.h"
#include "qx11info_x11.h"

#include <stdlib.h>

//#define ALIEN_DEBUG

// defined in qapplication_x11.cpp
//bool qt_wstate_iconified(WId);
//void qt_updated_rootinfo();


#if !defined(QT_NO_IM)
#include "qinputcontext.h"
#include "qinputcontextfactory.h"
#endif

#include "qwidget_p.h"

#define XCOORD_MAX 16383
#define WRECT_MAX 8191

QT_BEGIN_NAMESPACE

extern bool qt_nograb();

QWidget *QWidgetPrivate::mouseGrabber = 0;
QWidget *QWidgetPrivate::keyboardGrabber = 0;

void qt_net_remove_user_time(QWidget *tlw);
void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);

int qt_x11_create_desktop_on_screen = -1;

extern void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);

// MWM support
struct QtMWMHints {
    ulong flags, functions, decorations;
    long input_mode;
    ulong status;
};

enum {
    MWM_HINTS_FUNCTIONS   = (1L << 0),

    MWM_FUNC_ALL      = (1L << 0),
    MWM_FUNC_RESIZE   = (1L << 1),
    MWM_FUNC_MOVE     = (1L << 2),
    MWM_FUNC_MINIMIZE = (1L << 3),
    MWM_FUNC_MAXIMIZE = (1L << 4),
    MWM_FUNC_CLOSE    = (1L << 5),

    MWM_HINTS_DECORATIONS = (1L << 1),

    MWM_DECOR_ALL      = (1L << 0),
    MWM_DECOR_BORDER   = (1L << 1),
    MWM_DECOR_RESIZEH  = (1L << 2),
    MWM_DECOR_TITLE    = (1L << 3),
    MWM_DECOR_MENU     = (1L << 4),
    MWM_DECOR_MINIMIZE = (1L << 5),
    MWM_DECOR_MAXIMIZE = (1L << 6),

    MWM_HINTS_INPUT_MODE = (1L << 2),

    MWM_INPUT_MODELESS                  = 0L,
    MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
    MWM_INPUT_FULL_APPLICATION_MODAL    = 3L
};


static QtMWMHints GetMWMHints(Display *display, Window window)
{
    QtMWMHints mwmhints;

    Atom type;
    int format;
    ulong nitems, bytesLeft;
    uchar *data = 0;
    if ((XGetWindowProperty(display, window, ATOM(_MOTIF_WM_HINTS), 0, 5, false,
                            ATOM(_MOTIF_WM_HINTS), &type, &format, &nitems, &bytesLeft,
                            &data) == Success)
        && (type == ATOM(_MOTIF_WM_HINTS)
            && format == 32
            && nitems >= 5)) {
        mwmhints = *(reinterpret_cast<QtMWMHints *>(data));
    } else {
        mwmhints.flags = 0L;
        mwmhints.functions = MWM_FUNC_ALL;
        mwmhints.decorations = MWM_DECOR_ALL;
        mwmhints.input_mode = 0L;
        mwmhints.status = 0L;
    }

    if (data)
        XFree(data);

    return mwmhints;
}

static void SetMWMHints(Display *display, Window window, const QtMWMHints &mwmhints)
{
    if (mwmhints.flags != 0l) {
        XChangeProperty(display, window, ATOM(_MOTIF_WM_HINTS), ATOM(_MOTIF_WM_HINTS), 32,
                        PropModeReplace, (unsigned char *) &mwmhints, 5);
    } else {
        XDeleteProperty(display, window, ATOM(_MOTIF_WM_HINTS));
    }
}

// Returns true if we should set WM_TRANSIENT_FOR on \a w
static inline bool isTransient(const QWidget *w)
{
    return ((w->windowType() == Qt::Dialog
             || w->windowType() == Qt::Sheet
             || w->windowType() == Qt::Tool
             || w->windowType() == Qt::SplashScreen
             || w->windowType() == Qt::ToolTip
             || w->windowType() == Qt::Drawer
             || w->windowType() == Qt::Popup)
            && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
}

static void do_size_hints(QWidget* widget, QWExtra *x);

/*****************************************************************************
  QWidget member functions
 *****************************************************************************/

const uint stdWidgetEventMask =                        // X event mask
        (uint)(
            KeyPressMask | KeyReleaseMask |
            ButtonPressMask | ButtonReleaseMask |
            KeymapStateMask |
            ButtonMotionMask | PointerMotionMask |
            EnterWindowMask | LeaveWindowMask |
            FocusChangeMask |
            ExposureMask |
            PropertyChangeMask |
            StructureNotifyMask
       );

const uint stdDesktopEventMask =                        // X event mask
       (uint)(
           KeymapStateMask |
           EnterWindowMask | LeaveWindowMask |
           PropertyChangeMask
      );


/*
  The qt_ functions below are implemented in qwidgetcreate_x11.cpp.
*/

Window qt_XCreateWindow(const QWidget *creator,
                         Display *display, Window parent,
                         int x, int y, uint w, uint h,
                         int borderwidth, int depth,
                         uint windowclass, Visual *visual,
                         ulong valuemask, XSetWindowAttributes *attributes);
Window qt_XCreateSimpleWindow(const QWidget *creator,
                               Display *display, Window parent,
                               int x, int y, uint w, uint h, int borderwidth,
                               ulong border, ulong background);
void qt_XDestroyWindow(const QWidget *destroyer,
                        Display *display, Window window);


static void qt_insert_sip(QWidget* scrolled_widget, int dx, int dy)
{
    if (!scrolled_widget->isWindow() && !scrolled_widget->internalWinId())
        return;
    QX11Data::ScrollInProgress sip = { X11->sip_serial++, scrolled_widget, dx, dy };
    X11->sip_list.append(sip);

    XClientMessageEvent client_message;
    client_message.type = ClientMessage;
    client_message.window = scrolled_widget->internalWinId();
    client_message.format = 32;
    client_message.message_type = ATOM(_QT_SCROLL_DONE);
    client_message.data.l[0] = sip.id;

    XSendEvent(X11->display, scrolled_widget->internalWinId(), False, NoEventMask,
        (XEvent*)&client_message);
}

static int qt_sip_count(QWidget* scrolled_widget)
{
    int sips=0;

    for (int i = 0; i < X11->sip_list.size(); ++i) {
        const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
        if (sip.scrolled_widget == scrolled_widget)
            sips++;
    }

    return sips;
}

static void create_wm_client_leader()
{
    if (X11->wm_client_leader) return;

    X11->wm_client_leader =
        XCreateSimpleWindow(X11->display,
                             QX11Info::appRootWindow(),
                             0, 0, 1, 1, 0, 0, 0);

    // set client leader property to itself
    XChangeProperty(X11->display,
                     X11->wm_client_leader, ATOM(WM_CLIENT_LEADER),
                     XA_WINDOW, 32, PropModeReplace,
                     (unsigned char *)&X11->wm_client_leader, 1);

#ifndef QT_NO_SESSIONMANAGER
    // If we are session managed, inform the window manager about it
    QByteArray session = qApp->sessionId().toLatin1();
    if (!session.isEmpty()) {
        XChangeProperty(X11->display,
                         X11->wm_client_leader, ATOM(SM_CLIENT_ID),
                         XA_STRING, 8, PropModeReplace,
                         (unsigned char *)session.data(), session.size());
    }
#endif
}

/*!
   \internal
   Update the X11 cursor of the widget w.
   \a force is true if this function is called from dispatchEnterLeave, it means that the
   mouse is actually directly under this widget.
 */
void qt_x11_enforce_cursor(QWidget * w, bool force)
{
    if (!w->testAttribute(Qt::WA_WState_Created))
        return;

    static QPointer<QWidget> lastUnderMouse = 0;
    if (force) {
        lastUnderMouse = w;
    } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
        w = lastUnderMouse;
    } else if (!w->internalWinId()) {
        return; //the mouse is not under this widget, and it's not native, so don't change it
    }

    while (!w->internalWinId() && w->parentWidget() && !w->isWindow() && !w->testAttribute(Qt::WA_SetCursor))
        w = w->parentWidget();

    QWidget *nativeParent = w;
    if (!w->internalWinId())
        nativeParent = w->nativeParentWidget();
    // This does the same as effectiveWinId(), but since it is possible
    // to not have a native parent widget due to a special hack in
    // qwidget for reparenting widgets to a different X11 screen,
    // added additional check to make sure native parent widget exists.
    if (!nativeParent || !nativeParent->internalWinId())
        return;
    WId winid = nativeParent->internalWinId();

    if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
#ifndef QT_NO_CURSOR
        QCursor *oc = QApplication::overrideCursor();
        if (oc) {
            XDefineCursor(X11->display, winid, oc->handle());
        } else if (w->isEnabled()) {
            XDefineCursor(X11->display, winid, w->cursor().handle());
        } else {
            // enforce the windows behavior of clearing the cursor on
            // disabled widgets
            XDefineCursor(X11->display, winid, XNone);
        }
#endif
    } else {
        XDefineCursor(X11->display, winid, XNone);
    }
}

Q_GUI_EXPORT void qt_x11_enforce_cursor(QWidget * w)
{
    qt_x11_enforce_cursor(w, false);
}

Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
{
    if (!w || (!w->isWindow() && !w->internalWinId()))
        return;
    QApplication::flush();
    XEvent ev;
    QElapsedTimer t;
    t.start();
    static const int maximumWaitTime = 2000;
    if (!w->testAttribute(Qt::WA_WState_Created))
        return;

    WId winid = w->internalWinId();

    // first deliver events that are already in the local queue
    QApplication::sendPostedEvents();

    // the normal sequence is:
    //  ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose
    // with X11BypassWindowManagerHint:
    //  ConfigureNotify ... MapNotify ... Expose

    enum State {
        Initial, Mapped
    } state = Initial;

    do {
        if (XEventsQueued(X11->display, QueuedAlready)) {
            XNextEvent(X11->display, &ev);
            qApp->x11ProcessEvent(&ev);

            switch (state) {
            case Initial:
                if (ev.type == MapNotify && ev.xany.window == winid)
                    state = Mapped;
                break;
            case Mapped:
                if (ev.type == Expose && ev.xany.window == winid)
                    return;
                break;
            }
        } else {
            if (!XEventsQueued(X11->display, QueuedAfterFlush))
                qApp->syncX(); // non-busy wait
        }
        if (t.elapsed() > maximumWaitTime)
            return;
    } while(1);
}

void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)
{
    if (!w->isVisible()) // not managed by the window manager
        return;

    XEvent e;
    e.xclient.type = ClientMessage;
    e.xclient.message_type = ATOM(_NET_WM_STATE);
    e.xclient.display = X11->display;
    e.xclient.window = w->internalWinId();
    e.xclient.format = 32;
    e.xclient.data.l[0] = set ? 1 : 0;
    e.xclient.data.l[1] = one;
    e.xclient.data.l[2] = two;
    e.xclient.data.l[3] = 0;
    e.xclient.data.l[4] = 0;
    XSendEvent(X11->display, RootWindow(X11->display, w->x11Info().screen()),
               false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
}

struct QX11WindowAttributes {
    const XWindowAttributes *att;
};

void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a)
{
    QX11WindowAttributes att;
    att.att = &a;
    qt_x11_getX11InfoForWindow(xinfo,att);
}


static QVector<Atom> getNetWmState(QWidget *w)
{
    QVector<Atom> returnValue;

    // Don't read anything, just get the size of the property data
    Atom actualType;
    int actualFormat;
    ulong propertyLength;
    ulong bytesLeft;
    uchar *propertyData = 0;
    if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0, 0,
                           False, XA_ATOM, &actualType, &actualFormat,
                           &propertyLength, &bytesLeft, &propertyData) == Success
        && actualType == XA_ATOM && actualFormat == 32) {
        returnValue.resize(bytesLeft / 4);
        XFree((char*) propertyData);
        propertyData = 0;

        // fetch all data
        if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0,
                               returnValue.size(), False, XA_ATOM, &actualType, &actualFormat,
                               &propertyLength, &bytesLeft, &propertyData) != Success) {
            returnValue.clear();
        } else if (propertyLength != (ulong)returnValue.size()) {
            returnValue.resize(propertyLength);
        }

        // put it into netWmState
        if (!returnValue.isEmpty()) {
            memcpy(returnValue.data(), propertyData, returnValue.size() * sizeof(Atom));
        }
        if (propertyData)
            XFree((char*) propertyData);
    }

    return returnValue;
}

void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
{
    Q_Q(QWidget);
    Qt::WindowType type = q->windowType();
    Qt::WindowFlags &flags = data.window_flags;
    QWidget *parentWidget = q->parentWidget();

    if (type == Qt::ToolTip)
        flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
    if (type == Qt::Popup)
        flags |= Qt::X11BypassWindowManagerHint;

    bool topLevel = (flags & Qt::Window);
    bool popup = (type == Qt::Popup);
    bool dialog = (type == Qt::Dialog
                   || type == Qt::Sheet);
    bool desktop = (type == Qt::Desktop);
    bool tool = (type == Qt::Tool || type == Qt::SplashScreen
                 || type == Qt::ToolTip || type == Qt::Drawer);

#ifdef ALIEN_DEBUG
    qDebug() << "QWidgetPrivate::create_sys START:" << q << "topLevel?" << topLevel << "WId:"
             << window << "initializeWindow:" << initializeWindow << "destroyOldWindow" << destroyOldWindow;
#endif
    if (topLevel) {
        if (parentWidget) { // if our parent stays on top, so must we
            QWidget *ptl = parentWidget->window();
            if(ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
                flags |= Qt::WindowStaysOnTopHint;
        }

        if (type == Qt::SplashScreen) {
            if (X11->isSupportedByWM(ATOM(_NET_WM_WINDOW_TYPE_SPLASH))) {
                flags &= ~Qt::X11BypassWindowManagerHint;
            } else {
                flags |= Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint;
            }
        }
        // All these buttons depend on the system menu, so we enable it
        if (flags & (Qt::WindowMinimizeButtonHint
                     | Qt::WindowMaximizeButtonHint
                     | Qt::WindowContextHelpButtonHint))
            flags |= Qt::WindowSystemMenuHint;
    }


    Window parentw, destroyw = 0;
    WId id = 0;

    // always initialize
    if (!window)
        initializeWindow = true;

    QX11Info *parentXinfo = parentWidget ? &parentWidget->d_func()->xinfo : 0;

    if (desktop &&
        qt_x11_create_desktop_on_screen >= 0 &&
        qt_x11_create_desktop_on_screen != xinfo.screen()) {
        // desktop on a certain screen other than the default requested
        QX11InfoData *xd = &X11->screens[qt_x11_create_desktop_on_screen];
        xinfo.setX11Data(xd);
    } else if (parentXinfo && (parentXinfo->screen() != xinfo.screen()
                               || (parentXinfo->visual() != xinfo.visual()
                                   && !q->inherits("QGLWidget"))))
    {
        // QGLWidgets have to be excluded here as they have a
        // specially crafted QX11Info structure which can't be swapped
        // out with the parent widgets QX11Info. The parent visual,
        // for instance, might not even be GL capable.
        xinfo = *parentXinfo;
    }

    //get display, screen number, root window and desktop geometry for
    //the current screen
    Display *dpy = X11->display;
    int scr = xinfo.screen();
    Window root_win = RootWindow(dpy, scr);
    int sw = DisplayWidth(dpy,scr);
    int sh = DisplayHeight(dpy,scr);

    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)) {
        QDesktopWidget *desktopWidget = qApp->desktop();
        if (desktopWidget->isVirtualDesktop()) {
            QRect r = desktopWidget->screenGeometry();
            sw = r.width();
            sh = r.height();
        }

        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));
    }

    parentw = topLevel ? root_win : parentWidget->effectiveWinId();

    XSetWindowAttributes wsa;

    if (window) {                                // override the old window
        if (destroyOldWindow) {
            if (topLevel)
                X11->dndEnable(q, false);
            destroyw = data.winid;
        }
        id = window;
        setWinId(window);
        XWindowAttributes a;
        XGetWindowAttributes(dpy, window, &a);
        data.crect.setRect(a.x, a.y, a.width, a.height);

        if (a.map_state == IsUnmapped)
            q->setAttribute(Qt::WA_WState_Visible, false);
        else
            q->setAttribute(Qt::WA_WState_Visible);

        qt_x11_getX11InfoForWindow(&xinfo,a);

    } else if (desktop) {                        // desktop widget
#ifdef QWIDGET_EXTRA_DEBUG
        qDebug() << "create desktop";
#endif
        id = (WId)parentw;                        // id = root window
//         QWidget *otherDesktop = find(id);        // is there another desktop?
//         if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
//             otherDesktop->d->setWinId(0);        // remove id from widget mapper
//             d->setWinId(id);                     // make sure otherDesktop is
//             otherDesktop->d->setWinId(id);       // found first
//         } else {
        setWinId(id);
//         }
    } else if (topLevel || q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) {
#ifdef QWIDGET_EXTRA_DEBUG
        static int topLevels = 0;
        static int children = 0;
        if (parentw == root_win)
            qDebug() << "create toplevel" << ++topLevels;
        else
            qDebug() << "create child" << ++children;
#endif
        QRect safeRect = data.crect; //##### must handle huge sizes as well.... i.e. wrect
        if (safeRect.width() < 1|| safeRect.height() < 1) {
            if (topLevel) {
                // top-levels must be at least 1x1
                safeRect.setSize(safeRect.size().expandedTo(QSize(1, 1)));
            } else {
                // create it way off screen, and rely on
                // setWSGeometry() to do the right thing with it later
                safeRect = QRect(-1000,-1000,1,1);
            }
        }
#ifndef QT_NO_XRENDER
        int screen = xinfo.screen();
        if (topLevel && X11->use_xrender
            && xinfo.depth() != 32 && X11->argbVisuals[screen]
            && q->testAttribute(Qt::WA_TranslucentBackground))
        {
            QX11InfoData *xd = xinfo.getX11Data(true);

            xd->screen = screen;
            xd->visual = X11->argbVisuals[screen];
            xd->colormap = X11->argbColormaps[screen];
            xd->depth = 32;
            xd->defaultVisual = false;
            xd->defaultColormap = false;
            xd->cells = xd->visual->map_entries;
            xinfo.setX11Data(xd);
        }
#endif
        if (xinfo.defaultVisual() && xinfo.defaultColormap()) {
            id = (WId)qt_XCreateSimpleWindow(q, dpy, parentw,
                                             safeRect.left(), safeRect.top(),
                                             safeRect.width(), safeRect.height(),
                                             0,
                                             BlackPixel(dpy, xinfo.screen()),
                                             WhitePixel(dpy, xinfo.screen()));
        } else {
            wsa.background_pixel = WhitePixel(dpy, xinfo.screen());
            wsa.border_pixel = BlackPixel(dpy, xinfo.screen());
            wsa.colormap = xinfo.colormap();
            id = (WId)qt_XCreateWindow(q, dpy, parentw,
                                       safeRect.left(), safeRect.top(),
                                       safeRect.width(), safeRect.height(),
                                       0, xinfo.depth(), InputOutput,
                                       (Visual *) xinfo.visual(),
                                       CWBackPixel|CWBorderPixel|CWColormap,
                                       &wsa);
        }

        setWinId(id);                                // set widget id/handle + hd
    }

#ifndef QT_NO_XRENDER
    if (picture) {
        XRenderFreePicture(X11->display, picture);
        picture = 0;
    }

    if (X11->use_xrender && !desktop && q->internalWinId()) {
        XRenderPictFormat *format = XRenderFindVisualFormat(dpy, (Visual *) xinfo.visual());
        if (format)
            picture = XRenderCreatePicture(dpy, id, format, 0, 0);
    }
#endif // QT_NO_XRENDER

    QtMWMHints mwmhints;
    mwmhints.flags = 0L;
    mwmhints.functions = 0L;
    mwmhints.decorations = 0;
    mwmhints.input_mode = 0L;
    mwmhints.status = 0L;

    if (topLevel) {
        ulong wsa_mask = 0;
        if (type != Qt::SplashScreen) { // && customize) {
            mwmhints.flags |= MWM_HINTS_DECORATIONS;

            bool customize = flags & Qt::CustomizeWindowHint;
            if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
                mwmhints.decorations |= MWM_DECOR_BORDER;
                mwmhints.decorations |= MWM_DECOR_RESIZEH;

                if (flags & Qt::WindowTitleHint)
                    mwmhints.decorations |= MWM_DECOR_TITLE;

                if (flags & Qt::WindowSystemMenuHint)
                    mwmhints.decorations |= MWM_DECOR_MENU;

                if (flags & Qt::WindowMinimizeButtonHint) {
                    mwmhints.decorations |= MWM_DECOR_MINIMIZE;
                    mwmhints.functions |= MWM_FUNC_MINIMIZE;
                }

                if (flags & Qt::WindowMaximizeButtonHint) {
                    mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
                    mwmhints.functions |= MWM_FUNC_MAXIMIZE;
                }

                if (flags & Qt::WindowCloseButtonHint)
                     mwmhints.functions |= MWM_FUNC_CLOSE;
            }
        } else {
            // if type == Qt::SplashScreen
            mwmhints.decorations = MWM_DECOR_ALL;
        }

        if (tool) {
            wsa.save_under = True;
            wsa_mask |= CWSaveUnder;
        }

        if (flags & Qt::X11BypassWindowManagerHint) {
            wsa.override_redirect = True;
            wsa_mask |= CWOverrideRedirect;
        }

        if (wsa_mask && initializeWindow) {
            Q_ASSERT(id);
            XChangeWindowAttributes(dpy, id, wsa_mask, &wsa);
        }

        if (mwmhints.functions != 0) {
            mwmhints.flags |= MWM_HINTS_FUNCTIONS;
            mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
        } else {
            mwmhints.functions = MWM_FUNC_ALL;
        }

        if (!(flags & Qt::FramelessWindowHint)
            && flags & Qt::CustomizeWindowHint
            && flags & Qt::WindowTitleHint
            && !(flags &
                 (Qt::WindowMinimizeButtonHint
                  | Qt::WindowMaximizeButtonHint
                  | Qt::WindowCloseButtonHint))) {
            // a special case - only the titlebar without any button
            mwmhints.flags = MWM_HINTS_FUNCTIONS;
            mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
            mwmhints.decorations = 0;
        }
    }

    if (!initializeWindow) {
        // do no initialization
    } else if (popup) {                        // popup widget
        // set EWMH window types
        setNetWmWindowTypes();

        wsa.override_redirect = True;
        wsa.save_under = True;
        Q_ASSERT(id);
        XChangeWindowAttributes(dpy, id, CWOverrideRedirect | CWSaveUnder,
                                &wsa);
    } else if (topLevel && !desktop) {        // top-level widget
        if (!X11->wm_client_leader)
            create_wm_client_leader();

        // note: WM_TRANSIENT_FOR is set in QWidgetPrivate::show_sys()

        XSizeHints size_hints;
        size_hints.flags = USSize | PSize | PWinGravity;
        size_hints.x = data.crect.left();
        size_hints.y = data.crect.top();
        size_hints.width = data.crect.width();
        size_hints.height = data.crect.height();
        size_hints.win_gravity =
            QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;

        XWMHints wm_hints;                        // window manager hints
        memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
        wm_hints.flags = InputHint | StateHint | WindowGroupHint;
        wm_hints.input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
        wm_hints.initial_state = NormalState;
        wm_hints.window_group = X11->wm_client_leader;

        XClassHint class_hint;
        QByteArray appName = qAppName().toLatin1();
        class_hint.res_name = appName.data(); // application name
        class_hint.res_class = const_cast<char *>(QX11Info::appClass());   // application class

        XSetWMProperties(dpy, id, 0, 0,
                         qApp->d_func()->argv, qApp->d_func()->argc,
                         &size_hints, &wm_hints, &class_hint);

        XResizeWindow(dpy, id,
                      qBound(1, data.crect.width(), XCOORD_MAX),
                      qBound(1, data.crect.height(), XCOORD_MAX));
        XStoreName(dpy, id, appName.data());
        Atom protocols[5];
        int n = 0;
        protocols[n++] = ATOM(WM_DELETE_WINDOW);        // support del window protocol
        protocols[n++] = ATOM(WM_TAKE_FOCUS);                // support take focus window protocol
        protocols[n++] = ATOM(_NET_WM_PING);                // support _NET_WM_PING protocol
#ifndef QT_NO_XSYNC
        protocols[n++] = ATOM(_NET_WM_SYNC_REQUEST);        // support _NET_WM_SYNC_REQUEST protocol
#endif // QT_NO_XSYNC
        if (flags & Qt::WindowContextHelpButtonHint)
            protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP);
        XSetWMProtocols(dpy, id, protocols, n);

        // set mwm hints
        SetMWMHints(dpy, id, mwmhints);

        // set EWMH window types
        setNetWmWindowTypes();

        // set _NET_WM_PID
        long curr_pid = getpid();
        XChangeProperty(dpy, id, ATOM(_NET_WM_PID), XA_CARDINAL, 32, PropModeReplace,
                        (unsigned char *) &curr_pid, 1);

        // when we create a toplevel widget, the frame strut should be dirty
        data.fstrut_dirty = 1;

        // declare the widget's window role
        if (QTLWExtra *topData = maybeTopData()) {
            if (!topData->role.isEmpty()) {
                QByteArray windowRole = topData->role.toUtf8();
                XChangeProperty(dpy, id,
                                ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
                                (unsigned char *)windowRole.constData(), windowRole.length());
            }
        }

        // set client leader property
        XChangeProperty(dpy, id, ATOM(WM_CLIENT_LEADER),
                        XA_WINDOW, 32, PropModeReplace,
                        (unsigned char *)&X11->wm_client_leader, 1);
    } else {
        // non-toplevel widgets don't have a frame, so no need to
        // update the strut
        data.fstrut_dirty = 0;
    }

    if (initializeWindow && q->internalWinId()) {
        // don't erase when resizing
        wsa.bit_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
        Q_ASSERT(id);
        XChangeWindowAttributes(dpy, id, CWBitGravity, &wsa);
    }

    // set X11 event mask
    if (desktop) {
//         QWidget* main_desktop = find(id);
//         if (main_desktop->testWFlags(Qt::WPaintDesktop))
//             XSelectInput(dpy, id, stdDesktopEventMask | ExposureMask);
//         else
        XSelectInput(dpy, id, stdDesktopEventMask);
    } else if (q->internalWinId()) {
        XSelectInput(dpy, id, stdWidgetEventMask);
#if !defined (QT_NO_TABLET)
        QTabletDeviceDataList *tablet_list = qt_tablet_devices();
        if (X11->ptrXSelectExtensionEvent) {
            for (int i = 0; i < tablet_list->size(); ++i) {
                QTabletDeviceData tablet = tablet_list->at(i);
                X11->ptrXSelectExtensionEvent(dpy, id, reinterpret_cast<XEventClass*>(tablet.eventList),
                                              tablet.eventCount);
            }
        }
#endif
    }

    if (desktop) {
        q->setAttribute(Qt::WA_WState_Visible);
    } else if (topLevel) {                        // set X cursor
        if (initializeWindow) {
            qt_x11_enforce_cursor(q);

            if (QTLWExtra *topData = maybeTopData())
                if (!topData->caption.isEmpty())
                    setWindowTitle_helper(topData->caption);

            //always enable dnd: it's not worth the effort to maintain the state
            // NOTE: this always creates topData()
            X11->dndEnable(q, true);

            if (maybeTopData() && maybeTopData()->opacity != 255)
                q->setWindowOpacity(maybeTopData()->opacity/255.);

        }
    } else if (q->internalWinId()) {
        qt_x11_enforce_cursor(q);
        if (QWidget *p = q->parentWidget()) // reset the cursor on the native parent
            qt_x11_enforce_cursor(p);
    }

    if (extra && !extra->mask.isEmpty() && q->internalWinId())
        XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
                            extra->mask.handle(), ShapeSet);

    if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled)) {
        QInputContext *inputContext = q->inputContext();
        if (inputContext)
            inputContext->setFocusWidget(q);
    }

    if (destroyw)
        qt_XDestroyWindow(q, dpy, destroyw);

    // newly created windows are positioned at the window system's
    // (0,0) position. If the parent uses wrect mapping to expand the
    // coordinate system, we must also adjust this widget's window
    // system position
    if (!topLevel && !parentWidget->data->wrect.topLeft().isNull())
        setWSGeometry();
    else if (topLevel && (data.crect.width() == 0 || data.crect.height() == 0))
        q->setAttribute(Qt::WA_OutsideWSRange, true);

    if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
        Q_ASSERT(q->internalWinId());
        XMapWindow(X11->display, q->internalWinId());
        // Ensure that mapped alien widgets are flushed immediately when re-created as native widgets.
        if (QWindowSurface *surface = q->windowSurface())
            surface->flush(q, q->rect(), q->mapTo(surface->window(), QPoint()));
    }

#ifdef ALIEN_DEBUG
    qDebug() << "QWidgetPrivate::create_sys END:" << q;
#endif
}

static void qt_x11_recreateWidget(QWidget *widget)
{
    if (widget->inherits("QGLWidget")) {
        // We send QGLWidgets a ParentChange event which causes them to
        // recreate their GL context, which in turn causes them to choose
        // their visual again. Now that WA_TranslucentBackground is set,
        // QGLContext::chooseVisual will select an ARGB visual.
        QEvent e(QEvent::ParentChange);
        QApplication::sendEvent(widget, &e);
    } else {
        // For regular widgets, reparent them with their parent which
        // also triggers a recreation of the native window
        QPoint pos = widget->pos();
        bool visible = widget->isVisible();
        if (visible)
            widget->hide();

        widget->setParent(widget->parentWidget(), widget->windowFlags());
        widget->move(pos);
        if (visible)
            widget->show();
    }
}

static void qt_x11_recreateNativeWidgetsRecursive(QWidget *widget)
{
    if (widget->internalWinId())
        qt_x11_recreateWidget(widget);

    const QObjectList &children = widget->children();
    for (int i = 0; i < children.size(); ++i) {
        QWidget *child = qobject_cast<QWidget*>(children.at(i));
        if (child)
            qt_x11_recreateNativeWidgetsRecursive(child);
    }
}

void QWidgetPrivate::x11UpdateIsOpaque()
{
#ifndef QT_NO_XRENDER
    Q_Q(QWidget);
    if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground))
        return;

    bool topLevel = (data.window_flags & Qt::Window);
    int screen = xinfo.screen();
    if (topLevel && X11->use_xrender
        && X11->argbVisuals[screen] && xinfo.depth() != 32)
    {
        qt_x11_recreateNativeWidgetsRecursive(q);
    }
#endif
}

/*
  Returns true if the background is inherited; otherwise returns
  false.

  Mainly used in the paintOnScreen case.
*/
bool QWidgetPrivate::isBackgroundInherited() const
{
    Q_Q(const QWidget);

    // windows do not inherit their background
    if (q->isWindow() || q->windowType() == Qt::SubWindow)
        return false;

    if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent))
        return false;

    const QPalette &pal = q->palette();
    QPalette::ColorRole bg = q->backgroundRole();
    QBrush brush = pal.brush(bg);

    // non opaque brushes leaves us no choice, we must inherit
    if (!q->autoFillBackground() || !brush.isOpaque())
        return true;

    if (brush.style() == Qt::SolidPattern) {
        // the background is just a solid color. If there is no
        // propagated contents, then we claim as performance
        // optimization that it was not inheritet. This is the normal
        // case in standard Windows or Motif style.
        const QWidget *w = q->parentWidget();
        if (!w->d_func()->isBackgroundInherited())
            return false;
    }

    return true;
}

void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
{
    Q_D(QWidget);
    d->aboutToDestroy();
    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 childList = children();
        for (int i = 0; i < childList.size(); ++i) { // destroy all widget children
            register QObject *obj = childList.at(i);
            if (obj->isWidgetType())
                static_cast<QWidget*>(obj)->destroy(destroySubWindows,
                                                    destroySubWindows);
        }
        if (QWidgetPrivate::mouseGrabber == this)
            releaseMouse();
        if (QWidgetPrivate::keyboardGrabber == this)
            releaseKeyboard();
        if (isWindow())
            X11->deferred_map.removeAll(this);
        if (isModal()) {
            // just be sure we leave modal
            QApplicationPrivate::leaveModal(this);
        }
        else if ((windowType() == Qt::Popup))
            qApp->d_func()->closePopup(this);

#ifndef QT_NO_XRENDER
        if (d->picture) {
            if (destroyWindow)
                XRenderFreePicture(X11->display, d->picture);
            d->picture = 0;
        }
#endif // QT_NO_XRENDER

        // delete the _NET_WM_USER_TIME_WINDOW
        qt_net_remove_user_time(this);

        if ((windowType() == Qt::Desktop)) {
            if (acceptDrops())
                X11->dndEnable(this, false);
        } else {
            if (isWindow())
                X11->dndEnable(this, false);
            if (destroyWindow)
                qt_XDestroyWindow(this, X11->display, data->winid);
        }
        QT_TRY {
            d->setWinId(0);
        } QT_CATCH (const std::bad_alloc &) {
            // swallow - destructors must not throw
        }

        extern void qPRCleanup(QWidget *widget); // from qapplication_x11.cpp
        if (testAttribute(Qt::WA_WState_Reparented))
            qPRCleanup(this);

        if(d->ic) {
            delete d->ic;
        } else {
            // release previous focus information participating with
            // preedit preservation of qic
            QInputContext *qic = QApplicationPrivate::inputContext;
            if (qic)
                qic->widgetDestroyed(this);
        }
    }
}

void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
{
    Q_Q(QWidget);
#ifdef ALIEN_DEBUG
    qDebug() << "QWidgetPrivate::setParent_sys START" << q << "parent:" << parent;
#endif
    QX11Info old_xinfo = xinfo;
    if (parent && parent->windowType() == Qt::Desktop) {
        // make sure the widget is created on the same screen as the
        // programmer specified desktop widget
        xinfo = parent->d_func()->xinfo;
        parent = 0;
    }

    QTLWExtra *topData = maybeTopData();
    bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
    if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
        q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
    extern void qPRCreate(const QWidget *, Window);
#ifndef QT_NO_CURSOR
    QCursor oldcurs;
#endif

    // dnd unregister (we will register again below)
    if (q->testAttribute(Qt::WA_DropSiteRegistered))
        q->setAttribute(Qt::WA_DropSiteRegistered, false);

    // if we are a top then remove our dnd prop for now
    // it will get rest later
    if (q->isWindow() && wasCreated)
        X11->dndEnable(q, false);

    if (topData)
        qt_net_remove_user_time(q);

//     QWidget *oldparent = q->parentWidget();
    WId old_winid = wasCreated ? data.winid : 0;
    if ((q->windowType() == Qt::Desktop))
        old_winid = 0;
    setWinId(0);

#ifndef QT_NO_XRENDER
    if (picture) {
        XRenderFreePicture(X11->display, picture);
        picture = 0;
    }
#endif

    // hide and reparent our own window away. Otherwise we might get
    // destroyed when emitting the child remove event below. See QWorkspace.
    if (wasCreated && old_winid) {
        XUnmapWindow(X11->display, old_winid);
        if (!old_xinfo.screen() != xinfo.screen())
            XReparentWindow(X11->display, old_winid, RootWindow(X11->display, xinfo.screen()), 0, 0);
    }
    if (topData) {
        topData->parentWinId = 0;
        // zero the frame strut and mark it dirty
        topData->frameStrut.setCoords(0, 0, 0, 0);

        // reparenting from top-level, make sure show() works again
        topData->waitingForMapNotify = 0;
        topData->validWMState = 0;
    }
    data.fstrut_dirty = (!parent || (f & Qt::Window)); // toplevels get a dirty framestrut

    QObjectPrivate::setParent_helper(parent);
    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)
        createWinId();
    if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
        q->setAttribute(Qt::WA_WState_Hidden);
    q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);

    if (wasCreated) {
        QObjectList chlist = q->children();
        for (int i = 0; i < chlist.size(); ++i) { // reparent children
            QObject *obj = chlist.at(i);
            if (obj->isWidgetType()) {
                QWidget *w = (QWidget *)obj;
                if (!w->testAttribute(Qt::WA_WState_Created))
                    continue;
                if (xinfo.screen() != w->d_func()->xinfo.screen()) {
                    // ### force setParent() to not shortcut out (because
                    // ### we're setting the parent to the current parent)
                    // ### setParent will add child back to the list
                    // ### of children so we need to make sure the
                    // ### widget won't be added twice.
                    w->d_func()->parent = 0;
                    this->children.removeOne(w);
                    w->setParent(q);
                } else if (!w->isWindow()) {
                    w->d_func()->invalidateBuffer(w->rect());
                    if (w->internalWinId()) {
                        if (w->testAttribute(Qt::WA_NativeWindow)) {
                            QWidget *nativeParentWidget = w->nativeParentWidget();
                            // Qt::WA_NativeWindow ensures that we always have a nativeParentWidget
                            Q_ASSERT(nativeParentWidget != 0);
                            QPoint p = w->mapTo(nativeParentWidget, QPoint());
                            XReparentWindow(X11->display,
                                            w->internalWinId(),
                                            nativeParentWidget->internalWinId(),
                                            p.x(), p.y());
                        } else {
                            w->d_func()->setParent_sys(q, w->data->window_flags);
                        }
                    }
                } else if (isTransient(w)) {
                    /*
                      when reparenting toplevel windows with toplevel-transient children,
                      we need to make sure that the window manager gets the updated
                      WM_TRANSIENT_FOR information... unfortunately, some window managers
                      don't handle changing WM_TRANSIENT_FOR before the toplevel window is
                      visible, so we unmap and remap all toplevel-transient children *after*
                      the toplevel parent has been mapped.  thankfully, this is easy in Qt :)

                      note that the WM_TRANSIENT_FOR hint is actually updated in
                      QWidgetPrivate::show_sys()
                    */
                    if (w->internalWinId())
                        XUnmapWindow(X11->display, w->internalWinId());
                    QApplication::postEvent(w, new QEvent(QEvent::ShowWindowRequest));
                }
            }
        }
        qPRCreate(q, old_winid);
        updateSystemBackground();

        if (old_winid) {
            Window *cmwret;
            int count;
            if (XGetWMColormapWindows(X11->display, old_winid, &cmwret, &count)) {
                Window *cmw;
                int cmw_size = sizeof(Window)*count;
                cmw = new Window[count];
                memcpy((char *)cmw, (char *)cmwret, cmw_size);
                XFree((char *)cmwret);
                int i;
                for (i=0; i<count; i++) {
                    if (cmw[i] == old_winid) {
                        cmw[i] = q->internalWinId();
                        break;
                    }
                }
                int top_count;
                if (XGetWMColormapWindows(X11->display, q->window()->internalWinId(),
                                          &cmwret, &top_count))
                {
                    Window *merged_cmw = new Window[count + top_count];
                    memcpy((char *)merged_cmw, (char *)cmw, cmw_size);
                    memcpy((char *)merged_cmw + cmw_size, (char *)cmwret, sizeof(Window)*top_count);
                    delete [] cmw;
                    XFree((char *)cmwret);
                    cmw = merged_cmw;
                    count += top_count;
                }

                XSetWMColormapWindows(X11->display, q->window()->internalWinId(), cmw, count);
                delete [] cmw;
            }

            qt_XDestroyWindow(q, X11->display, old_winid);
        }
    }

    // check if we need to register our dropsite
    if (q->testAttribute(Qt::WA_AcceptDrops)
        || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) {
        q->setAttribute(Qt::WA_DropSiteRegistered, true);
    }
#if !defined(QT_NO_IM)
    ic = 0;
#endif
    invalidateBuffer(q->rect());
#ifdef ALIEN_DEBUG
    qDebug() << "QWidgetPrivate::setParent_sys END" << q;
#endif
}

QPoint QWidgetPrivate::mapToGlobal(const QPoint &pos) const
{
    Q_Q(const QWidget);
    if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId()) {
        QPoint p = pos + q->data->crect.topLeft();
        //cannot trust that !isWindow() implies parentWidget() before create
        return (q->isWindow() || !q->parentWidget()) ?  p : q->parentWidget()->d_func()->mapToGlobal(p);
    }
    int x, y;
    Window child;
    QPoint p = mapToWS(pos);
    XTranslateCoordinates(X11->display, q->internalWinId(),
                          QApplication::desktop()->screen(xinfo.screen())->internalWinId(),
                          p.x(), p.y(), &x, &y, &child);
    return QPoint(x, y);
}

QPoint QWidgetPrivate::mapFromGlobal(const QPoint &pos) const
{
    Q_Q(const QWidget);
    if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId()) {
        //cannot trust that !isWindow() implies parentWidget() before create
        QPoint p = (q->isWindow() || !q->parentWidget()) ?  pos : q->parentWidget()->d_func()->mapFromGlobal(pos);
        return p - q->data->crect.topLeft();
    }
    int x, y;
    Window child;
    XTranslateCoordinates(X11->display,
                          QApplication::desktop()->screen(xinfo.screen())->internalWinId(),
                          q->internalWinId(), pos.x(), pos.y(), &x, &y, &child);
    return mapFromWS(QPoint(x, y));
}

QPoint QWidget::mapToGlobal(const QPoint &pos) const
{
    Q_D(const QWidget);
    return d->mapToGlobal(pos);
}

QPoint QWidget::mapFromGlobal(const QPoint &pos) const
{
    Q_D(const QWidget);
    return d->mapFromGlobal(pos);
}

void QWidgetPrivate::updateSystemBackground()
{
    Q_Q(QWidget);
    if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId())
        return;
    QBrush brush = q->palette().brush(QPalette::Active, q->backgroundRole());
    Qt::WindowType type = q->windowType();
    if (brush.style() == Qt::NoBrush
        || q->testAttribute(Qt::WA_NoSystemBackground)
        || q->testAttribute(Qt::WA_UpdatesDisabled)
        || type == Qt::Popup || type == Qt::ToolTip
        )
        XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
    else if (brush.style() == Qt::SolidPattern && brush.isOpaque())
        XSetWindowBackground(X11->display, q->internalWinId(),
                             QColormap::instance(xinfo.screen()).pixel(brush.color()));
    else if (isBackgroundInherited())
        XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), ParentRelative);
    else if (brush.style() == Qt::TexturePattern) {
        extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
        XSetWindowBackgroundPixmap(X11->display, q->internalWinId(),
                                   static_cast<QX11PixmapData*>(qt_toX11Pixmap(brush.texture()).data.data())->x11ConvertToDefaultDepth());
    } else
        XSetWindowBackground(X11->display, q->internalWinId(),
                             QColormap::instance(xinfo.screen()).pixel(brush.color()));
}

#ifndef QT_NO_CURSOR
void QWidgetPrivate::setCursor_sys(const QCursor &)
{
    Q_Q(QWidget);
    qt_x11_enforce_cursor(q);
    XFlush(X11->display);
}

void QWidgetPrivate::unsetCursor_sys()
{
    Q_Q(QWidget);
    qt_x11_enforce_cursor(q);
    XFlush(X11->display);
}
#endif

static XTextProperty*
qstring_to_xtp(const QString& s)
{
    static XTextProperty tp = { 0, 0, 0, 0 };
    static bool free_prop = true; // we can't free tp.value in case it references
    // the data of the static QCString below.
    if (tp.value) {
        if (free_prop)
            XFree(tp.value);
        tp.value = 0;
        free_prop = true;
    }

    static const QTextCodec* mapper = QTextCodec::codecForLocale();
    int errCode = 0;
    if (mapper) {
        QByteArray mapped = mapper->fromUnicode(s);
        char* tl[2];
        tl[0] = mapped.data();
        tl[1] = 0;
        errCode = XmbTextListToTextProperty(X11->display, tl, 1, XStdICCTextStyle, &tp);
#if defined(QT_DEBUG)
        if (errCode < 0)
            qDebug("qstring_to_xtp result code %d", errCode);
#endif
    }
    if (!mapper || errCode < 0) {
        static QByteArray qcs;
        qcs = s.toAscii();
        tp.value = (uchar*)qcs.data();
        tp.encoding = XA_STRING;
        tp.format = 8;
        tp.nitems = qcs.length();
        free_prop = false;
    }

    // ### If we knew WM could understand unicode, we could use
    // ### a much simpler, cheaper encoding...
    /*
        tp.value = (XChar2b*)s.unicode();
        tp.encoding = XA_UNICODE; // wish
        tp.format = 16;
        tp.nitems = s.length();
    */

    return &tp;
}

void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
{
    Q_Q(QWidget);
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
    if (!q->internalWinId())
        return;
    XSetWMName(X11->display, q->internalWinId(), qstring_to_xtp(caption));

    QByteArray net_wm_name = caption.toUtf8();
    XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
                    PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
}

void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
{
    Q_Q(QWidget);
    if (!q->testAttribute(Qt::WA_WState_Created))
        return;
    QTLWExtra *topData = this->topData();
    if (topData->iconPixmap && !forceReset)
        // already been set
        return;

    // preparing images to set the _NET_WM_ICON property
    QIcon icon = q->windowIcon();
    QVector<long> icon_data;
    Qt::HANDLE pixmap_handle = 0;
    if (!icon.isNull()) {
        QList<QSize> availableSizes = icon.availableSizes();
        if(availableSizes.isEmpty()) {
            // try to use default sizes since the icon can be a scalable image like svg.
            availableSizes.push_back(QSize(16,16));
            availableSizes.push_back(QSize(32,32));
            availableSizes.push_back(QSize(64,64));
            availableSizes.push_back(QSize(128,128));
        }
        for(int i = 0; i < availableSizes.size(); ++i) {
            QSize size = availableSizes.at(i);
            QPixmap pixmap = icon.pixmap(size);
            if (!pixmap.isNull()) {
                QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
                int pos = icon_data.size();
                icon_data.resize(pos + 2 + image.width()*image.height());
                icon_data[pos++] = image.width();
                icon_data[pos++] = image.height();
                if (sizeof(long) == sizeof(quint32)) {
                    memcpy(icon_data.data() + pos, image.scanLine(0), image.byteCount());
                } else {
                    for (int y = 0; y < image.height(); ++y) {
                        uint *scanLine = reinterpret_cast<uint *>(image.scanLine(y));
                        for (int x = 0; x < image.width(); ++x)
                            icon_data[pos + y*image.width() + x] = scanLine[x];
                    }
                }
            }
        }
        if (!icon_data.isEmpty()) {
            extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
            /*
              if the app is running on an unknown desktop, or it is not
              using the default visual, convert the icon to 1bpp as stated
              in the ICCCM section 4.1.2.4; otherwise, create the icon pixmap
              in the default depth (even though this violates the ICCCM)
            */
            if (X11->desktopEnvironment == DE_UNKNOWN
                || !QX11Info::appDefaultVisual(xinfo.screen())
                || !QX11Info::appDefaultColormap(xinfo.screen())) {
                // unknown DE or non-default visual/colormap, use 1bpp bitmap
                if (!forceReset || !topData->iconPixmap)
                    topData->iconPixmap = new QBitmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
                pixmap_handle = topData->iconPixmap->handle();
            } else {
                // default depth, use a normal pixmap (even though this
                // violates the ICCCM), since this works on all DEs known to Qt
                if (!forceReset || !topData->iconPixmap)
                    topData->iconPixmap = new QPixmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
                pixmap_handle = static_cast<QX11PixmapData*>(topData->iconPixmap->data.data())->x11ConvertToDefaultDepth();
            }
        }
    }

    if (!q->internalWinId())
        return;

    if (!icon_data.isEmpty()) {
        XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32,
                        PropModeReplace, (unsigned char *) icon_data.data(),
                        icon_data.size());
    } else {
        XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON));
    }

    XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
    XWMHints wm_hints;
    if (!h) {
        memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
        h = &wm_hints;
    }

    if (pixmap_handle) {
        h->icon_pixmap = pixmap_handle;
        h->flags |= IconPixmapHint;
    } else {
        h->icon_pixmap = 0;
        h->flags &= ~(IconPixmapHint | IconMaskHint);
    }

    XSetWMHints(X11->display, q->internalWinId(), h);
    if (h != &wm_hints)
        XFree((char *)h);
}

void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
{
    Q_Q(QWidget);
    if (!q->internalWinId())
        return;
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
    XSetWMIconName(X11->display, q->internalWinId(), qstring_to_xtp(iconText));

    QByteArray icon_name = iconText.toUtf8();
    XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON_NAME), ATOM(UTF8_STRING), 8,
                    PropModeReplace, (unsigned char *) icon_name.constData(), icon_name.size());
}


void QWidget::grabMouse()
{
    if (isVisible() && !qt_nograb()) {
        if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
            QWidgetPrivate::mouseGrabber->releaseMouse();
        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
#ifndef QT_NO_DEBUG
        int status =
#endif
            XGrabPointer(X11->display, effectiveWinId(), False,
                          (uint)(ButtonPressMask | ButtonReleaseMask |
                                  PointerMotionMask | EnterWindowMask |
                                  LeaveWindowMask),
                          GrabModeAsync, GrabModeAsync,
                          XNone, XNone, X11->time);
#ifndef QT_NO_DEBUG
        if (status) {
            const char *s =
                status == GrabNotViewable ? "\"GrabNotViewable\"" :
                status == AlreadyGrabbed  ? "\"AlreadyGrabbed\"" :
                status == GrabFrozen      ? "\"GrabFrozen\"" :
                status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
                "<?>";
            qWarning("QWidget::grabMouse: Failed with %s", s);
        }
#endif
        QWidgetPrivate::mouseGrabber = this;
    }
}


#ifndef QT_NO_CURSOR
void QWidget::grabMouse(const QCursor &cursor)
{
    if (!qt_nograb()) {
        if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
            QWidgetPrivate::mouseGrabber->releaseMouse();
        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
#ifndef QT_NO_DEBUG
        int status =
#endif
        XGrabPointer(X11->display, effectiveWinId(), False,
                      (uint)(ButtonPressMask | ButtonReleaseMask |
                             PointerMotionMask | EnterWindowMask | LeaveWindowMask),
                      GrabModeAsync, GrabModeAsync,
                      XNone, cursor.handle(), X11->time);
#ifndef QT_NO_DEBUG
        if (status) {
            const char *s =
                status == GrabNotViewable ? "\"GrabNotViewable\"" :
                status == AlreadyGrabbed  ? "\"AlreadyGrabbed\"" :
                status == GrabFrozen      ? "\"GrabFrozen\"" :
                status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
                                            "<?>";
            qWarning("QWidget::grabMouse: Failed with %s", s);
        }
#endif
        QWidgetPrivate::mouseGrabber = this;
    }
}
#endif


void QWidget::releaseMouse()
{
    if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
        XUngrabPointer(X11->display, X11->time);
        XFlush(X11->display);
        QWidgetPrivate::mouseGrabber = 0;
    }
}


void QWidget::grabKeyboard()
{
    if (!qt_nograb()) {
        if (QWidgetPrivate::keyboardGrabber && QWidgetPrivate::keyboardGrabber != this)
            QWidgetPrivate::keyboardGrabber->releaseKeyboard();
        XGrabKeyboard(X11->display, effectiveWinId(), False, GrabModeAsync, GrabModeAsync,
                      X11->time);
        QWidgetPrivate::keyboardGrabber = this;
    }
}


void QWidget::releaseKeyboard()
{
    if (!qt_nograb() && QWidgetPrivate::keyboardGrabber == this) {
        XUngrabKeyboard(X11->display, X11->time);
        QWidgetPrivate::keyboardGrabber = 0;
    }
}


QWidget *QWidget::mouseGrabber()
{
    return QWidgetPrivate::mouseGrabber;
}


QWidget *QWidget::keyboardGrabber()
{
    return QWidgetPrivate::keyboardGrabber;
}

void QWidget::activateWindow()
{
    QWidget *tlw = window();
    if (tlw->isVisible() && !tlw->d_func()->topData()->embedded && !X11->deferred_map.contains(tlw)) {
        if (X11->userTime == 0)
            X11->userTime = X11->time;
        qt_net_update_user_time(tlw, X11->userTime);

        if (X11->isSupportedByWM(ATOM(_NET_ACTIVE_WINDOW))
            && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)) {
            XEvent e;
            e.xclient.type = ClientMessage;
            e.xclient.message_type = ATOM(_NET_ACTIVE_WINDOW);
            e.xclient.display = X11->display;
            e.xclient.window = tlw->internalWinId();
            e.xclient.format = 32;
            e.xclient.data.l[0] = 1;     // 1 == application
            e.xclient.data.l[1] = X11->userTime;
            if (QWidget *aw = QApplication::activeWindow())
                e.xclient.data.l[2] = aw->internalWinId();
            else
                e.xclient.data.l[2] = XNone;
            e.xclient.data.l[3] = 0;
            e.xclient.data.l[4] = 0;
            XSendEvent(X11->display, RootWindow(X11->display, tlw->x11Info().screen()),
                       false, SubstructureNotifyMask | SubstructureRedirectMask, &e);
        } else {
            if (!qt_widget_private(tlw)->topData()->waitingForMapNotify)
                XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
        }
    }
}

void QWidget::setWindowState(Qt::WindowStates newstate)
{
    Q_D(QWidget);
    bool needShow = false;
    Qt::WindowStates oldstate = windowState();
    if (oldstate == newstate)
        return;
    if (isWindow()) {
        // Ensure the initial size is valid, since we store it as normalGeometry below.
        if (!testAttribute(Qt::WA_Resized) && !isVisible())
            adjustSize();

        QTLWExtra *top = d->topData();

        if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
            if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
                && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))) {
                if ((newstate & Qt::WindowMaximized) && !(oldstate & Qt::WindowFullScreen))
                    top->normalGeometry = geometry();
                qt_change_net_wm_state(this, (newstate & Qt::WindowMaximized),
                                       ATOM(_NET_WM_STATE_MAXIMIZED_HORZ),
                                       ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
            } else if (! (newstate & Qt::WindowFullScreen)) {
                if (newstate & Qt::WindowMaximized) {
                    // save original geometry
                    const QRect normalGeometry = geometry();

                    if (isVisible()) {
                        data->fstrut_dirty = true;
                        const QRect maxRect = QApplication::desktop()->availableGeometry(this);
                        const QRect r = top->normalGeometry;
                        const QRect fs = d->frameStrut();
                        setGeometry(maxRect.x() + fs.left(),
                                    maxRect.y() + fs.top(),
                                    maxRect.width() - fs.left() - fs.right(),
                                    maxRect.height() - fs.top() - fs.bottom());
                        top->normalGeometry = r;
                    }

                    if (top->normalGeometry.width() < 0)
                        top->normalGeometry = normalGeometry;
                } else {
                    // restore original geometry
                    setGeometry(top->normalGeometry);
                }
            }
        }

        if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
            if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
                if (newstate & Qt::WindowFullScreen) {
                    top->normalGeometry = geometry();
                    top->fullScreenOffset = d->frameStrut().topLeft();
                }
                qt_change_net_wm_state(this, (newstate & Qt::WindowFullScreen),
                                       ATOM(_NET_WM_STATE_FULLSCREEN));
            } else {
                needShow = isVisible();

                if (newstate & Qt::WindowFullScreen) {
                    data->fstrut_dirty = true;
                    const QRect normalGeometry = geometry();
                    const QPoint fullScreenOffset = d->frameStrut().topLeft();

                    top->savedFlags = windowFlags();
                    setParent(0, Qt::Window | Qt::FramelessWindowHint);
                    const QRect r = top->normalGeometry;
                    setGeometry(qApp->desktop()->screenGeometry(this));
                    top->normalGeometry = r;

                    if (top->normalGeometry.width() < 0) {
                        top->normalGeometry = normalGeometry;
                        top->fullScreenOffset = fullScreenOffset;
                    }
                } else {
                    setParent(0, top->savedFlags);

                    if (newstate & Qt::WindowMaximized) {
                        // from fullscreen to maximized
                        data->fstrut_dirty = true;
                        const QRect maxRect = QApplication::desktop()->availableGeometry(this);
                        const QRect r = top->normalGeometry;
                        const QRect fs = d->frameStrut();
                        setGeometry(maxRect.x() + fs.left(),
                                    maxRect.y() + fs.top(),
                                    maxRect.width() - fs.left() - fs.right(),
                                    maxRect.height() - fs.top() - fs.bottom());
                        top->normalGeometry = r;
                    } else {
                        // restore original geometry
                        setGeometry(top->normalGeometry.adjusted(-top->fullScreenOffset.x(),
                                                                 -top->fullScreenOffset.y(),
                                                                 -top->fullScreenOffset.x(),
                                                                 -top->fullScreenOffset.y()));
                    }
                }
            }
        }

        createWinId();
        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
        if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
            if (isVisible()) {
                if (newstate & Qt::WindowMinimized) {
                    XEvent e;
                    e.xclient.type = ClientMessage;
                    e.xclient.message_type = ATOM(WM_CHANGE_STATE);
                    e.xclient.display = X11->display;
                    e.xclient.window = data->winid;
                    e.xclient.format = 32;
                    e.xclient.data.l[0] = IconicState;
                    e.xclient.data.l[1] = 0;
                    e.xclient.data.l[2] = 0;
                    e.xclient.data.l[3] = 0;
                    e.xclient.data.l[4] = 0;
                    XSendEvent(X11->display,
                               RootWindow(X11->display,d->xinfo.screen()),
                               False, (SubstructureNotifyMask|SubstructureRedirectMask), &e);
                } else {
                    setAttribute(Qt::WA_Mapped);
                    XMapWindow(X11->display, effectiveWinId());
                }
            }

            needShow = false;
        }
    }

    data->window_state = newstate;

    if (needShow)
        show();

    if (newstate & Qt::WindowActive)
        activateWindow();

    QWindowStateChangeEvent e(oldstate);
    QApplication::sendEvent(this, &e);
}

/*!
  \internal
  Platform-specific part of QWidget::show().
*/

void QWidgetPrivate::show_sys()
{
    Q_Q(QWidget);
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));

    if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
        invalidateBuffer(q->rect());
        q->setAttribute(Qt::WA_Mapped);
        if (QTLWExtra *tlwExtra = maybeTopData())
            tlwExtra->waitingForMapNotify = 0;
        return;
    }

    if (q->isWindow()) {
        XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
        XWMHints  wm_hints;
        bool got_hints = h != 0;
        if (!got_hints) {
            memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
            h = &wm_hints;
        }
        h->initial_state = q->isMinimized() ? IconicState : NormalState;
        h->flags |= StateHint;
        XSetWMHints(X11->display, q->internalWinId(), h);
        if (got_hints)
            XFree((char *)h);

        // update WM_NORMAL_HINTS
        do_size_hints(q, extra);

        // udpate WM_TRANSIENT_FOR
        if (isTransient(q)) {
            QWidget *p = q->parentWidget();

#ifndef QT_NO_MENU
            // hackish ... try to find the main window related to this QMenu
            if (qobject_cast<QMenu *>(q)) {
                p = static_cast<QMenuPrivate*>(this)->causedPopup.widget;
                if (!p)
                    p = q->parentWidget();
                if (!p)
                    p = QApplication::widgetAt(q->pos());
                if (!p)
                    p = qApp->activeWindow();
            }
#endif
            if (p)
                p = p->window();
            if (p) {
                // transient for window
                XSetTransientForHint(X11->display, q->internalWinId(), p->internalWinId());
            } else {
                // transient for group
                XSetTransientForHint(X11->display, q->internalWinId(), X11->wm_client_leader);
            }
        }

        // update _MOTIF_WM_HINTS
        QtMWMHints mwmhints = GetMWMHints(X11->display, q->internalWinId());

        if (data.window_modality != Qt::NonModal) {
            switch (data.window_modality) {
            case Qt::WindowModal:
                mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
                break;
            case Qt::ApplicationModal:
            default:
                mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
                break;
            }
            mwmhints.flags |= MWM_HINTS_INPUT_MODE;
        } else {
            mwmhints.input_mode = MWM_INPUT_MODELESS;
            mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
        }

        if (q->minimumSize() == q->maximumSize()) {
            // fixed size, remove the resize handle (since mwm/dtwm
            // isn't smart enough to do it itself)
            mwmhints.flags |= MWM_HINTS_FUNCTIONS;
            if (mwmhints.functions == MWM_FUNC_ALL) {
                mwmhints.functions = MWM_FUNC_MOVE;
            } else {
                mwmhints.functions &= ~MWM_FUNC_RESIZE;
            }

            if (mwmhints.decorations == MWM_DECOR_ALL) {
                mwmhints.flags |= MWM_HINTS_DECORATIONS;
                mwmhints.decorations = (MWM_DECOR_BORDER
                                        | MWM_DECOR_TITLE
                                        | MWM_DECOR_MENU);
            } else {
                mwmhints.decorations &= ~MWM_DECOR_RESIZEH;
            }

            if (q->windowFlags() & Qt::WindowMinimizeButtonHint) {
                mwmhints.flags |= MWM_HINTS_DECORATIONS;
                mwmhints.decorations |= MWM_DECOR_MINIMIZE;
                mwmhints.functions |= MWM_FUNC_MINIMIZE;
            }
            if (q->windowFlags() & Qt::WindowMaximizeButtonHint) {
                mwmhints.flags |= MWM_HINTS_DECORATIONS;
                mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
                mwmhints.functions |= MWM_FUNC_MAXIMIZE;
            }
            if (q->windowFlags() & Qt::WindowCloseButtonHint)
                mwmhints.functions |= MWM_FUNC_CLOSE;
        }

        SetMWMHints(X11->display, q->internalWinId(), mwmhints);

        // update _NET_WM_STATE
        QVector<Atom> netWmState = getNetWmState(q);

        Qt::WindowFlags flags = q->windowFlags();
        if (flags & Qt::WindowStaysOnTopHint) {
            if (flags & Qt::WindowStaysOnBottomHint)
                qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
            if (!netWmState.contains(ATOM(_NET_WM_STATE_ABOVE)))
                netWmState.append(ATOM(_NET_WM_STATE_ABOVE));
            if (!netWmState.contains(ATOM(_NET_WM_STATE_STAYS_ON_TOP)))
                netWmState.append(ATOM(_NET_WM_STATE_STAYS_ON_TOP));
        } else if (flags & Qt::WindowStaysOnBottomHint) {
            if (!netWmState.contains(ATOM(_NET_WM_STATE_BELOW)))
                netWmState.append(ATOM(_NET_WM_STATE_BELOW));
        }
        if (q->isFullScreen()) {
            if (!netWmState.contains(ATOM(_NET_WM_STATE_FULLSCREEN)))
                netWmState.append(ATOM(_NET_WM_STATE_FULLSCREEN));
        }
        if (q->isMaximized()) {
            if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
                netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ));
            if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))
                netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
        }
        if (data.window_modality != Qt::NonModal) {
            if (!netWmState.contains(ATOM(_NET_WM_STATE_MODAL)))
                netWmState.append(ATOM(_NET_WM_STATE_MODAL));
        }

        if (!netWmState.isEmpty()) {
            XChangeProperty(X11->display, q->internalWinId(),
                            ATOM(_NET_WM_STATE), XA_ATOM, 32, PropModeReplace,
                            (unsigned char *) netWmState.data(), netWmState.size());
        } else {
            XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_STATE));
        }

        // set _NET_WM_USER_TIME
        Time userTime = X11->userTime;
        bool setUserTime = false;
        if (q->testAttribute(Qt::WA_ShowWithoutActivating)) {
            userTime = 0;
            setUserTime = true;
        } else if (userTime != CurrentTime) {
            setUserTime = true;
        }
        if (setUserTime)
            qt_net_update_user_time(q, userTime);

#ifndef QT_NO_XSYNC
        if (!topData()->syncUpdateCounter) {
            XSyncValue value;
            XSyncIntToValue(&value, 0);
            topData()->syncUpdateCounter = XSyncCreateCounter(X11->display, value);

            XChangeProperty(X11->display, q->internalWinId(),
                            ATOM(_NET_WM_SYNC_REQUEST_COUNTER),
                            XA_CARDINAL,
                            32, PropModeReplace,
                            (uchar *) &topData()->syncUpdateCounter, 1);

            topData()->newCounterValueHi = 0;
            topData()->newCounterValueLo = 0;
        }
#endif

        if (!topData()->embedded
            && (topData()->validWMState || topData()->waitingForMapNotify)
            && !q->isMinimized()) {
            X11->deferred_map.append(q);
            return;
        }

        if (q->isMaximized() && !q->isFullScreen()
            && !(X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
                 && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))) {
            XMapWindow(X11->display, q->internalWinId());
            data.fstrut_dirty = true;
            qt_x11_wait_for_window_manager(q);

            // if the wm was not smart enough to adjust our size, do that manually
            QRect maxRect = QApplication::desktop()->availableGeometry(q);

            QTLWExtra *top = topData();
            QRect normalRect = top->normalGeometry;
            const QRect fs = frameStrut();

            q->setGeometry(maxRect.x() + fs.left(),
                           maxRect.y() + fs.top(),
                           maxRect.width() - fs.left() - fs.right(),
                           maxRect.height() - fs.top() - fs.bottom());

            // restore the original normalGeometry
            top->normalGeometry = normalRect;
            // internalSetGeometry() clears the maximized flag... make sure we set it back
            data.window_state = data.window_state | Qt::WindowMaximized;
            q->setAttribute(Qt::WA_Mapped);
            return;
        }

        if (q->isFullScreen() && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
            XMapWindow(X11->display, q->internalWinId());
            qt_x11_wait_for_window_manager(q);
            q->setAttribute(Qt::WA_Mapped);
            return;
        }
    }

    invalidateBuffer(q->rect());

    if (q->testAttribute(Qt::WA_OutsideWSRange))
        return;
    q->setAttribute(Qt::WA_Mapped);
    if (q->isWindow())
        topData()->waitingForMapNotify = 1;

    if (!q->isWindow()
        && (!q->autoFillBackground()
            || q->palette().brush(q->backgroundRole()).style() == Qt::LinearGradientPattern)) {
        if (q->internalWinId()) {
            XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
            XMapWindow(X11->display, q->internalWinId());
            updateSystemBackground();
        }
        return;
    }

    if (q->internalWinId())
        XMapWindow(X11->display, q->internalWinId());

    // Freedesktop.org Startup Notification
    if (X11->startupId && q->isWindow()) {
        QByteArray message("remove: ID=");
        message.append(X11->startupId);
        sendStartupMessage(message.constData());
        X11->startupId = 0;
    }
}

/*!
  \internal
  Platform-specific part of QWidget::show().
*/

void QWidgetPrivate::sendStartupMessage(const char *message) const
{
    Q_Q(const QWidget);

    if (!message)
        return;

    XEvent xevent;
    xevent.xclient.type = ClientMessage;
    xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO_BEGIN);
    xevent.xclient.display = X11->display;
    xevent.xclient.window = q->internalWinId();
    xevent.xclient.format = 8;

    Window rootWindow = RootWindow(X11->display, DefaultScreen(X11->display));
    uint sent = 0;
    uint length = strlen(message) + 1;
    do {
        if (sent == 20)
            xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO);

        for (uint i = 0; i < 20 && i + sent <= length; i++)
            xevent.xclient.data.b[i] = message[i + sent++];

        XSendEvent(X11->display, rootWindow, false, PropertyChangeMask, &xevent);
    } while (sent <= length);
}

void QWidgetPrivate::setNetWmWindowTypes()
{
    Q_Q(QWidget);
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));

    if (!q->isWindow()) {
        if (q->internalWinId())
            XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_WINDOW_TYPE));
        return;
    }

    QVector<long> windowTypes;

    // manual selection 1 (these are never set by Qt and take precedence)
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DESKTOP));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDock))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DOCK));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeNotification))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NOTIFICATION));

    // manual selection 2 (Qt uses these during auto selection);
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeUtility))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeSplash))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDialog))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));

    // manual selection 3 (these can be set by Qt, but don't have a
    // corresponding Qt::WindowType). note that order of the *MENU
    // atoms is important
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeMenu))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_MENU));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypePopupMenu))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_POPUP_MENU));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolBar))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLBAR));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeCombo))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_COMBO));
    if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDND))
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DND));

    // automatic selection
    switch (q->windowType()) {
    case Qt::Dialog:
    case Qt::Sheet:
        // dialog netwm type
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
        break;

    case Qt::Tool:
    case Qt::Drawer:
        // utility netwm type
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
        break;

    case Qt::ToolTip:
        // tooltip netwm type
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
        break;

    case Qt::SplashScreen:
        // splash netwm type
        windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
        break;

    default:
        break;
    }

    if (q->windowFlags() & Qt::FramelessWindowHint) {
        // override netwm type - quick and easy for KDE noborder
        windowTypes.append(ATOM(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
    }

    // normal netwm type - default
    windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NORMAL));

    if (!windowTypes.isEmpty()) {
        XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE), XA_ATOM, 32,
                        PropModeReplace, (unsigned char *) windowTypes.constData(),
                        windowTypes.count());
    } else {
        XDeleteProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE));
    }
}

/*!
  \internal
  Platform-specific part of QWidget::hide().
*/

void QWidgetPrivate::hide_sys()
{
    Q_Q(QWidget);
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
    deactivateWidgetCleanup();
    if (q->isWindow()) {
        X11->deferred_map.removeAll(q);
        if (q->internalWinId()) // in nsplugin, may be 0
            XWithdrawWindow(X11->display, q->internalWinId(), xinfo.screen());
        XFlush(X11->display);
    } else {
        invalidateBuffer(q->rect());
        if (q->internalWinId()) // in nsplugin, may be 0
            XUnmapWindow(X11->display, q->internalWinId());
    }
    q->setAttribute(Qt::WA_Mapped, false);
}

void QWidgetPrivate::setFocus_sys()
{

}


void QWidgetPrivate::raise_sys()
{
    Q_Q(QWidget);
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
    if (q->internalWinId())
        XRaiseWindow(X11->display, q->internalWinId());
}

void QWidgetPrivate::lower_sys()
{
    Q_Q(QWidget);
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
    if (q->internalWinId())
        XLowerWindow(X11->display, q->internalWinId());
    if(!q->isWindow())
        invalidateBuffer(q->rect());
}

void QWidgetPrivate::stackUnder_sys(QWidget* w)
{
    Q_Q(QWidget);
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
    if (q->internalWinId() && w->internalWinId()) {
        Window stack[2];
        stack[0] = w->internalWinId();;
        stack[1] = q->internalWinId();
        XRestackWindows(X11->display, stack, 2);
    }
    if(!q->isWindow() || !w->internalWinId())
        invalidateBuffer(q->rect());
}


static void do_size_hints(QWidget* widget, QWExtra *x)
{
    Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
    XSizeHints s;
    s.flags = 0;
    if (x) {
        QRect g = widget->geometry();
        s.x = g.x();
        s.y = g.y();
        s.width = g.width();
        s.height = g.height();
        if (x->minw > 0 || x->minh > 0) {
            // add minimum size hints
            s.flags |= PMinSize;
            s.min_width  = qMin(XCOORD_MAX, x->minw);
            s.min_height = qMin(XCOORD_MAX, x->minh);
        }
        if (x->maxw < QWIDGETSIZE_MAX || x->maxh < QWIDGETSIZE_MAX) {
            // add maximum size hints
            s.flags |= PMaxSize;
            s.max_width  = qMin(XCOORD_MAX, x->maxw);
            s.max_height = qMin(XCOORD_MAX, x->maxh);
        }
        if (x->topextra &&
            (x->topextra->incw > 0 || x->topextra->inch > 0)) {
            // add resize increment hints
            s.flags |= PResizeInc | PBaseSize;
            s.width_inc = x->topextra->incw;
            s.height_inc = x->topextra->inch;
            s.base_width = x->topextra->basew;
            s.base_height = x->topextra->baseh;
        }
    }
    if (widget->testAttribute(Qt::WA_Moved)) {
        // user (i.e. command-line) specified position
        s.flags |= USPosition;
        s.flags |= PPosition;
    }
    if (widget->testAttribute(Qt::WA_Resized)) {
        // user (i.e. command-line) specified size
        s.flags |= USSize;
        s.flags |= PSize;
    }
    s.flags |= PWinGravity;
    if (widget->testAttribute(Qt::WA_Moved) && x && x->topextra && !x->topextra->posFromMove) {
        // position came from setGeometry(), tell the WM that we don't
        // want our window gravity-shifted
        s.win_gravity = StaticGravity;
    } else {
        // position came from move()
        s.x = widget->x();
        s.y = widget->y();
        s.win_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
    }
    if (widget->internalWinId())
        XSetWMNormalHints(X11->display, widget->internalWinId(), &s);
}


/*
  Helper function for non-toplevel widgets. Helps to map Qt's 32bit
  coordinate system to X11's 16bit coordinate system.

  Sets the geometry of the widget to data.crect, but clipped to sizes
  that X can handle. Unmaps widgets that are completely outside the
  valid range.

  Maintains data.wrect, which is the geometry of the X widget,
  measured in this widget's coordinate system.

  if the parent is not clipped, parentWRect is empty, otherwise
  parentWRect is the geometry of the parent's X rect, measured in
  parent's coord sys
 */
void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &)
{
    Q_Q(QWidget);
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));

    /*
      There are up to four different coordinate systems here:
      Qt coordinate system for this widget.
      X coordinate system for this widget (relative to wrect).
      Qt coordinate system for parent
      X coordinate system for parent (relative to parent's wrect).
     */
    Display *dpy = xinfo.display();
    QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
    QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
    QRect wrect;
    //xrect is the X geometry of my X widget. (starts out in  parent's Qt coord sys, and ends up in parent's X coord sys)
    QRect xrect = data.crect;

    const QWidget *const parent = q->parentWidget();
    QRect parentWRect = parent->data->wrect;

    if (parentWRect.isValid()) {
        // parent is clipped, and we have to clip to the same limit as parent
        if (!parentWRect.contains(xrect)) {
            xrect &= parentWRect;
            wrect = xrect;
            //translate from parent's to my Qt coord sys
            wrect.translate(-data.crect.topLeft());
        }
        //translate from parent's Qt coords to parent's X coords
        xrect.translate(-parentWRect.topLeft());

    } else {
        // parent is not clipped, we may or may not have to clip

        if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
            // This is where the main optimization is: we are already
            // clipped, and if our clip is still valid, we can just
            // move our window, and do not need to move or clip
            // children

            QRect vrect = xrect & parent->rect();
            vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords
            if (data.wrect.contains(vrect)) {
                xrect = data.wrect;
                xrect.translate(data.crect.topLeft());
                if (data.winid)
                    XMoveWindow(dpy, data.winid, xrect.x(), xrect.y());
                return;
            }
        }

        if (!validRange.contains(xrect)) {
            // we are too big, and must clip
            xrect &=wrectRange;
            wrect = xrect;
            wrect.translate(-data.crect.topLeft());
            //parent's X coord system is equal to parent's Qt coord
            //sys, so we don't need to map xrect.
        }

    }

    // unmap if we are outside the valid window system coord system
    bool outsideRange = !xrect.isValid();
    bool mapWindow = false;
    if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
        q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
        if (outsideRange) {
            if (data.winid)
                XUnmapWindow(dpy, data.winid);
            q->setAttribute(Qt::WA_Mapped, false);
        } else if (!q->isHidden()) {
            mapWindow = true;
        }
    }

    if (outsideRange)
        return;

    bool jump = (data.wrect != wrect);
    data.wrect = wrect;


    // and now recursively for all children...
    // ### can be optimized
    for (int i = 0; i < children.size(); ++i) {
        QObject *object = children.at(i);
        if (object->isWidgetType()) {
            QWidget *w = static_cast<QWidget *>(object);
            if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
                w->d_func()->setWSGeometry(jump);
        }
    }

    if (data.winid) {
        // move ourselves to the new position and map (if necessary) after
        // the movement. Rationale: moving unmapped windows is much faster
        // than moving mapped windows
        if (jump) //avoid flicker when jumping
            XSetWindowBackgroundPixmap(dpy, data.winid, XNone);
        if (!parent->internalWinId())
            xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0)));
        XMoveResizeWindow(dpy, data.winid, xrect.x(), xrect.y(), xrect.width(), xrect.height());
    }

    //to avoid flicker, we have to show children after the helper widget has moved
    if (jump) {
        for (int i = 0; i < children.size(); ++i) {
            QObject *object = children.at(i);
            if (object->isWidgetType()) {
                QWidget *w = static_cast<QWidget *>(object);
                if (!w->testAttribute(Qt::WA_OutsideWSRange) && !w->testAttribute(Qt::WA_Mapped) && !w->isHidden()) {
                    w->setAttribute(Qt::WA_Mapped);
                    if (w->internalWinId())
                        XMapWindow(dpy, w->data->winid);
                }
            }
        }
    }


    if  (jump && data.winid)
        XClearArea(dpy, data.winid, 0, 0, wrect.width(), wrect.height(), True);

    if (mapWindow && !dontShow) {
        q->setAttribute(Qt::WA_Mapped);
        if (data.winid)
            XMapWindow(dpy, data.winid);
    }
}

void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
{
    Q_Q(QWidget);
    Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
    Display *dpy = X11->display;

    if ((q->windowType() == Qt::Desktop))
        return;
    if (q->isWindow()) {
        if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
            && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
            data.window_state &= ~Qt::WindowMaximized;
        if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
            data.window_state &= ~Qt::WindowFullScreen;
        if (QTLWExtra *topData = maybeTopData())
            topData->normalGeometry = QRect(0,0,-1,-1);
    } else {
        uint s = data.window_state;
        s &= ~(Qt::WindowMaximized | Qt::WindowFullScreen);
        data.window_state = s;
    }
    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 oldPos(q->pos());
    QSize oldSize(q->size());
    QRect oldGeom(data.crect);
    QRect  r(x, y, w, h);

    // We only care about stuff that changes the geometry, or may
    // cause the window manager to change its state
    if (!q->isWindow() && oldGeom == r)
        return;

    data.crect = r;
    bool isResize = q->size() != oldSize;

    if (q->isWindow()) {
        if (w == 0 || h == 0) {
            q->setAttribute(Qt::WA_OutsideWSRange, true);
            if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
                hide_sys();
        } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
            q->setAttribute(Qt::WA_OutsideWSRange, false);

            // put the window in its place and show it
            if (data.winid)
                XMoveResizeWindow(dpy, data.winid, x, y, w, h);
            topData()->posFromMove = false; // force StaticGravity
            do_size_hints(q, extra);
            show_sys();
        } else {
            q->setAttribute(Qt::WA_OutsideWSRange, false);
            if (!q->isVisible())
                do_size_hints(q, extra);
            if (isMove) {
                if ((data.window_flags & Qt::X11BypassWindowManagerHint) == Qt::X11BypassWindowManagerHint
                    // work around 4Dwm's incompliance with ICCCM 4.1.5
                    || X11->desktopEnvironment == DE_4DWM) {
                    if (data.winid)
                        XMoveResizeWindow(dpy, data.winid, x, y, w, h);
                } else if (q->isVisible()
                           && topData()->validWMState
                           && X11->isSupportedByWM(ATOM(_NET_MOVERESIZE_WINDOW))) {
                    XEvent e;
                    e.xclient.type = ClientMessage;
                    e.xclient.message_type = ATOM(_NET_MOVERESIZE_WINDOW);
                    e.xclient.display = X11->display;
                    e.xclient.window = q->internalWinId();
                    e.xclient.format = 32;
                    e.xclient.data.l[0] = StaticGravity | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12;
                    e.xclient.data.l[1] = x;
                    e.xclient.data.l[2] = y;
                    e.xclient.data.l[3] = w;
                    e.xclient.data.l[4] = h;
                    XSendEvent(X11->display, RootWindow(X11->display, q->x11Info().screen()),
                               false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
                } else if (data.winid) {
                    // pos() is right according to ICCCM 4.1.5
                    XMoveResizeWindow(dpy, data.winid, q->pos().x(), q->pos().y(), w, h);
                }
            } else if (isResize && data.winid) {
                if (!q->isVisible()
                    && topData()->validWMState
                    && !q->testAttribute(Qt::WA_PendingMoveEvent)) {
                    /*
                       even though we've not visible, we could be in a
                       race w/ the window manager, and it may ignore
                       our ConfigureRequest. setting posFromMove to
                       false makes sure that doDeferredMap() in
                       qapplication_x11.cpp keeps the window in the
                       right place
                    */
                    topData()->posFromMove = false;
                }
                XResizeWindow(dpy, data.winid, w, h);
            }
        }
        if (isResize && !q->testAttribute(Qt::WA_DontShowOnScreen)) // set config pending only on resize, see qapplication_x11.cpp, translateConfigEvent()
            q->setAttribute(Qt::WA_WState_ConfigPending);

    } else {
        QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
        const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false;
        const bool disableInTopLevelResize = inTopLevelResize && q->internalWinId();
        if (disableInTopLevelResize) {
            // Top-level resize optimization does not work for native child widgets;
            // disable it for this particular widget.
            tlwExtra->inTopLevelResize = false;
        }

        if (!isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible()) {
            moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y());
        }
        if (q->testAttribute(Qt::WA_WState_Created))
            setWSGeometry();

        if (isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible())
            invalidateBuffer_resizeHelper(oldPos, oldSize);

        if (disableInTopLevelResize)
            tlwExtra->inTopLevelResize = true;
    }

    if (q->isVisible()) {
        if (isMove && q->pos() != oldPos) {
            if (X11->desktopEnvironment != DE_4DWM) {
                // pos() is right according to ICCCM 4.1.5
                QMoveEvent e(q->pos(), oldPos);
                QApplication::sendEvent(q, &e);
            } else {
                // work around 4Dwm's incompliance with ICCCM 4.1.5
                QMoveEvent e(data.crect.topLeft(), oldGeom.topLeft());
                QApplication::sendEvent(q, &e);
            }
        }
        if (isResize) {
            static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
            // If we have a backing store with static contents, we have to disable the top-level
            // resize optimization in order to get invalidated regions for resized widgets.
            // The optimization discards all invalidateBuffer() calls since we're going to
            // repaint everything anyways, but that's not the case with static contents.
            const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra
                                           && !extra->topextra->inTopLevelResize
                                           && (!extra->topextra->backingStore
                                               || !extra->topextra->backingStore->hasStaticContents());
            if (setTopLevelResize)
                extra->topextra->inTopLevelResize = true;
            QResizeEvent e(q->size(), oldSize);
            QApplication::sendEvent(q, &e);
            if (setTopLevelResize)
                extra->topextra->inTopLevelResize = false;
        }
    } else {
        if (isMove && q->pos() != oldPos)
            q->setAttribute(Qt::WA_PendingMoveEvent, true);
        if (isResize)
            q->setAttribute(Qt::WA_PendingResizeEvent, true);
    }
}

void QWidgetPrivate::setConstraints_sys()
{
    Q_Q(QWidget);
#ifdef ALIEN_DEBUG
    qDebug() << "QWidgetPrivate::setConstraints_sys START" << q;
#endif
    if (q->testAttribute(Qt::WA_WState_Created))
        do_size_hints(q, extra);
#ifdef ALIEN_DEBUG
    qDebug() << "QWidgetPrivate::setConstraints_sys END" << q;
#endif
}

void QWidgetPrivate::scroll_sys(int dx, int dy)
{
    Q_Q(QWidget);

    scrollChildren(dx, dy);
    if (!paintOnScreen()) {
        scrollRect(q->rect(), dx, dy);
    } else {
        scroll_sys(dx, dy, QRect());
    }
}

void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
{
    Q_Q(QWidget);

    if (!paintOnScreen()) {
        scrollRect(r, dx, dy);
        return;
    }
    bool valid_rect = r.isValid();
    bool just_update = qAbs(dx) > q->width() || qAbs(dy) > q->height();
    QRect sr = valid_rect ? r : clipRect();
    if (just_update)
        q->update();
    else if (!valid_rect)
        dirty.translate(dx, dy);

    int x1, y1, x2, y2, w = sr.width(), h = sr.height();
    if (dx > 0) {
        x1 = sr.x();
        x2 = x1+dx;
        w -= dx;
    } else {
        x2 = sr.x();
        x1 = x2-dx;
        w += dx;
    }
    if (dy > 0) {
        y1 = sr.y();
        y2 = y1+dy;
        h -= dy;
    } else {
        y2 = sr.y();
        y1 = y2-dy;
        h += dy;
    }

    if (dx == 0 && dy == 0)
        return;

    Display *dpy = X11->display;
    // Want expose events
    if (w > 0 && h > 0 && !just_update && q->internalWinId()) {
        GC gc = XCreateGC(dpy, q->internalWinId(), 0, 0);
        XSetGraphicsExposures(dpy, gc, True);
        XCopyArea(dpy, q->internalWinId(), q->internalWinId(), gc, x1, y1, w, h, x2, y2);
        XFreeGC(dpy, gc);
    }

    if (!valid_rect && !children.isEmpty()) {        // scroll children
        QPoint pd(dx, dy);
        for (int i = 0; i < children.size(); ++i) { // move all children
            register QObject *object = children.at(i);
            if (object->isWidgetType()) {
                QWidget *w = static_cast<QWidget *>(object);
                if (!w->isWindow())
                    w->move(w->pos() + pd);
            }
        }
    }

    if (just_update)
        return;

    // Don't let the server be bogged-down with repaint events
    bool repaint_immediately = (qt_sip_count(q) < 3 && !q->testAttribute(Qt::WA_WState_InPaintEvent));

    if (dx) {
        int x = x2 == sr.x() ? sr.x()+w : sr.x();
        if (repaint_immediately)
            q->repaint(x, sr.y(), qAbs(dx), sr.height());
        else if (q->internalWinId())
            XClearArea(dpy, data.winid, x, sr.y(), qAbs(dx), sr.height(), True);
    }
    if (dy) {
        int y = y2 == sr.y() ? sr.y()+h : sr.y();
        if (repaint_immediately)
            q->repaint(sr.x(), y, sr.width(), qAbs(dy));
        else if (q->internalWinId())
            XClearArea(dpy, data.winid, sr.x(), y, sr.width(), qAbs(dy), True);
    }

    qt_insert_sip(q, dx, dy); // #### ignores r
}

int QWidget::metric(PaintDeviceMetric m) const
{
    Q_D(const QWidget);
    int val;
    if (m == PdmWidth) {
        val = data->crect.width();
    } else if (m == PdmHeight) {
        val = data->crect.height();
    } else {
        Display *dpy = X11->display;
        int scr = d->xinfo.screen();
        switch (m) {
            case PdmDpiX:
            case PdmPhysicalDpiX:
                if (d->extra && d->extra->customDpiX)
                    val = d->extra->customDpiX;
                else if (d->parent)
                    val = static_cast<QWidget *>(d->parent)->metric(m);
                else
                    val = QX11Info::appDpiX(scr);
                break;
            case PdmDpiY:
            case PdmPhysicalDpiY:
                if (d->extra && d->extra->customDpiY)
                    val = d->extra->customDpiY;
                else if (d->parent)
                    val = static_cast<QWidget *>(d->parent)->metric(m);
                else
                    val = QX11Info::appDpiY(scr);
                break;
            case PdmWidthMM:
                val = (DisplayWidthMM(dpy,scr)*data->crect.width())/
                      DisplayWidth(dpy,scr);
                break;
            case PdmHeightMM:
                val = (DisplayHeightMM(dpy,scr)*data->crect.height())/
                      DisplayHeight(dpy,scr);
                break;
            case PdmNumColors:
                val = d->xinfo.cells();
                break;
            case PdmDepth:
                val = d->xinfo.depth();
                break;
            default:
                val = 0;
                qWarning("QWidget::metric: Invalid metric command");
        }
    }
    return val;
}

void QWidgetPrivate::createSysExtra()
{
    extra->compress_events = true;
    extra->xDndProxy = 0;
}

void QWidgetPrivate::deleteSysExtra()
{
}

void QWidgetPrivate::createTLSysExtra()
{
    extra->topextra->spont_unmapped = 0;
    extra->topextra->dnd = 0;
    extra->topextra->validWMState = 0;
    extra->topextra->waitingForMapNotify = 0;
    extra->topextra->parentWinId = 0;
    extra->topextra->userTimeWindow = 0;
#ifndef QT_NO_XSYNC
    extra->topextra->syncUpdateCounter = 0;
    extra->topextra->syncRequestTimestamp = 0;
    extra->topextra->newCounterValueHi = 0;
    extra->topextra->newCounterValueLo = 0;
#endif
}

void QWidgetPrivate::deleteTLSysExtra()
{
    // don't destroy input context here. it will be destroyed in
    // QWidget::destroy() destroyInputContext();
#ifndef QT_NO_XSYNC
    if (extra && extra->topextra && extra->topextra->syncUpdateCounter) {
        XSyncDestroyCounter(X11->display, extra->topextra->syncUpdateCounter);
        extra->topextra->syncUpdateCounter = 0;
    }
#endif
}

void QWidgetPrivate::registerDropSite(bool on)
{
    Q_UNUSED(on);
}

void QWidgetPrivate::setMask_sys(const QRegion &region)
{
    Q_Q(QWidget);
    if (!q->internalWinId())
        return;

    if (region.isEmpty()) {
        XShapeCombineMask(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
                          XNone, ShapeSet);
    } else {
        XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
                            region.handle(), ShapeSet);
    }
}

/*!
  \internal

  Computes the frame rectangle when needed.  This is an internal function, you
  should never call this.
*/

void QWidgetPrivate::updateFrameStrut()
{
    Q_Q(QWidget);

    QTLWExtra *top = topData();
    if (!top->validWMState) {
        return;
    }
    if (!q->isWindow() && !q->internalWinId()) {
        data.fstrut_dirty = false;
        return;
    }

    Atom type_ret;
    Window l = q->effectiveWinId(), w = l, p, r; // target window, its parent, root
    Window *c;
    int i_unused;
    unsigned int nc;
    unsigned char *data_ret;
    unsigned long l_unused;

    while (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
        if (c && nc > 0)
            XFree(c);

        if (! p) {
            qWarning("QWidget::updateFrameStrut: No parent");
            return;
        }

        // if the parent window is the root window, an Enlightenment virtual root or
        // a NET WM virtual root window, stop here
        data_ret = 0;
        if (p == r ||
            (XGetWindowProperty(X11->display, p,
                                ATOM(ENLIGHTENMENT_DESKTOP), 0, 1, False, XA_CARDINAL,
                                &type_ret, &i_unused, &l_unused, &l_unused,
                                &data_ret) == Success &&
             type_ret == XA_CARDINAL)) {
            if (data_ret)
                XFree(data_ret);

            break;
        } else if (X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)) && X11->net_virtual_root_list) {
            int i = 0;
            while (X11->net_virtual_root_list[i] != 0) {
                if (X11->net_virtual_root_list[i++] == p)
                    break;
            }
        }

        l = w;
        w = p;
    }

    // we have our window
    int transx, transy;
    XWindowAttributes wattr;
    if (XTranslateCoordinates(X11->display, l, w,
                              0, 0, &transx, &transy, &p) &&
        XGetWindowAttributes(X11->display, w, &wattr)) {
        top->frameStrut.setCoords(transx,
                                  transy,
                                  wattr.width - data.crect.width() - transx,
                                  wattr.height - data.crect.height() - transy);

        // add the border_width for the window managers frame... some window managers
        // do not use a border_width of zero for their frames, and if we the left and
        // top strut, we ensure that pos() is absolutely correct.  frameGeometry()
        // will still be incorrect though... perhaps i should have foffset as well, to
        // indicate the frame offset (equal to the border_width on X).
        // - Brad
        top->frameStrut.adjust(wattr.border_width,
                               wattr.border_width,
                               wattr.border_width,
                               wattr.border_width);
    }

   data.fstrut_dirty = false;
}

void QWidgetPrivate::setWindowOpacity_sys(qreal opacity)
{
    Q_Q(QWidget);
    ulong value = ulong(opacity * 0xffffffff);
    XChangeProperty(QX11Info::display(), q->internalWinId(), ATOM(_NET_WM_WINDOW_OPACITY), XA_CARDINAL,
                    32, PropModeReplace, (uchar*)&value, 1);
}

const QX11Info &QWidget::x11Info() const
{
    Q_D(const QWidget);
    return d->xinfo;
}

void QWidgetPrivate::setWindowRole()
{
    Q_Q(QWidget);
    if (!q->internalWinId())
        return;
    QByteArray windowRole = topData()->role.toUtf8();
    XChangeProperty(X11->display, q->internalWinId(),
                    ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
                    (unsigned char *)windowRole.constData(), windowRole.length());
}

Q_GLOBAL_STATIC(QX11PaintEngine, qt_widget_paintengine)
QPaintEngine *QWidget::paintEngine() const
{
    Q_D(const QWidget);
    if (qt_widget_paintengine()->isActive()) {
        if (d->extraPaintEngine)
            return d->extraPaintEngine;
        QWidget *self = const_cast<QWidget *>(this);
        self->d_func()->extraPaintEngine = new QX11PaintEngine();
        return d->extraPaintEngine;
    }
    return qt_widget_paintengine();
}

QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
{
    return new QX11WindowSurface(q_func());
}

Qt::HANDLE QWidget::x11PictureHandle() const
{
#ifndef QT_NO_XRENDER
    Q_D(const QWidget);
    if (!internalWinId() && testAttribute(Qt::WA_WState_Created))
        (void)winId(); // enforce native window
    return d->picture;
#else
    return 0;
#endif // QT_NO_XRENDER
}

#ifndef QT_NO_XRENDER
XRenderColor QX11Data::preMultiply(const QColor &c)
{
    XRenderColor color;
    const uint A = c.alpha(),
               R = c.red(),
               G = c.green(),
               B = c.blue();
    color.alpha = (A | A << 8);
    color.red   = (R | R << 8) * color.alpha / 0x10000;
    color.green = (G | G << 8) * color.alpha / 0x10000;
    color.blue  = (B | B << 8) * color.alpha / 0x10000;
    return color;
}
Picture QX11Data::getSolidFill(int screen, const QColor &c)
{
    if (!X11->use_xrender)
        return XNone;

    XRenderColor color = preMultiply(c);
    for (int i = 0; i < X11->solid_fill_count; ++i) {
        if (X11->solid_fills[i].screen == screen
            && X11->solid_fills[i].color.alpha == color.alpha
            && X11->solid_fills[i].color.red == color.red
            && X11->solid_fills[i].color.green == color.green
            && X11->solid_fills[i].color.blue == color.blue)
            return X11->solid_fills[i].picture;
    }
    // none found, replace one
    int i = qrand() % 16;

    if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) {
        XRenderFreePicture (X11->display, X11->solid_fills[i].picture);
        X11->solid_fills[i].picture = 0;
    }

    if (!X11->solid_fills[i].picture) {
        Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 1, 1, 32);
        XRenderPictureAttributes attrs;
        attrs.repeat = True;
        X11->solid_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
                                                            XRenderFindStandardFormat(X11->display, PictStandardARGB32),
                                                            CPRepeat, &attrs);
        XFreePixmap (X11->display, pixmap);
    }

    X11->solid_fills[i].color = color;
    X11->solid_fills[i].screen = screen;
    XRenderFillRectangle (X11->display, PictOpSrc, X11->solid_fills[i].picture, &color, 0, 0, 1, 1);
    return X11->solid_fills[i].picture;
}
#endif

void QWidgetPrivate::setModal_sys()
{
}

void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &att)
{
    QX11InfoData* xd = xinfo->getX11Data(true);
    const XWindowAttributes &a = *(att.att);
    // find which screen the window is on...
    xd->screen = QX11Info::appScreen(); // by default, use the default :)
    int i;
    for (i = 0; i < ScreenCount(X11->display); i++) {
        if (RootWindow(X11->display, i) == a.root) {
            xd->screen = i;
            break;
        }
    }

    xd->depth = a.depth;
    xd->cells = DisplayCells(X11->display, xd->screen);
    xd->visual = a.visual;
    xd->defaultVisual = (XVisualIDFromVisual((Visual *) a.visual) ==
                         XVisualIDFromVisual((Visual *) QX11Info::appVisual(xinfo->screen())));
    xd->colormap = a.colormap;
    xd->defaultColormap = (a.colormap == QX11Info::appColormap(xinfo->screen()));
    xinfo->setX11Data(xd);
}

void QWidgetPrivate::updateX11AcceptFocus()
{
    Q_Q(QWidget);
    if (!q->isWindow() || !q->internalWinId())
        return;

    XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
    XWMHints wm_hints;
    if (!h) {
        memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
        h = &wm_hints;
    }
    h->flags |= InputHint;
    h->input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;

    XSetWMHints(X11->display, q->internalWinId(), h);
    if (h != &wm_hints)
        XFree((char *)h);
}

QT_END_NAMESPACE
