1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qcursor.h"
43 #include "qapplication.h"
44 #include "qapplication_p.h"
45 #include "qpainter.h"
46 #include "qbitmap.h"
47 #include "qimage.h"
48 #include "qhash.h"
49 #include "qstack.h"
50 #include "qlayout.h"
51 #include "qtextcodec.h"
52 #include "qinputcontext.h"
53 #include "qdesktopwidget.h"
54 
55 #include "qwsdisplay_qws.h"
56 #include "private/qwsdisplay_qws_p.h"
57 #include "qscreen_qws.h"
58 #include "qwsmanager_qws.h"
59 #include <private/qwsmanager_p.h>
60 #include <private/qbackingstore_p.h>
61 #include <private/qwindowsurface_qws_p.h>
62 #include <private/qwslock_p.h>
63 #include "qpaintengine.h"
64 
65 #include "qdebug.h"
66 
67 #include "qwidget_p.h"
68 
69 QT_BEGIN_NAMESPACE
70 
71 QT_USE_NAMESPACE
72 
73 extern int *qt_last_x;
74 extern int *qt_last_y;
75 extern WId qt_last_cursor;
76 extern bool qws_overrideCursor;
77 extern QWidget *qt_pressGrab;
78 extern QWidget *qt_mouseGrb;
79 
80 static QWidget *keyboardGrb = 0;
81 
takeLocalId()82 static int takeLocalId()
83 {
84     static int n=-1000;
85     return --n;
86 }
87 
88 class QWSServer;
89 extern QWSServer *qwsServer;
90 
isServerProcess()91 static inline bool isServerProcess()
92 {
93     return (qwsServer != 0);
94 }
95 
96 /*****************************************************************************
97   QWidget member functions
98  *****************************************************************************/
99 
create_sys(WId window,bool initializeWindow,bool)100 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool /*destroyOldWindow*/)
101 {
102     Q_Q(QWidget);
103     Qt::WindowType type = q->windowType();
104 
105     // Make sure the WindowTitleHint is on if any of the title bar hints are set
106     // Note: This might be moved to cross-platform QWidgetPrivate::adjustFlags()
107     if (  !(data.window_flags & Qt::CustomizeWindowHint) && (
108            (data.window_flags & Qt::WindowSystemMenuHint) ||
109            (data.window_flags & Qt::WindowContextHelpButtonHint) ||
110            (data.window_flags & Qt::WindowMinimizeButtonHint) ||
111            (data.window_flags & Qt::WindowMaximizeButtonHint) ||
112            (data.window_flags & Qt::WindowCloseButtonHint) ) ) {
113         data.window_flags |= Qt::WindowTitleHint;
114     }
115 
116     // Decoration plugins on QWS don't support switching on the close button on its own
117     if (data.window_flags & Qt::WindowCloseButtonHint)
118         data.window_flags |= Qt::WindowSystemMenuHint;
119 
120     Qt::WindowFlags flags = data.window_flags;
121 
122     data.alloc_region_index = -1;
123 
124     // we don't have a "Drawer" window type
125     if (type == Qt::Drawer) {
126         type = Qt::Widget;
127         flags &= ~Qt::WindowType_Mask;
128     }
129 
130 
131     bool topLevel = (flags & Qt::Window);
132     bool popup = (type == Qt::Popup);
133     bool dialog = (type == Qt::Dialog
134                    || type == Qt::Sheet
135                    || (flags & Qt::MSWindowsFixedSizeDialogHint));
136     bool desktop = (type == Qt::Desktop);
137     bool tool = (type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip);
138 
139 
140 #ifndef QT_NO_WARNING_OUTPUT
141     static bool toolWarningShown = false;
142     if (!toolWarningShown && type == Qt::Tool && !(flags & Qt::FramelessWindowHint)) {
143         qWarning("Qt for Embedded Linux " QT_VERSION_STR " does not support tool windows with frames.\n"
144                  "This behavior will change in a later release. To ensure compatibility with\n"
145                  "future versions, use (Qt::Tool | Qt::FramelessWindowHint).");
146         toolWarningShown = true;
147     }
148 #endif
149 
150     WId           id;
151     QWSDisplay* dpy = QWidget::qwsDisplay();
152 
153     if (!window)                                // always initialize
154         initializeWindow = true;
155 
156     // use the size of the primary screen to determine the default window size
157     QList<QScreen *> screens = qt_screen->subScreens();
158     if (screens.isEmpty())
159         screens.append(qt_screen);
160     int sw = screens[0]->width();
161     int sh = screens[0]->height();
162 
163     if (desktop) {                                // desktop widget
164         dialog = popup = false;                        // force these flags off
165         data.crect.setRect(0, 0, sw, sh);
166     } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
167         int width = sw / 2;
168         int height = 4 * sh / 10;
169         if (extra) {
170             width = qMax(qMin(width, extra->maxw), extra->minw);
171             height = qMax(qMin(height, extra->maxh), extra->minh);
172         }
173         data.crect.setSize(QSize(width, height));
174     }
175 
176     if (window) {                                // override the old window
177         id = window;
178         setWinId(window);
179     } else if (desktop) {                        // desktop widget
180         id = (WId)-2;                                // id = root window
181 #if 0
182         QWidget *otherDesktop = q->find(id);        // is there another desktop?
183         if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
184             otherDesktop->d_func()->setWinId(0);        // remove id from widget mapper
185             setWinId(id);                        // make sure otherDesktop is
186             otherDesktop->d_func()->setWinId(id);        //   found first
187         } else
188 #endif
189         {
190             setWinId(id);
191         }
192     } else {
193         id = topLevel ? dpy->takeId() : takeLocalId();
194         setWinId(id);                                // set widget id/handle + hd
195     }
196 
197 
198     bool hasFrame = true;
199     if (topLevel) {
200         if (desktop || popup || tool || q->testAttribute(Qt::WA_DontShowOnScreen))
201             hasFrame = false;
202         else
203             hasFrame = !(flags & Qt::FramelessWindowHint);
204     }
205     if (desktop) {
206         q->setAttribute(Qt::WA_WState_Visible);
207     } else if (topLevel) {                        // set X cursor
208         //QCursor *oc = QApplication::overrideCursor();
209         if (initializeWindow) {
210             //XXX XDefineCursor(dpy, winid, oc ? oc->handle() : cursor().handle());
211         }
212         QWidget::qwsDisplay()->nameRegion(q->internalWinId(), q->objectName(), q->windowTitle());
213     }
214 
215     if (topLevel) {
216         createTLExtra();
217         QTLWExtra *topextra = extra->topextra;
218 #ifndef QT_NO_QWS_MANAGER
219         if (hasFrame) {
220             // get size of wm decoration and make the old crect the new frect
221             QRect cr = data.crect;
222             QRegion r = QApplication::qwsDecoration().region(q, cr) | cr;
223             QRect br(r.boundingRect());
224             topextra->frameStrut.setCoords(cr.x() - br.x(),
225                                                   cr.y() - br.y(),
226                                                   br.right() - cr.right(),
227                                                   br.bottom() - cr.bottom());
228             if (!q->testAttribute(Qt::WA_Moved) || topextra->posFromMove)
229                 data.crect.translate(topextra->frameStrut.left(), topextra->frameStrut.top());
230             if (!topData()->qwsManager) {
231                 topData()->qwsManager = new QWSManager(q);
232                 if((q->data->window_state & ~Qt::WindowActive) == Qt::WindowMaximized)
233                     topData()->qwsManager->maximize();
234             }
235 
236         } else if (topData()->qwsManager) {
237             delete topData()->qwsManager;
238             topData()->qwsManager = 0;
239             data.crect.translate(-topextra->frameStrut.left(), -topextra->frameStrut.top());
240             topextra->frameStrut.setCoords(0, 0, 0, 0);
241         }
242 #endif
243         if (!topextra->caption.isEmpty())
244             setWindowTitle_helper(topextra->caption);
245 
246         //XXX If we are session managed, inform the window manager about it
247     } else {
248         if (extra && extra->topextra)        { // already allocated due to reparent?
249             extra->topextra->frameStrut.setCoords(0, 0, 0, 0);
250         }
251         //updateRequestedRegion(mapToGlobal(QPoint(0,0)));
252     }
253 }
254 
255 
destroy(bool destroyWindow,bool destroySubWindows)256 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
257 {
258     Q_D(QWidget);
259     d->aboutToDestroy();
260     if (!isWindow() && parentWidget())
261         parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
262 
263     d->deactivateWidgetCleanup();
264     if (testAttribute(Qt::WA_WState_Created)) {
265         setAttribute(Qt::WA_WState_Created, false);
266         QObjectList childObjects =  children();
267         for (int i = 0; i < childObjects.size(); ++i) {
268             QObject *obj = childObjects.at(i);
269             if (obj->isWidgetType())
270                 static_cast<QWidget*>(obj)->destroy(destroySubWindows,
271                                                      destroySubWindows);
272         }
273         releaseMouse();
274         if (qt_pressGrab == this)
275           qt_pressGrab = 0;
276 
277         if (keyboardGrb == this)
278             releaseKeyboard();
279         if (testAttribute(Qt::WA_ShowModal))                // just be sure we leave modal
280             QApplicationPrivate::leaveModal(this);
281         else if ((windowType() == Qt::Popup))
282             qApp->d_func()->closePopup(this);
283 #ifndef QT_NO_IM
284         if (d->ic) {
285             delete d->ic;
286             d->ic =0;
287         } else {
288             // release previous focus information participating with
289             // preedit preservation of qic -- while we still have a winId
290             QInputContext *qic = QApplicationPrivate::inputContext;
291             if (qic)
292                 qic->widgetDestroyed(this);
293         }
294 #endif //QT_NO_IM
295 
296         if ((windowType() == Qt::Desktop)) {
297         } else {
298             if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
299                 d->hide_sys();
300             }
301             if (destroyWindow && isWindow()) {
302                 if (d->extra && d->extra->topextra && d->extra->topextra->backingStore)
303                     d->extra->topextra->backingStore->windowSurface->setGeometry(QRect());
304                 qwsDisplay()->destroyRegion(internalWinId());
305             }
306         }
307         QT_TRY {
308             d->setWinId(0);
309         } QT_CATCH (const std::bad_alloc &) {
310             // swallow - destructors must not throw
311         }
312     }
313 }
314 
315 
setParent_sys(QWidget * newparent,Qt::WindowFlags f)316 void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
317 {
318     Q_Q(QWidget);
319     bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
320      if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
321         q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
322 #ifndef QT_NO_CURSOR
323     QCursor oldcurs;
324     bool setcurs=q->testAttribute(Qt::WA_SetCursor);
325     if (setcurs) {
326         oldcurs = q->cursor();
327         q->unsetCursor();
328     }
329 #endif
330 
331     WId old_winid = data.winid;
332     if ((q->windowType() == Qt::Desktop))
333         old_winid = 0;
334 
335     if (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_WState_Created))
336         hide_sys();
337 
338     setWinId(0);
339 
340     if (parent != newparent) {
341         QWidget *oldparent = q->parentWidget();
342         QObjectPrivate::setParent_helper(newparent);
343         if (oldparent) {
344 //            oldparent->d_func()->setChildrenAllocatedDirty();
345 //            oldparent->data->paintable_region_dirty = true;
346         }
347         if (newparent) {
348 //            newparent->d_func()->setChildrenAllocatedDirty();
349 //            newparent->data->paintable_region_dirty = true;
350             //@@@@@@@
351         }
352     }
353     Qt::FocusPolicy fp = q->focusPolicy();
354     QSize    s            = q->size();
355     //QBrush   bgc    = background();                        // save colors
356     bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
357 
358     data.window_flags = f;
359     q->setAttribute(Qt::WA_WState_Created, false);
360     q->setAttribute(Qt::WA_WState_Visible, false);
361     q->setAttribute(Qt::WA_WState_Hidden, false);
362     adjustFlags(data.window_flags, q);
363     // keep compatibility with previous versions, we need to preserve the created state
364     // (but we recreate the winId for the widget being reparented, again for compatibility)
365     if (wasCreated || (!q->isWindow() && newparent->testAttribute(Qt::WA_WState_Created)))
366         createWinId();
367     if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
368         q->setAttribute(Qt::WA_WState_Hidden);
369     q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
370 
371     if (q->isWindow()) {
372         QRect fs = frameStrut();
373         data.crect = QRect(fs.left(), fs.top(), s.width(), s.height());
374         if ((data.window_flags & Qt::FramelessWindowHint) && extra && extra->topextra)
375             extra->topextra->frameStrut.setCoords(0, 0, 0, 0);
376     } else {
377         data.crect = QRect(0, 0, s.width(), s.height());
378     }
379 
380     q->setFocusPolicy(fp);
381     if (extra && !extra->mask.isEmpty()) {
382         QRegion r = extra->mask;
383         extra->mask = QRegion();
384         q->setMask(r);
385     }
386     if ((int)old_winid > 0) {
387         QWidget::qwsDisplay()->destroyRegion(old_winid);
388         extra->topextra->backingStore->windowSurface->setGeometry(QRect());
389     }
390 #ifndef QT_NO_CURSOR
391     if (setcurs) {
392         q->setCursor(oldcurs);
393     }
394 #endif
395 }
396 
397 
mapToGlobal(const QPoint & pos) const398 QPoint QWidget::mapToGlobal(const QPoint &pos) const
399 {
400     int           x=pos.x(), y=pos.y();
401     const QWidget* w = this;
402     while (w) {
403         x += w->data->crect.x();
404         y += w->data->crect.y();
405         w = w->isWindow() ? 0 : w->parentWidget();
406     }
407     return QPoint(x, y);
408 }
409 
mapFromGlobal(const QPoint & pos) const410 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
411 {
412     int           x=pos.x(), y=pos.y();
413     const QWidget* w = this;
414     while (w) {
415         x -= w->data->crect.x();
416         y -= w->data->crect.y();
417         w = w->isWindow() ? 0 : w->parentWidget();
418     }
419     return QPoint(x, y);
420 }
421 
422 #if 0 // #####
423 void QWidget::setMicroFocusHint(int x, int y, int width, int height,
424                                  bool text, QFont *)
425 {
426     if (QRect(x, y, width, height) != microFocusHint()) {
427         d->createExtra();
428         d->extra->micro_focus_hint.setRect(x, y, width, height);
429     }
430 #ifndef QT_NO_QWS_INPUTMETHODS
431     if (text) {
432         QWidget *tlw = window();
433         int winid = tlw->internalWinId();
434         QPoint p(x, y + height);
435         QPoint gp = mapToGlobal(p);
436 
437         QRect r = QRect(mapToGlobal(QPoint(0,0)),
438                          size());
439 
440         r.setBottom(tlw->geometry().bottom());
441 
442         //qDebug("QWidget::setMicroFocusHint %d %d %d %d", r.x(),
443         //        r.y(), r.width(), r.height());
444         QInputContext::setMicroFocusWidget(this);
445 
446         qwsDisplay()->setIMInfo(winid, gp.x(), gp.y(), r);
447 
448         //send font info,  ###if necessary
449         qwsDisplay()->setInputFont(winid, font());
450     }
451 #endif
452 }
453 #endif
454 
updateSystemBackground()455 void QWidgetPrivate::updateSystemBackground() {}
456 
457 #ifndef QT_NO_CURSOR
setCursor_sys(const QCursor & cursor)458 void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
459 {
460     Q_UNUSED(cursor);
461     Q_Q(QWidget);
462     if (q->isVisible())
463         updateCursor();
464 }
465 
unsetCursor_sys()466 void QWidgetPrivate::unsetCursor_sys()
467 {
468     Q_Q(QWidget);
469     if (q->isVisible())
470         updateCursor();
471 }
472 #endif //QT_NO_CURSOR
473 
setWindowTitle_sys(const QString & caption)474 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
475 {
476     Q_Q(QWidget);
477     QWidget::qwsDisplay()->setWindowCaption(q, caption);
478 }
479 
setWindowIcon_sys(bool)480 void QWidgetPrivate::setWindowIcon_sys(bool /*forceReset*/)
481 {
482 #if 0
483      QTLWExtra* x = d->topData();
484      delete x->icon;
485      x->icon = 0;
486     QBitmap mask;
487     if (unscaledPixmap.isNull()) {
488     } else {
489         QImage unscaledIcon = unscaledPixmap.toImage();
490         QPixmap pixmap =
491             QPixmap::fromImage(unscaledIcon.scale(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
492         x->icon = new QPixmap(pixmap);
493         mask = pixmap.mask() ? *pixmap.mask() : pixmap.createHeuristicMask();
494     }
495 #endif
496 }
497 
setWindowIconText_sys(const QString & iconText)498 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
499 {
500     Q_UNUSED(iconText);
501 }
502 
grabMouse()503 void QWidget::grabMouse()
504 {
505     if (qt_mouseGrb)
506         qt_mouseGrb->releaseMouse();
507 
508     qwsDisplay()->grabMouse(this,true);
509 
510     qt_mouseGrb = this;
511     qt_pressGrab = 0;
512 }
513 
514 #ifndef QT_NO_CURSOR
grabMouse(const QCursor & cursor)515 void QWidget::grabMouse(const QCursor &cursor)
516 {
517     if (qt_mouseGrb)
518         qt_mouseGrb->releaseMouse();
519 
520     qwsDisplay()->grabMouse(this,true);
521     qwsDisplay()->selectCursor(this, cursor.handle());
522     qt_mouseGrb = this;
523     qt_pressGrab = 0;
524 }
525 #endif
526 
releaseMouse()527 void QWidget::releaseMouse()
528 {
529     if (qt_mouseGrb == this) {
530         qwsDisplay()->grabMouse(this,false);
531         qt_mouseGrb = 0;
532     }
533 }
534 
grabKeyboard()535 void QWidget::grabKeyboard()
536 {
537     if (keyboardGrb)
538         keyboardGrb->releaseKeyboard();
539     qwsDisplay()->grabKeyboard(this, true);
540     keyboardGrb = this;
541 }
542 
releaseKeyboard()543 void QWidget::releaseKeyboard()
544 {
545     if (keyboardGrb == this) {
546         qwsDisplay()->grabKeyboard(this, false);
547         keyboardGrb = 0;
548     }
549 }
550 
551 
mouseGrabber()552 QWidget *QWidget::mouseGrabber()
553 {
554     if (qt_mouseGrb)
555         return qt_mouseGrb;
556     return qt_pressGrab;
557 }
558 
559 
keyboardGrabber()560 QWidget *QWidget::keyboardGrabber()
561 {
562     return keyboardGrb;
563 }
564 
activateWindow()565 void QWidget::activateWindow()
566 {
567     QWidget *tlw = window();
568     if (tlw->isVisible()) {
569         Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
570         qwsDisplay()->requestFocus(tlw->internalWinId(), true);
571     }
572 }
573 
show_sys()574 void QWidgetPrivate::show_sys()
575 {
576     Q_Q(QWidget);
577     q->setAttribute(Qt::WA_Mapped);
578     if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
579         invalidateBuffer(q->rect());
580         return;
581     }
582 
583     if (q->isWindow()) {
584 
585 
586         if (!q->testAttribute(Qt::WA_ShowWithoutActivating)
587             && q->windowType() != Qt::Popup
588             && q->windowType() != Qt::Tool
589             && q->windowType() != Qt::ToolTip) {
590             QWidget::qwsDisplay()->requestFocus(data.winid,true);
591         }
592 
593 
594         if (QWindowSurface *surface = q->windowSurface()) {
595             const QRect frameRect = q->frameGeometry();
596             if (surface->geometry() != frameRect)
597                 surface->setGeometry(frameRect);
598         }
599 
600         QRegion r = localRequestedRegion();
601 #ifndef QT_NO_QWS_MANAGER
602         if (extra && extra->topextra && extra->topextra->qwsManager) {
603             r.translate(data.crect.topLeft());
604             r += extra->topextra->qwsManager->region();
605             r.translate(-data.crect.topLeft());
606         }
607 #endif
608         data.fstrut_dirty = true;
609         invalidateBuffer(r);
610 	bool staysontop =
611             (q->windowFlags() & Qt::WindowStaysOnTopHint)
612             || q->windowType() == Qt::Popup;
613         if (!staysontop && q->parentWidget()) { // if our parent stays on top, so must we
614             QWidget *ptl = q->parentWidget()->window();
615             if (ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
616                 staysontop = true;
617         }
618 
619         QWSChangeAltitudeCommand::Altitude altitude;
620         altitude = staysontop ? QWSChangeAltitudeCommand::StaysOnTop : QWSChangeAltitudeCommand::Raise;
621         QWidget::qwsDisplay()->setAltitude(data.winid, altitude, true);
622         if (!q->objectName().isEmpty()) {
623             QWidget::qwsDisplay()->setWindowCaption(q, q->windowTitle());
624         }
625     }
626 #ifdef Q_BACKINGSTORE_SUBSURFACES
627     else if ( extra && extra->topextra && extra->topextra->windowSurface) {
628         QWSWindowSurface *surface;
629         surface = static_cast<QWSWindowSurface*>(q->windowSurface());
630         const QPoint p = q->mapToGlobal(QPoint());
631         surface->setGeometry(QRect(p, q->size()));
632     }
633 #endif
634 
635     if (!q->window()->data->in_show) {
636          invalidateBuffer(q->rect());
637     }
638 }
639 
640 
hide_sys()641 void QWidgetPrivate::hide_sys()
642 {
643     Q_Q(QWidget);
644     deactivateWidgetCleanup();
645 
646     if (q->isWindow()) {
647         q->releaseMouse();
648 //        requestWindowRegion(QRegion());
649 
650         if (extra->topextra->backingStore)
651             extra->topextra->backingStore->releaseBuffer();
652 
653 
654         QWidget::qwsDisplay()->requestFocus(data.winid,false);
655     } else {
656         QWidget *p = q->parentWidget();
657         if (p &&p->isVisible()) {
658             invalidateBuffer(q->rect());
659         }
660     }
661 }
662 
663 
664 
effectiveState(Qt::WindowStates state)665 static Qt::WindowStates effectiveState(Qt::WindowStates state)
666  {
667      if (state & Qt::WindowMinimized)
668          return Qt::WindowMinimized;
669      else if (state & Qt::WindowFullScreen)
670          return Qt::WindowFullScreen;
671      else if (state & Qt::WindowMaximized)
672          return Qt::WindowMaximized;
673      return Qt::WindowNoState;
674  }
675 
setMaxWindowState_helper()676 void QWidgetPrivate::setMaxWindowState_helper()
677 {
678     // in_set_window_state is usually set in setWindowState(), but this
679     // function is used in other functions as well
680     // (e.g QApplicationPrivate::setMaxWindowRect())
681     const uint old_state = data.in_set_window_state;
682     data.in_set_window_state = 1;
683 
684 #ifndef QT_NO_QWS_MANAGER
685     if (extra && extra->topextra && extra->topextra->qwsManager)
686         extra->topextra->qwsManager->maximize();
687     else
688 #endif
689     {
690         Q_Q(QWidget);
691         const QDesktopWidget *desktop = QApplication::desktop();
692         const int screen = desktop->screenNumber(q);
693         const QRect maxWindowRect = desktop->availableGeometry(screen);
694         q->setGeometry(maxWindowRect);
695     }
696     data.in_set_window_state = old_state;
697 }
698 
setFullScreenSize_helper()699 void QWidgetPrivate::setFullScreenSize_helper()
700 {
701     Q_Q(QWidget);
702 
703     const uint old_state = data.in_set_window_state;
704     data.in_set_window_state = 1;
705 
706     const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
707     q->move(screen.topLeft());
708     q->resize(screen.size());
709 
710     data.in_set_window_state = old_state;
711 }
712 
setWindowState(Qt::WindowStates newstate)713 void QWidget::setWindowState(Qt::WindowStates newstate)
714 {
715     Q_D(QWidget);
716     Qt::WindowStates oldstate = windowState();
717     if (oldstate == newstate)
718         return;
719     if (isWindow() && !testAttribute(Qt::WA_WState_Created))
720         create();
721 
722     data->window_state = newstate;
723     data->in_set_window_state = 1;
724     bool needShow = false;
725     Qt::WindowStates newEffectiveState = effectiveState(newstate);
726     Qt::WindowStates oldEffectiveState = effectiveState(oldstate);
727     if (isWindow() && newEffectiveState != oldEffectiveState) {
728         d->createTLExtra();
729         if (oldEffectiveState == Qt::WindowNoState) { //normal
730             d->topData()->normalGeometry = geometry();
731         } else if (oldEffectiveState == Qt::WindowFullScreen) {
732             setParent(0, d->topData()->savedFlags);
733             needShow = true;
734         } else if (oldEffectiveState == Qt::WindowMinimized) {
735             needShow = true;
736         }
737 
738         if (newEffectiveState == Qt::WindowMinimized) {
739             //### not ideal...
740             hide();
741             needShow = false;
742         } else if (newEffectiveState == Qt::WindowFullScreen) {
743             d->topData()->savedFlags = windowFlags();
744             setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
745             d->setFullScreenSize_helper();
746             raise();
747             needShow = true;
748         } else if (newEffectiveState == Qt::WindowMaximized) {
749             createWinId();
750             d->setMaxWindowState_helper();
751         } else { //normal
752             QRect r = d->topData()->normalGeometry;
753             if (r.width() >= 0) {
754                 d->topData()->normalGeometry = QRect(0,0,-1,-1);
755                 setGeometry(r);
756             }
757         }
758     }
759     data->in_set_window_state = 0;
760 
761     if (needShow)
762         show();
763 
764     if (newstate & Qt::WindowActive)
765         activateWindow();
766 
767     QWindowStateChangeEvent e(oldstate);
768     QApplication::sendEvent(this, &e);
769 }
770 
setFocus_sys()771 void QWidgetPrivate::setFocus_sys()
772 {
773 
774 }
775 
raise_sys()776 void QWidgetPrivate::raise_sys()
777 {
778     Q_Q(QWidget);
779     //@@@ transaction
780     if (q->isWindow()) {
781         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
782         QWidget::qwsDisplay()->setAltitude(q->internalWinId(),
783                                            QWSChangeAltitudeCommand::Raise);
784         // XXX: subsurfaces?
785 #ifdef QT_NO_WINDOWGROUPHINT
786 #else
787         QObjectList childObjects =  q->children();
788         if (!childObjects.isEmpty()) {
789             QWidgetList toraise;
790             for (int i = 0; i < childObjects.size(); ++i) {
791                 QObject *obj = childObjects.at(i);
792                 if (obj->isWidgetType()) {
793                     QWidget* w = static_cast<QWidget*>(obj);
794                     if (w->isWindow())
795                         toraise.append(w);
796                 }
797             }
798 
799             for (int i = 0; i < toraise.size(); ++i) {
800                 QWidget *w = toraise.at(i);
801                 if (w->isVisible())
802                     w->raise();
803             }
804         }
805 #endif // QT_NO_WINDOWGROUPHINT
806     }
807 }
808 
lower_sys()809 void QWidgetPrivate::lower_sys()
810 {
811     Q_Q(QWidget);
812     if (q->isWindow()) {
813         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
814         QWidget::qwsDisplay()->setAltitude(data.winid,
815                                            QWSChangeAltitudeCommand::Lower);
816     } else if (QWidget *p = q->parentWidget()) {
817         setDirtyOpaqueRegion();
818         p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
819     }
820 }
821 
stackUnder_sys(QWidget *)822 void QWidgetPrivate::stackUnder_sys(QWidget*)
823 {
824     Q_Q(QWidget);
825     if (QWidget *p = q->parentWidget()) {
826         setDirtyOpaqueRegion();
827         p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
828     }
829 }
830 
moveSurface(QWindowSurface * surface,const QPoint & offset)831 void QWidgetPrivate::moveSurface(QWindowSurface *surface, const QPoint &offset)
832 {
833     QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surface);
834     if (!s->move(offset))
835         s->invalidateBuffer();
836 
837     QWSDisplay::instance()->moveRegion(s->winId(), offset.x(), offset.y());
838 }
839 
setGeometry_sys(int x,int y,int w,int h,bool isMove)840 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
841 {
842     Q_Q(QWidget);
843     if (extra) {                                // any size restrictions?
844         w = qMin(w,extra->maxw);
845         h = qMin(h,extra->maxh);
846         w = qMax(w,extra->minw);
847         h = qMax(h,extra->minh);
848     }
849 
850     QPoint oldp = q->geometry().topLeft();
851     QSize olds = q->size();
852     QRect r(x, y, w, h);
853 
854     bool isResize = olds != r.size();
855     isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
856 
857     // We only care about stuff that changes the geometry, or may
858     // cause the window manager to change its state
859     if (r.size() == olds && oldp == r.topLeft())
860         return;
861 
862     if (!data.in_set_window_state) {
863         q->data->window_state &= ~Qt::WindowMaximized;
864         q->data->window_state &= ~Qt::WindowFullScreen;
865         if (q->isWindow())
866             topData()->normalGeometry = QRect(0, 0, -1, -1);
867     }
868     QPoint oldPos = q->pos();
869     data.crect = r;
870 
871     if ((q->windowType() == Qt::Desktop))
872         return;
873 
874     if (q->isVisible()) {
875 
876         bool toplevelMove = false;
877         QWSWindowSurface *surface = 0;
878 
879         if (q->isWindow()) {
880             //### ConfigPending not implemented, do we need it?
881             //setAttribute(Qt::WA_WState_ConfigPending);
882             const QWidgetBackingStore *bs = maybeBackingStore();
883             if (bs)
884                 surface = static_cast<QWSWindowSurface*>(bs->windowSurface);
885             if (isMove && !isResize && surface) {
886                 const QPoint offset(x - oldp.x(), y - oldp.y());
887                 moveSurface(surface, offset);
888                 toplevelMove = true; //server moves window, but we must send moveEvent, which might trigger painting
889 
890 #ifdef Q_BACKINGSTORE_SUBSURFACES
891                 QList<QWindowSurface*> surfaces = bs->subSurfaces;
892                 for (int i = 0; i < surfaces.size(); ++i)
893                     moveSurface(surfaces.at(i), offset);
894 #endif
895             } else {
896                     updateFrameStrut();
897             }
898         }
899 
900         if (!toplevelMove) {
901             if (q->isWindow()) {
902                 if (surface)
903                     surface->setGeometry(q->frameGeometry());
904                 else
905                     invalidateBuffer(q->rect()); //###
906 
907 #ifdef Q_BACKINGSTORE_SUBSURFACES
908                 // XXX: should not resize subsurfaces. Children within a layout
909                 // will be resized automatically while children with a static
910                 // geometry should get a new clip region instead.
911                 const QRect clipRect = q->geometry();
912                 QWidgetBackingStore *bs = maybeBackingStore();
913                 QList<QWindowSurface*> surfaces = bs->subSurfaces;
914                 for (int i = 0; i < surfaces.size(); ++i) {
915                     QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surfaces.at(i));
916                     QRect srect = s->geometry();
917                     s->setGeometry(clipRect & srect);
918                 }
919 #endif
920             }
921 #ifdef Q_BACKINGSTORE_SUBSURFACES
922             // XXX: merge this case with the isWindow() case
923             else if (maybeTopData() && maybeTopData()->windowSurface) {
924                 QWSWindowSurface *surface;
925                 surface = static_cast<QWSWindowSurface*>(q->windowSurface());
926                 if (isMove && !isResize) {
927                     moveSurface(surface, QPoint(x - oldp.x(), y - oldp.y()));
928                 } else {
929                     const QPoint p = q->mapToGlobal(QPoint());
930                     surface->setGeometry(QRect(p, QSize(w, h)));
931                 }
932             }
933 #endif
934             else {
935                 if (isMove && !isResize)
936                     moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
937                 else
938                     invalidateBuffer_resizeHelper(oldPos, olds);
939             }
940         }
941 
942         //### must have frame geometry correct before sending move/resize events
943         if (isMove) {
944             QMoveEvent e(q->pos(), oldPos);
945             QApplication::sendEvent(q, &e);
946         }
947         if (isResize) {
948             QResizeEvent e(r.size(), olds);
949             QApplication::sendEvent(q, &e);
950         }
951 
952     } else { // not visible
953         if (isMove && q->pos() != oldPos)
954             q->setAttribute(Qt::WA_PendingMoveEvent, true);
955         if (isResize)
956             q->setAttribute(Qt::WA_PendingResizeEvent, true);
957     }
958 }
959 
setConstraints_sys()960 void QWidgetPrivate::setConstraints_sys()
961 {
962 }
963 
getScreen() const964 QScreen* QWidgetPrivate::getScreen() const
965 {
966     Q_Q(const QWidget);
967 
968     const QList<QScreen*> subScreens = qt_screen->subScreens();
969     if (subScreens.isEmpty() || q->windowType() == Qt::Desktop)
970         return qt_screen;
971 
972     const int screen = QApplication::desktop()->screenNumber(q);
973 
974     return qt_screen->subScreens().at(screen < 0 ? 0 : screen);
975 }
976 
scroll_sys(int dx,int dy)977 void QWidgetPrivate::scroll_sys(int dx, int dy)
978 {
979     Q_Q(QWidget);
980     scrollChildren(dx, dy);
981     scrollRect(q->rect(), dx, dy);
982 }
983 
scroll_sys(int dx,int dy,const QRect & r)984 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
985 {
986     scrollRect(r, dx, dy);
987 }
988 
metric(PaintDeviceMetric m) const989 int QWidget::metric(PaintDeviceMetric m) const
990 {
991     Q_D(const QWidget);
992 
993     int val;
994     if (m == PdmWidth) {
995         val = data->crect.width();
996     } else if (m == PdmWidthMM) {
997         const QScreen *screen = d->getScreen();
998         val = data->crect.width() * screen->physicalWidth() / screen->width();
999     } else if (m == PdmHeight) {
1000         val = data->crect.height();
1001     } else if (m == PdmHeightMM) {
1002         const QScreen *screen = d->getScreen();
1003         val = data->crect.height() * screen->physicalHeight() / screen->height();
1004     } else if (m == PdmDepth) {
1005         return qwsDisplay()->depth();
1006     } else if (m == PdmDpiX || m == PdmPhysicalDpiX) {
1007         if (d->extra && d->extra->customDpiX)
1008             return d->extra->customDpiX;
1009         else if (d->parent)
1010             return static_cast<QWidget *>(d->parent)->metric(m);
1011         const QScreen *screen = d->getScreen();
1012         return qRound(screen->width() / double(screen->physicalWidth() / 25.4));
1013     } else if (m == PdmDpiY || m == PdmPhysicalDpiY) {
1014         if (d->extra && d->extra->customDpiY)
1015             return d->extra->customDpiY;
1016         else if (d->parent)
1017             return static_cast<QWidget *>(d->parent)->metric(m);
1018         const QScreen *screen = d->getScreen();
1019         return qRound(screen->height() / double(screen->physicalHeight() / 25.4));
1020     } else if (m == PdmNumColors) {
1021         QScreen *screen = d->getScreen();
1022         int ret = screen->colorCount();
1023         if (!ret) {
1024             const int depth = qwsDisplay()->depth();
1025             switch (depth) {
1026             case 1:
1027                 ret = 2;
1028                 break;
1029             case 8:
1030                 ret = 256;
1031                 break;
1032             case 16:
1033                 ret = 65536;
1034                 break;
1035             case 24:
1036                 ret = 16777216;
1037                 break;
1038             case 32:
1039                 ret = 2147483647;
1040                 break;
1041             }
1042         }
1043         return ret;
1044     } else {
1045         val = QPaintDevice::metric(m);// XXX
1046     }
1047     return val;
1048 }
1049 
createSysExtra()1050 void QWidgetPrivate::createSysExtra()
1051 {
1052 }
1053 
deleteSysExtra()1054 void QWidgetPrivate::deleteSysExtra()
1055 {
1056 }
1057 
createTLSysExtra()1058 void QWidgetPrivate::createTLSysExtra()
1059 {
1060 #ifndef QT_NO_QWS_MANAGER
1061     extra->topextra->qwsManager = 0;
1062 #endif
1063 }
1064 
deleteTLSysExtra()1065 void QWidgetPrivate::deleteTLSysExtra()
1066 {
1067 }
1068 
registerDropSite(bool on)1069 void QWidgetPrivate::registerDropSite(bool on)
1070 {
1071     Q_UNUSED(on);
1072 }
1073 
localRequestedRegion() const1074 QRegion QWidgetPrivate::localRequestedRegion() const
1075 {
1076     Q_Q(const QWidget);
1077     QRegion r(q->rect());
1078     if (extra && !extra->mask.isEmpty())
1079         r &= extra->mask;
1080 
1081     return r;
1082 }
1083 
localAllocatedRegion() const1084 QRegion QWidgetPrivate::localAllocatedRegion() const
1085 {
1086     Q_Q(const QWidget);
1087 
1088     QWidgetBackingStore *wbs = q->window()->d_func()->maybeBackingStore();
1089 
1090     QWindowSurface *ws = wbs ? wbs->windowSurface : 0;
1091     if (!ws)
1092         return QRegion();
1093     QRegion r = static_cast<QWSWindowSurface*>(ws)->clipRegion();
1094     if (!q->isWindow()) {
1095         QPoint off = q->mapTo(q->window(), QPoint());
1096         r &= localRequestedRegion().translated(off);
1097         r.translate(-off);
1098     }
1099     return r;
1100 }
1101 
intersects(const QRect & r) const1102 inline bool QRect::intersects(const QRect &r) const
1103 {
1104     return (qMax(x1, r.x1) <= qMin(x2, r.x2) &&
1105              qMax(y1, r.y1) <= qMin(y2, r.y2));
1106 }
1107 
setMask_sys(const QRegion & region)1108 void QWidgetPrivate::setMask_sys(const QRegion &region)
1109 {
1110     Q_UNUSED(region);
1111     Q_Q(QWidget);
1112 
1113     if (!q->isVisible() || !q->isWindow())
1114         return;
1115 
1116     data.fstrut_dirty = true;
1117     invalidateBuffer(q->rect());
1118     QWindowSurface *surface = extra->topextra->backingStore->windowSurface;
1119     if (surface) {
1120         // QWSWindowSurface::setGeometry() returns without doing anything
1121         // if old geom  == new geom. Therefore, we need to reset the old value.
1122         surface->QWindowSurface::setGeometry(QRect());
1123         surface->setGeometry(q->frameGeometry());
1124     }
1125 }
1126 
updateFrameStrut()1127 void QWidgetPrivate::updateFrameStrut()
1128 {
1129     Q_Q(QWidget);
1130 
1131     if(!q->isVisible() || (q->windowType() == Qt::Desktop)) {
1132         data.fstrut_dirty = q->isVisible();
1133         return;
1134     }
1135 
1136 #ifndef QT_NO_QWS_MANAGER
1137     if (extra && extra->topextra && extra->topextra->qwsManager) {
1138         QTLWExtra *topextra = extra->topextra;
1139         const QRect oldFrameStrut = topextra->frameStrut;
1140         const QRect contents = data.crect;
1141         QRegion r = localRequestedRegion().translated(contents.topLeft());
1142         r += extra->topextra->qwsManager->region();
1143         const QRect frame = r.boundingRect();
1144 
1145         topextra->frameStrut.setCoords(contents.left() - frame.left(),
1146                                        contents.top() - frame.top(),
1147                                        frame.right() - contents.right(),
1148                                        frame.bottom() - contents.bottom());
1149         topextra->qwsManager->repaintRegion(QDecoration::All, QDecoration::Normal);
1150     }
1151 #endif
1152     data.fstrut_dirty = false;
1153 }
1154 
1155 #ifndef QT_NO_CURSOR
updateCursor() const1156 void QWidgetPrivate::updateCursor() const
1157 {
1158     Q_Q(const QWidget);
1159 
1160     if (QApplication::overrideCursor())
1161         return;
1162 
1163     if (qt_last_x
1164         && (!QWidget::mouseGrabber() || QWidget::mouseGrabber() == q)
1165         && qt_last_cursor != (WId)q->cursor().handle())
1166     {
1167         const QPoint pos(*qt_last_x, *qt_last_y);
1168         const QPoint offset = q->mapToGlobal(QPoint());
1169         if (!localAllocatedRegion().contains(pos - offset))
1170             return;
1171 
1172         const QWidget *w = q->childAt(q->mapFromGlobal(pos));
1173         if (!w || w->cursor().handle() == q->cursor().handle())
1174             QWidget::qwsDisplay()->selectCursor(const_cast<QWidget*>(q),
1175                                                 q->cursor().handle());
1176     }
1177 }
1178 #endif
1179 
setWindowOpacity_sys(qreal level)1180 void QWidgetPrivate::setWindowOpacity_sys(qreal level)
1181 {
1182     Q_Q(QWidget);
1183     Q_UNUSED(level);
1184     createWinId();
1185     QWidget::qwsDisplay()->setOpacity(q->data->winid, topData()->opacity);
1186 }
1187 
1188 //static QSingleCleanupHandler<QWSPaintEngine> qt_paintengine_cleanup_handler;
1189 //static QWSPaintEngine *qt_widget_paintengine = 0;
paintEngine() const1190 QPaintEngine *QWidget::paintEngine() const
1191 {
1192     qWarning("QWidget::paintEngine: Should no longer be called");
1193     return 0; //##### @@@
1194 //     if (!qt_widget_paintengine) {
1195 //         qt_widget_paintengine = new QRasterPaintEngine();
1196 //         qt_paintengine_cleanup_handler.set(&qt_widget_paintengine);
1197 //     }
1198 //     if (qt_widget_paintengine->isActive()) {
1199 //         if (d->extraPaintEngine)
1200 //             return d->extraPaintEngine;
1201 //         const_cast<QWidget *>(this)->d_func()->extraPaintEngine = new QRasterPaintEngine();
1202 //         return d->extraPaintEngine;
1203 //     }
1204 //    return qt_widget_paintengine;
1205 }
1206 
createDefaultWindowSurface_sys()1207 QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
1208 {
1209     Q_Q(QWidget);
1210     if (q->windowType() == Qt::Desktop)
1211         return 0;
1212     q->ensurePolished();
1213     return qt_screen->createSurface(q);
1214 }
1215 
setModal_sys()1216 void QWidgetPrivate::setModal_sys()
1217 {
1218 }
1219 
1220 
1221 QT_END_NAMESPACE
1222