1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qvncscreen.h"
41#include "qvnc_p.h"
42#include <QtFbSupport/private/qfbwindow_p.h>
43#include <QtFbSupport/private/qfbcursor_p.h>
44
45#include <QtGui/QPainter>
46#include <QtGui/QScreen>
47#include <QtCore/QRegularExpression>
48
49
50QT_BEGIN_NAMESPACE
51
52
53QVncScreen::QVncScreen(const QStringList &args)
54 : mArgs(args)
55{
56 initialize();
57}
58
59QVncScreen::~QVncScreen()
60{
61#if QT_CONFIG(cursor)
62 if (clientCursor)
63 delete clientCursor;
64#endif
65}
66
67bool QVncScreen::initialize()
68{
69 QRegularExpression sizeRx(QLatin1String("size=(\\d+)x(\\d+)"));
70 QRegularExpression mmSizeRx(QLatin1String("mmsize=(?<width>(\\d*\\.)?\\d+)x(?<height>(\\d*\\.)?\\d+)"));
71 QRegularExpression depthRx(QLatin1String("depth=(\\d+)"));
72
73 mGeometry = QRect(0, 0, 1024, 768);
74 mFormat = QImage::Format_ARGB32_Premultiplied;
75 mDepth = 32;
76 mPhysicalSize = QSizeF(mGeometry.width()/96.*25.4, mGeometry.height()/96.*25.4);
77
78 for (const QString &arg : qAsConst(t&: mArgs)) {
79 QRegularExpressionMatch match;
80 if (arg.contains(re: mmSizeRx, rmatch: &match)) {
81 mPhysicalSize = QSizeF(match.captured(name: "width").toDouble(), match.captured(name: "height").toDouble());
82 } else if (arg.contains(re: sizeRx, rmatch: &match)) {
83 mGeometry.setSize(QSize(match.captured(nth: 1).toInt(), match.captured(nth: 2).toInt()));
84 } else if (arg.contains(re: depthRx, rmatch: &match)) {
85 mDepth = match.captured(nth: 1).toInt();
86 }
87 }
88
89 switch (depth()) {
90 case 32:
91 dirty = new QVncDirtyMapOptimized<quint32>(this);
92 break;
93 case 16:
94 dirty = new QVncDirtyMapOptimized<quint16>(this);
95 mFormat = QImage::Format_RGB16;
96 break;
97 case 8:
98 dirty = new QVncDirtyMapOptimized<quint8>(this);
99 break;
100 default:
101 qWarning(msg: "QVNCScreen::initDevice: No support for screen depth %d",
102 depth());
103 dirty = nullptr;
104 return false;
105 }
106
107 QFbScreen::initializeCompositor();
108
109 setPowerState(PowerStateOff);
110
111 return true;
112}
113
114QRegion QVncScreen::doRedraw()
115{
116 QRegion touched = QFbScreen::doRedraw();
117
118 if (touched.isEmpty())
119 return touched;
120 dirtyRegion += touched;
121
122 vncServer->setDirty();
123 return touched;
124}
125
126
127void QVncScreen::enableClientCursor(QVncClient *client)
128{
129#if QT_CONFIG(cursor)
130 delete mCursor;
131 mCursor = nullptr;
132 if (!clientCursor)
133 clientCursor = new QVncClientCursor();
134 clientCursor->addClient(client);
135#else
136 Q_UNUSED(client)
137#endif
138}
139
140void QVncScreen::disableClientCursor(QVncClient *client)
141{
142#if QT_CONFIG(cursor)
143 if (!clientCursor)
144 return;
145
146 uint clientCount = clientCursor->removeClient(client);
147 if (clientCount == 0) {
148 delete clientCursor;
149 clientCursor = nullptr;
150 }
151
152 mCursor = new QFbCursor(this);
153#else
154 Q_UNUSED(client)
155#endif
156}
157
158QPlatformCursor *QVncScreen::cursor() const
159{
160#if QT_CONFIG(cursor)
161 return mCursor ? static_cast<QPlatformCursor *>(mCursor) : static_cast<QPlatformCursor *>(clientCursor);
162#else
163 return nullptr;
164#endif
165}
166
167// grabWindow() grabs "from the screen" not from the backingstores.
168// In linuxfb's case it will also include the mouse cursor.
169QPixmap QVncScreen::grabWindow(WId wid, int x, int y, int width, int height) const
170{
171 if (!wid) {
172 if (width < 0)
173 width = mScreenImage.width() - x;
174 if (height < 0)
175 height = mScreenImage.height() - y;
176 return QPixmap::fromImage(image: mScreenImage).copy(ax: x, ay: y, awidth: width, aheight: height);
177 }
178
179 QFbWindow *window = windowForId(wid);
180 if (window) {
181 const QRect geom = window->geometry();
182 if (width < 0)
183 width = geom.width() - x;
184 if (height < 0)
185 height = geom.height() - y;
186 QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height));
187 rect &= window->geometry();
188 return QPixmap::fromImage(image: mScreenImage).copy(rect);
189 }
190
191 return QPixmap();
192}
193
194#if Q_BYTE_ORDER == Q_BIG_ENDIAN
195bool QVncScreen::swapBytes() const
196{
197 return false;
198
199 /* TODO
200 if (depth() != 16)
201 return false;
202
203 if (screen())
204 return screen()->frameBufferLittleEndian();
205 return frameBufferLittleEndian();
206 */
207}
208#endif
209
210QFbScreen::Flags QVncScreen::flags() const
211{
212 return QFbScreen::DontForceFirstWindowToFullScreen;
213}
214
215QT_END_NAMESPACE
216
217

source code of qtbase/src/plugins/platforms/vnc/qvncscreen.cpp