1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qfbwindow_p.h"
5#include "qfbscreen_p.h"
6
7#include <QtGui/QScreen>
8#include <qpa/qwindowsysteminterface.h>
9
10QT_BEGIN_NAMESPACE
11
12Q_CONSTINIT static QBasicAtomicInt winIdGenerator = Q_BASIC_ATOMIC_INITIALIZER(0);
13
14QFbWindow::QFbWindow(QWindow *window)
15 : QPlatformWindow(window), mBackingStore(0), mWindowState(Qt::WindowNoState)
16{
17 mWindowId = winIdGenerator.fetchAndAddRelaxed(valueToAdd: 1) + 1;
18}
19
20QFbWindow::~QFbWindow()
21{
22}
23
24QFbScreen *QFbWindow::platformScreen() const
25{
26 return static_cast<QFbScreen *>(window()->screen()->handle());
27}
28
29void QFbWindow::setGeometry(const QRect &rect)
30{
31 // store previous geometry for screen update
32 mOldGeometry = geometry();
33
34 QWindowSystemInterface::handleGeometryChange(window: window(), newRect: rect);
35
36 QPlatformWindow::setGeometry(rect);
37
38 if (mOldGeometry != rect)
39 QWindowSystemInterface::handleExposeEvent(window: window(), region: QRect(QPoint(0, 0), geometry().size()));
40}
41
42void QFbWindow::setVisible(bool visible)
43{
44 QRect newGeom;
45 QFbScreen *fbScreen = platformScreen();
46 if (visible) {
47 bool convOk = false;
48 static bool envDisableForceFullScreen = qEnvironmentVariableIntValue(varName: "QT_QPA_FB_FORCE_FULLSCREEN", ok: &convOk) == 0 && convOk;
49 const bool platformDisableForceFullScreen = fbScreen->flags().testFlag(flag: QFbScreen::DontForceFirstWindowToFullScreen);
50 const bool forceFullScreen = !envDisableForceFullScreen && !platformDisableForceFullScreen && fbScreen->windowCount() == 0;
51 if (forceFullScreen || (mWindowState & Qt::WindowFullScreen))
52 newGeom = platformScreen()->geometry();
53 else if (mWindowState & Qt::WindowMaximized)
54 newGeom = platformScreen()->availableGeometry();
55 }
56 QPlatformWindow::setVisible(visible);
57
58 if (visible)
59 fbScreen->addWindow(window: this);
60 else
61 fbScreen->removeWindow(window: this);
62
63 if (!newGeom.isEmpty())
64 setGeometry(newGeom); // may or may not generate an expose
65
66 if (newGeom.isEmpty() || newGeom == mOldGeometry) {
67 // QWindow::isExposed() maps to QWindow::visible() by default so simply
68 // generating an expose event regardless of this being a show or hide is
69 // just what is needed here.
70 QWindowSystemInterface::handleExposeEvent(window: window(), region: QRect(QPoint(0, 0), geometry().size()));
71 }
72}
73
74void QFbWindow::setWindowState(Qt::WindowStates state)
75{
76 QPlatformWindow::setWindowState(state);
77 mWindowState = state;
78}
79
80void QFbWindow::setWindowFlags(Qt::WindowFlags flags)
81{
82 mWindowFlags = flags;
83}
84
85Qt::WindowFlags QFbWindow::windowFlags() const
86{
87 return mWindowFlags;
88}
89
90void QFbWindow::raise()
91{
92 platformScreen()->raise(window: this);
93 QWindowSystemInterface::handleExposeEvent(window: window(), region: QRect(QPoint(0, 0), geometry().size()));
94}
95
96void QFbWindow::lower()
97{
98 platformScreen()->lower(window: this);
99 QWindowSystemInterface::handleExposeEvent(window: window(), region: QRect(QPoint(0, 0), geometry().size()));
100}
101
102void QFbWindow::repaint(const QRegion &region)
103{
104 const QRect currentGeometry = geometry();
105 const QRect oldGeometryLocal = mOldGeometry;
106 mOldGeometry = currentGeometry;
107 // If this is a move, redraw the previous location
108 if (oldGeometryLocal != currentGeometry)
109 platformScreen()->setDirty(oldGeometryLocal);
110 auto topLeft = currentGeometry.topLeft();
111 for (auto rect : region)
112 platformScreen()->setDirty(rect.translated(p: topLeft));
113}
114
115QT_END_NAMESPACE
116

source code of qtbase/src/platformsupport/fbconvenience/qfbwindow.cpp