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 <qapplication.h>
43 #include <qwidget.h>
44 #include <qpainter.h>
45 #include <qpaintengine.h>
46 #include <qdrawutil.h>
47 #include "qdecorationdefault_qws.h"
48 
49 QT_BEGIN_NAMESPACE
50 
51 #if !defined(QT_NO_QWS_DECORATION_DEFAULT) || defined(QT_PLUGIN)
52 
53 QPixmap *QDecorationDefault::staticHelpPixmap = 0;
54 QPixmap *QDecorationDefault::staticMenuPixmap = 0;
55 QPixmap *QDecorationDefault::staticClosePixmap = 0;
56 QPixmap *QDecorationDefault::staticMinimizePixmap = 0;
57 QPixmap *QDecorationDefault::staticMaximizePixmap = 0;
58 QPixmap *QDecorationDefault::staticNormalizePixmap = 0;
59 
60 #ifndef QT_NO_IMAGEFORMAT_XPM
61 
62 /* XPM */
63 static const char * const default_menu_xpm[] = {
64 /* width height ncolors chars_per_pixel */
65 "16 16 11 1",
66 /* colors */
67 "  c #000000",
68 ". c #336600",
69 "X c #666600",
70 "o c #99CC00",
71 "O c #999933",
72 "+ c #333300",
73 "@ c #669900",
74 "# c #999900",
75 "$ c #336633",
76 "% c #666633",
77 "& c #99CC33",
78 /* pixels */
79 "oooooooooooooooo",
80 "oooooooooooooooo",
81 "ooooo#.++X#ooooo",
82 "ooooX      Xoooo",
83 "oooX  XO#%  X&oo",
84 "oo#  Ooo&@O  Ooo",
85 "oo. Xoo#+ @X Xoo",
86 "oo+ OoO+ +O# +oo",
87 "oo+ #O+  +## +oo",
88 "oo. %@ ++ +. Xoo",
89 "oo#  O@OO+   #oo",
90 "oooX  X##$   Ooo",
91 "ooooX        Xoo",
92 "oooo&OX++X#OXooo",
93 "oooooooooooooooo",
94 "oooooooooooooooo"
95 };
96 
97 static const char * const default_help_xpm[] = {
98 "16 16 3 1",
99 "       s None  c None",
100 ".      c #ffffff",
101 "X      c #707070",
102 "                ",
103 "                ",
104 "    ......      ",
105 "   ..XXXXXX     ",
106 "   .XX   .XX    ",
107 "   .XX   .XX    ",
108 "        ..XX    ",
109 "       ..XX     ",
110 "      ..XX      ",
111 "      .XX       ",
112 "      .XX       ",
113 "      ..        ",
114 "      .XX       ",
115 "      .XX       ",
116 "                ",
117 "                "};
118 
119 static const char * const default_close_xpm[] = {
120 "16 16 3 1",
121 "       s None  c None",
122 ".      c #ffffff",
123 "X      c #707070",
124 "                ",
125 "                ",
126 "  .X        .X  ",
127 "  .XX      .XX  ",
128 "   .XX    .XX   ",
129 "    .XX  .XX    ",
130 "     .XX.XX     ",
131 "      .XXX      ",
132 "      .XXX      ",
133 "     .XX.XX     ",
134 "    .XX  .XX    ",
135 "   .XX    .XX   ",
136 "  .XX      .XX  ",
137 "  .X        .X  ",
138 "                ",
139 "                "};
140 
141 static const char * const default_maximize_xpm[] = {
142 "16 16 3 1",
143 "       s None  c None",
144 ".      c #ffffff",
145 "X      c #707070",
146 "                ",
147 "                ",
148 "  ...........   ",
149 "  .XXXXXXXXXX   ",
150 "  .X       .X   ",
151 "  .X       .X   ",
152 "  .X       .X   ",
153 "  .X       .X   ",
154 "  .X       .X   ",
155 "  .X       .X   ",
156 "  .X       .X   ",
157 "  .X........X   ",
158 "  .XXXXXXXXXX   ",
159 "                ",
160 "                ",
161 "                "};
162 
163 static const char * const default_minimize_xpm[] = {
164 "16 16 3 1",
165 "       s None  c None",
166 ".      c #ffffff",
167 "X      c #707070",
168 "                ",
169 "                ",
170 "                ",
171 "                ",
172 "                ",
173 "                ",
174 "       ...      ",
175 "       . X      ",
176 "       .XX      ",
177 "                ",
178 "                ",
179 "                ",
180 "                ",
181 "                ",
182 "                ",
183 "                "};
184 
185 static const char * const default_normalize_xpm[] = {
186 "16 16 3 1",
187 "       s None  c None",
188 ".      c #ffffff",
189 "X      c #707070",
190 "                ",
191 "                ",
192 "     ........   ",
193 "     .XXXXXXXX  ",
194 "     .X     .X  ",
195 "     .X     .X  ",
196 "  ....X...  .X  ",
197 "  .XXXXXXXX .X  ",
198 "  .X     .XXXX  ",
199 "  .X     .X     ",
200 "  .X     .X     ",
201 "  .X......X     ",
202 "  .XXXXXXXX     ",
203 "                ",
204 "                ",
205 "                "};
206 
207 #endif // QT_NO_IMAGEFORMAT_XPM
208 
209 /*!
210   \class QDecorationDefault
211   \since 4.4
212   \ingroup qws
213   \brief The QDecorationDefault class is a base class providing default window decorations.
214 
215   See the documentation for class QDecoration for a detailed
216   description. This subclass of QDecoration provides standard
217   icons for the decoration regions.
218 
219   Note that this class is non-portable and only available in
220   \l{Qt for Embedded Linux}.
221  */
222 
223 /*!
224   Default constructor.
225  */
QDecorationDefault()226 QDecorationDefault::QDecorationDefault()
227     : QDecoration()
228 {
229     menu_width = 20;
230     help_width = 20;
231     close_width = 20;
232     minimize_width = 20;
233     maximize_width = 20;
234     normalize_width = 20;
235 }
236 
237 /*!
238   The constructor deletes the static pixmaps.
239  */
~QDecorationDefault()240 QDecorationDefault::~QDecorationDefault()
241 {
242     delete staticMenuPixmap;
243     delete staticClosePixmap;
244     delete staticMinimizePixmap;
245     delete staticMaximizePixmap;
246     delete staticNormalizePixmap;
247 
248     // This makes it safe to delete and then create a QDecorationDefault
249     staticMenuPixmap = 0;
250     staticClosePixmap = 0;
251     staticMinimizePixmap = 0;
252     staticMaximizePixmap = 0;
253     staticNormalizePixmap = 0;
254 }
255 
256 /*!
257   \fn const char **QDecorationDefault::xpmForRegion(int region)
258 
259   Returns a pointer to the X pixmap for the icon specified by
260   \a region. An X pixmap is an ASCII-text-based image. The value
261   of \a region must be one of a subset of the values of enum
262   DecorationRegion. The supported values are \e Help, \e Menu,
263   \e Close, \e Minimize, \e Maximize, and \e Normalize. Other
264   values of \a region cause zero to be returned.
265 
266   \sa QDecoration::DecorationRegion
267  */
xpmForRegion(int reg)268 const char **QDecorationDefault::xpmForRegion(int reg)
269 {
270 #ifdef QT_NO_IMAGEFORMAT_XPM
271     Q_UNUSED(reg);
272 #else
273     switch(reg)
274     {
275     case Help:
276         return (const char **)default_help_xpm;
277     case Menu:
278         return (const char **)default_menu_xpm;
279     case Close:
280         return (const char **)default_close_xpm;
281     case Minimize:
282         return (const char **)default_minimize_xpm;
283     case Maximize:
284         return (const char **)default_maximize_xpm;
285     case Normalize:
286         return (const char **)default_normalize_xpm;
287     }
288 #endif
289     return 0;
290 }
291 
292 /*!
293     \fn QPixmap QDecorationDefault::pixmapFor(const QWidget *widget,
294     int decorationRegion, int &xoff, int &yoff)
295 
296     Returns a pointer to the QPixmap for the widget specified by \a widget and
297     \a decorationRegion. The returned QPixmap is constructed from the default
298     X pixmap obtained from xpmForRegion().
299 
300     \a xoff and \a yoff specify the offset for the pixmap.
301 
302     The value of \a decorationRegion must be one of a subset of the values
303     of enum DecorationRegion. The supported values are \e Help,
304     \e Menu, \e Close, \e Minimize, \e Maximize, and \e Normalize.
305     Other values of \a decorationRegion return 0.
306 
307     \sa QDecoration::DecorationRegion
308 */
pixmapFor(const QWidget * widget,int decorationRegion,int & xoff,int &)309 QPixmap QDecorationDefault::pixmapFor(const QWidget *widget,
310                                       int decorationRegion,
311                                       int &xoff,
312                                       int &/*yoff*/)
313 {
314 #ifdef QT_NO_IMAGEFORMAT_XPM
315     Q_UNUSED(widget);
316     Q_UNUSED(decorationRegion);
317     Q_UNUSED(xoff);
318     return QPixmap();
319 #else
320     static const char **staticHelpPixmapXPM = 0;
321     static const char **staticMenuPixmapXPM = 0;
322     static const char **staticClosePixmapXPM = 0;
323     static const char **staticMinimizePixmapXPM = 0;
324     static const char **staticMaximizePixmapXPM = 0;
325     static const char **staticNormalizePixmapXPM = 0;
326     const char **xpm;
327 
328     // Why don't we just use/extend the enum type...
329 
330     if (staticHelpPixmapXPM != (xpm = xpmForRegion(Help)) || !staticHelpPixmap) {
331         staticHelpPixmapXPM = xpm;
332         staticHelpPixmap = new QPixmap(xpm);
333     }
334     if (staticMenuPixmapXPM != (xpm = xpmForRegion(Menu)) || !staticMenuPixmap) {
335         staticMenuPixmapXPM = xpm;
336         staticMenuPixmap = new QPixmap(xpm);
337     }
338     if (staticClosePixmapXPM != (xpm = xpmForRegion(Close)) || !staticClosePixmap) {
339         staticClosePixmapXPM = xpm;
340         staticClosePixmap = new QPixmap(xpm);
341     }
342     if (staticMinimizePixmapXPM != (xpm = xpmForRegion(Minimize)) || !staticMinimizePixmap) {
343         staticMinimizePixmapXPM = xpm;
344         staticMinimizePixmap = new QPixmap(xpm);
345     }
346     if (staticMaximizePixmapXPM != (xpm = xpmForRegion(Maximize)) || !staticMaximizePixmap) {
347         staticMaximizePixmapXPM = xpm;
348         staticMaximizePixmap = new QPixmap(xpm);
349     }
350     if (staticNormalizePixmapXPM != (xpm = xpmForRegion(Normalize)) || !staticNormalizePixmap) {
351         staticNormalizePixmapXPM = xpm;
352         staticNormalizePixmap = new QPixmap(xpm);
353     }
354 
355     const QPixmap *pm = 0;
356 
357     switch (decorationRegion) {
358         case Help:
359             pm = staticHelpPixmap;
360             break;
361         case Menu:
362             if (!widget->windowIcon().isNull())
363                 return widget->windowIcon().pixmap(16,16); //##### QIcon::pixmap() needs a size !!!!!!"
364             if (!pm) {
365                 xoff = 1;
366                 pm = staticMenuPixmap;
367             }
368             break;
369         case Close:
370             pm = staticClosePixmap;
371             break;
372         case Maximize:
373             pm = staticMaximizePixmap;
374             break;
375         case Normalize:
376             pm = staticNormalizePixmap;
377             break;
378         case Minimize:
379             pm = staticMinimizePixmap;
380             break;
381         default:
382             break;
383     }
384     return *pm;
385 #endif
386 }
387 
388 /*!
389     \fn int QDecorationDefault::titleBarHeight(const QWidget *widget)
390 
391     Returns the title bar height in pixels for the given \a widget. It is the
392     greater of 20, or the sum of the application font's line spacing value
393     plus a border width fudge factor.
394 */
titleBarHeight(const QWidget *)395 int QDecorationDefault::titleBarHeight(const QWidget *)
396 {
397     return qMax(20, QApplication::fontMetrics().height() + BORDER_WIDTH);
398 }
399 
400 /*!
401   Returns the region specified by \a decorationRegion for the
402   top-level \a widget. \a rect specifies the rectangle the decoration
403   wraps. The value of \a decorationRegion is a combination of the
404   bitmask values of enum DecorationRegion.
405  */
region(const QWidget * widget,const QRect & rect,int decorationRegion)406 QRegion QDecorationDefault::region(const QWidget *widget,
407                                    const QRect &rect,
408                                    int decorationRegion)
409 {
410     Qt::WindowFlags flags = widget->windowFlags();
411     bool hasBorder = !widget->isMaximized();
412     bool hasTitle = flags & Qt::WindowTitleHint;
413     bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
414     bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
415     bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
416     bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;
417     int state = widget->windowState();
418     bool isMinimized = state & Qt::WindowMinimized;
419     bool isMaximized = state & Qt::WindowMaximized;
420 
421     int titleHeight = hasTitle ? titleBarHeight(widget) : 0;
422     int bw = hasBorder ? BORDER_WIDTH : 0;
423     int bbw = hasBorder ? BOTTOM_BORDER_WIDTH : 0;
424 
425     QRegion region;
426     switch (decorationRegion) {
427         case All: {
428                 QRect r(rect.left() - bw,
429                         rect.top() - titleHeight - bw,
430                         rect.width() + 2 * bw,
431                         rect.height() + titleHeight + bw + bbw);
432                 region = r;
433                 region -= rect;
434             }
435             break;
436 
437         case Title: {
438                 QRect r(rect.left()
439                         + (hasSysMenu ? menu_width : 0),
440                         rect.top() - titleHeight,
441                         rect.width()
442                         - (hasSysMenu ? menu_width : 0)
443                         - close_width
444                         - (hasMaximize ? maximize_width : 0)
445                         - (hasMinimize ? minimize_width : 0)
446                         - (hasContextHelp ? help_width : 0),
447 
448                         titleHeight);
449                 if (r.width() > 0)
450                     region = r;
451             }
452             break;
453 
454         case Top: {
455                 QRect r(rect.left() + CORNER_GRAB,
456                         rect.top() - titleHeight - bw,
457                         rect.width() - 2 * CORNER_GRAB,
458                         bw);
459                 region = r;
460             }
461             break;
462 
463         case Left: {
464                 QRect r(rect.left() - bw,
465                         rect.top() - titleHeight + CORNER_GRAB,
466                         bw,
467                         rect.height() + titleHeight - 2 * CORNER_GRAB);
468                 region = r;
469             }
470             break;
471 
472         case Right: {
473                 QRect r(rect.right() + 1,
474                         rect.top() - titleHeight + CORNER_GRAB,
475                         bw,
476                         rect.height() + titleHeight - 2 * CORNER_GRAB);
477                 region = r;
478             }
479             break;
480 
481         case Bottom: {
482                 QRect r(rect.left() + CORNER_GRAB,
483                         rect.bottom() + 1,
484                         rect.width() - 2 * CORNER_GRAB,
485                         bw);
486                 region = r;
487             }
488             break;
489 
490         case TopLeft: {
491                 QRect r1(rect.left() - bw,
492                         rect.top() - bw - titleHeight,
493                         CORNER_GRAB + bw,
494                         bw);
495 
496                 QRect r2(rect.left() - bw,
497                         rect.top() - bw - titleHeight,
498                         bw,
499                         CORNER_GRAB + bw);
500 
501                 region = QRegion(r1) + r2;
502             }
503             break;
504 
505         case TopRight: {
506                 QRect r1(rect.right() - CORNER_GRAB,
507                         rect.top() - bw - titleHeight,
508                         CORNER_GRAB + bw,
509                         bw);
510 
511                 QRect r2(rect.right() + 1,
512                         rect.top() - bw - titleHeight,
513                         bw,
514                         CORNER_GRAB + bw);
515 
516                 region = QRegion(r1) + r2;
517             }
518             break;
519 
520         case BottomLeft: {
521                 QRect r1(rect.left() - bw,
522                         rect.bottom() + 1,
523                         CORNER_GRAB + bw,
524                         bw);
525 
526                 QRect r2(rect.left() - bw,
527                         rect.bottom() - CORNER_GRAB,
528                         bw,
529                         CORNER_GRAB + bw);
530                 region = QRegion(r1) + r2;
531             }
532             break;
533 
534         case BottomRight: {
535                 QRect r1(rect.right() - CORNER_GRAB,
536                         rect.bottom() + 1,
537                         CORNER_GRAB + bw,
538                         bw);
539 
540                 QRect r2(rect.right() + 1,
541                         rect.bottom() - CORNER_GRAB,
542                         bw,
543                         CORNER_GRAB + bw);
544                 region = QRegion(r1) + r2;
545             }
546             break;
547 
548         case Menu: {
549                 if (hasSysMenu) {
550                     region = QRect(rect.left(), rect.top() - titleHeight,
551                                    menu_width, titleHeight);
552                 }
553             }
554             break;
555 
556         case Help: {
557                 if (hasContextHelp) {
558                     QRect r(rect.right()
559                             - close_width
560                             - (hasMaximize ? maximize_width : 0)
561                             - (hasMinimize ? minimize_width : 0)
562                             - help_width + 1, rect.top() - titleHeight,
563                             help_width, titleHeight);
564                     if (r.left() > rect.left() + titleHeight)
565                         region = r;
566                 }
567             }
568             break;
569 
570 
571         case Minimize: {
572                 if (hasMinimize && !isMinimized) {
573                     QRect r(rect.right() - close_width
574                             - (hasMaximize ? maximize_width : 0)
575                             - minimize_width + 1, rect.top() - titleHeight,
576                             minimize_width, titleHeight);
577                     if (r.left() > rect.left() + titleHeight)
578                         region = r;
579                 }
580             }
581             break;
582 
583         case Maximize: {
584                 if (hasMaximize && !isMaximized) {
585                     QRect r(rect.right() - close_width - maximize_width + 1,
586                             rect.top() - titleHeight, maximize_width, titleHeight);
587                     if (r.left() > rect.left() + titleHeight)
588                         region = r;
589                 }
590             }
591             break;
592 
593         case Normalize: {
594                 if (hasMinimize && isMinimized) {
595                     QRect r(rect.right() - close_width
596                             - (hasMaximize ? maximize_width : 0)
597                             - minimize_width + 1, rect.top() - titleHeight,
598                             minimize_width, titleHeight);
599                     if (r.left() > rect.left() + titleHeight)
600                         region = r;
601                 } else if (hasMaximize && isMaximized) {
602                     QRect r(rect.right() - close_width - maximize_width + 1,
603                             rect.top() - titleHeight, maximize_width, titleHeight);
604                     if (r.left() > rect.left() + titleHeight)
605                         region = r;
606                 }
607             }
608             break;
609 
610         case Close: {
611                 QRect r(rect.right() - close_width + 1, rect.top() - titleHeight,
612                         close_width, titleHeight);
613                 if (r.left() > rect.left() + titleHeight)
614                     region = r;
615             }
616             break;
617 
618     default: {
619         int i = 1;
620         while (i) {
621             if (i & decorationRegion)
622                 region += this->region(widget, rect, i);
623             i <<= 1;
624         }
625     }
626             break;
627     }
628 
629     return region;
630 }
631 
632 /*!
633   Paints the border and title decoration for the top-level \a widget
634   using the \a painter provided and the decoration \a state. The value
635   of \a decorationRegion is a combination of the bitmask values of
636   enum DecorationRegion.
637 
638   Note that Qt for Embedded Linux expects this function to return true if any of
639   the widget's decorations are repainted; otherwise it returns false.
640  */
paint(QPainter * painter,const QWidget * widget,int decorationRegion,DecorationState state)641 bool QDecorationDefault::paint(QPainter *painter,
642                                const QWidget *widget,
643                                int decorationRegion,
644                                DecorationState state)
645 {
646     if (decorationRegion == None)
647         return false;
648 
649     const QRect titleRect = QDecoration::region(widget, Title).boundingRect();
650     const QPalette pal = QApplication::palette();
651     int titleHeight = titleRect.height();
652     int titleWidth = titleRect.width();
653     QRegion oldClipRegion = painter->clipRegion();
654 
655 
656     Qt::WindowFlags flags = widget->windowFlags();
657     bool hasBorder = !widget->isMaximized();
658     bool hasTitle = flags & Qt::WindowTitleHint;
659     bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
660     bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
661     bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
662     bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;
663 
664     bool paintAll = (decorationRegion == int(All));
665     bool handled = false;
666 
667     bool porterDuff = painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff);
668 
669     if ((paintAll || decorationRegion & Borders) && state == Normal && hasBorder) {
670         if (hasTitle) { // reduce flicker
671             QRect rect(widget->rect());
672             QRect r(rect.left(), rect.top() - titleHeight,
673                     rect.width(), titleHeight);
674             painter->setClipRegion(oldClipRegion - r);
675         }
676         QRect br = QDecoration::region(widget).boundingRect();
677         if (porterDuff)
678             painter->setCompositionMode(QPainter::CompositionMode_Source);
679         qDrawWinPanel(painter, br.x(), br.y(), br.width(),
680                     br.height(), pal, false,
681                     &pal.brush(QPalette::Window));
682         if (porterDuff)
683             painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
684         handled |= true;
685     }
686 
687     if ((paintAll || decorationRegion & Title && titleWidth > 0) && state == Normal && hasTitle) {
688         painter->setClipRegion(oldClipRegion);
689         QBrush titleBrush;
690         QPen   titlePen;
691 
692         if (widget == qApp->activeWindow()) {
693             titleBrush = pal.brush(QPalette::Highlight);
694             titlePen   = pal.color(QPalette::HighlightedText);
695         } else {
696             titleBrush = pal.brush(QPalette::Window);
697             titlePen   = pal.color(QPalette::Text);
698         }
699 
700         if (porterDuff)
701             painter->setCompositionMode(QPainter::CompositionMode_Source);
702         qDrawShadePanel(painter,
703                         titleRect.x(), titleRect.y(), titleRect.width(), titleRect.height(),
704                         pal, true, 1, &titleBrush);
705         if (porterDuff)
706             painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
707 
708         painter->setPen(titlePen);
709         painter->drawText(titleRect.x() + 4, titleRect.y(),
710                           titleRect.width() - 8, titleRect.height(),
711                           Qt::AlignVCenter, windowTitleFor(widget));
712         handled |= true;
713     }
714 
715     if (state != Hover) {
716         painter->setClipRegion(oldClipRegion);
717         if ((paintAll || decorationRegion & Menu) && hasSysMenu) {
718             paintButton(painter, widget, Menu, state, pal);
719             handled |= true;
720         }
721 
722         if ((paintAll || decorationRegion & Help) && hasContextHelp) {
723             paintButton(painter, widget, Help, state, pal);
724             handled |= true;
725         }
726 
727         if ((paintAll || decorationRegion & Minimize) && hasMinimize) {
728             paintButton(painter, widget, Minimize, state, pal);
729             handled |= true;
730         }
731 
732         if ((paintAll || decorationRegion & Maximize) && hasMaximize) {
733             paintButton(painter, widget,
734                         ((widget->windowState() & Qt::WindowMaximized)? Normalize : Maximize),
735                         state, pal);
736             handled |= true;
737         }
738 
739         if (paintAll || decorationRegion & Close) {
740             paintButton(painter, widget, Close, state, pal);
741             handled |= true;
742         }
743     }
744     return handled;
745 }
746 
747 /*!
748     \fn void QDecorationDefault::paintButton(QPainter *painter, const
749     QWidget *widget, int buttonRegion, DecorationState state,
750     const QPalette &palette)
751 
752     Paints a region of the top-level \a widget. The region is
753     painted in the specified decoration \a state using the
754     \a painter and \a palette provided. The region to be painted is specified
755     by \a buttonRegion, which is a combination of the bitmask values of
756     DecorationRegion. If the value of \a buttonRegion is one of \e Help,
757     \e Menu, \e Close, \e Minimize, \e Maximize, and \e Normalize, the
758     button pixmap for that region is painted.
759 
760     \sa pixmapFor()
761  */
paintButton(QPainter * painter,const QWidget * widget,int buttonRegion,DecorationState state,const QPalette & pal)762 void QDecorationDefault::paintButton(QPainter *painter,
763                                      const QWidget *widget,
764                                      int buttonRegion,
765                                      DecorationState state,
766                                      const QPalette &pal)
767 {
768     int xoff = 2;
769     int yoff = 2;
770 
771     const QPixmap pm = pixmapFor(widget, buttonRegion, xoff, yoff);
772     QRect brect(QDecoration::region(widget, buttonRegion).boundingRect());
773     bool porterDuff = painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff);
774 
775     if (state & QDecoration::Pressed) {
776         if (porterDuff)
777             painter->setCompositionMode(QPainter::CompositionMode_Source);
778         qDrawWinPanel(painter, brect, pal, true, &pal.brush(QPalette::Window));
779         if (porterDuff)
780             painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
781         ++xoff;
782         ++yoff;
783     } else {
784         painter->fillRect(brect, pal.brush(QPalette::Window));
785     }
786 
787     if (!pm.isNull())
788         painter->drawPixmap(brect.x() + xoff, brect.y() + yoff, pm);
789 }
790 
791 extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*);
792 
793 /*!
794   \internal
795  */
windowTitleFor(const QWidget * widget) const796 QString QDecorationDefault::windowTitleFor(const QWidget *widget) const
797 {
798     return qt_setWindowTitle_helperHelper(widget->windowTitle(), widget);
799 }
800 
801 #endif // QT_NO_QWS_DECORATION_DEFAULT
802 
803 QT_END_NAMESPACE
804