Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qintegrityfbscreen.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 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// Qt-Security score:significant reason:default
4
6#include <QtFbSupport/private/qfbcursor_p.h>
7#include <QtFbSupport/private/qfbwindow_p.h>
8#include <QtCore/QRegularExpression>
9#include <QtGui/QPainter>
10
11#include <qimage.h>
12#include <qdebug.h>
13
14#include <INTEGRITY.h>
15#include <memory_region.h>
16
18
19using namespace Qt::StringLiterals;
20
21static QImage::Format determineFormat(const FBInfo *fbinfo)
22{
23 QImage::Format format = QImage::Format_Invalid;
24
25 switch (fbinfo->BitsPerPixel) {
26 case 32:
27 if (fbinfo->Alpha.Bits)
28 format = QImage::Format_ARGB32;
29 else
30 format = QImage::Format_RGB32;
31 break;
32 case 24:
33 format = QImage::Format_RGB888;
34 break;
35 case 18:
36 format = QImage::Format_RGB666;
37 break;
38 case 16:
39 format = QImage::Format_RGB16;
40 break;
41 case 15:
42 format = QImage::Format_RGB555;
43 break;
44 case 12:
45 format = QImage::Format_RGB444;
46 break;
47 case 8:
48 break;
49 case 1:
50 format = QImage::Format_Mono; //###: LSB???
51 break;
52 default:
53 break;
54 }
55
56 return format;
57}
58
59QIntegrityFbScreen::QIntegrityFbScreen(const QStringList &args)
60 : mArgs(args), mBlitter(0)
61{
62}
63
65{
66 if (mFbh) {
67 MemoryRegion vmr;
68 CheckSuccess(gh_FB_close_munmap(mFbh, &vmr));
69 CheckSuccess(DeallocateMemoryRegionWithCookie(__ghs_VirtualMemoryRegionPool,
70 vmr, mVMRCookie));
71 }
72
73 delete mBlitter;
74}
75
77{
78 Error err;
79 QRegularExpression fbRx("fb=(.*)"_L1);
80 QRegularExpression sizeRx("size=(\\d+)x(\\d+)"_L1);
81 QRegularExpression offsetRx("offset=(\\d+)x(\\d+)"_L1);
82
83 QString fbDevice;
84 QRect userGeometry;
85
86 // Parse arguments
87 foreach (const QString &arg, mArgs) {
88 QRegularExpressionMatch match;
89 if (arg.contains(sizeRx, &match))
90 userGeometry.setSize(QSize(match.captured(1).toInt(), match.captured(2).toInt()));
91 else if (arg.contains(offsetRx, &match))
92 userGeometry.setTopLeft(QPoint(match.captured(1).toInt(), match.captured(2).toInt()));
93 else if (arg.contains(fbRx, &match))
94 fbDevice = match.captured(1);
95 }
96
97 if (fbDevice.isEmpty()) {
98 /* no driver specified, try to get default one */
99 err = gh_FB_get_driver_by_name(NULL, &mFbd);
100 if (err != Success) {
101 uintptr_t context = 0;
102 /* no default driver, take the first available one */
103 err = gh_FB_get_next_driver(&context, &mFbd);
104 }
105 } else {
106 err = gh_FB_get_driver_by_name(qPrintable(fbDevice), &mFbd);
107 }
108 if (err != Success) {
109 qErrnoWarning("Failed to open framebuffer %s: %d", qPrintable(fbDevice), err);
110 return false;
111 }
112
113 memset(&mFbinfo, 0, sizeof(FBInfo));
114 CheckSuccess(gh_FB_check_info(mFbd, &mFbinfo));
115 if (userGeometry.width() && userGeometry.height()) {
116 mFbinfo.Width = userGeometry.width();
117 mFbinfo.Height = userGeometry.height();
118 err = gh_FB_check_info(mFbd, &mFbinfo);
119 if (err != Success) {
120 qErrnoWarning("Unsupported resolution %dx%d for %s: %d",
121 userGeometry.width(), userGeometry.height(),
122 qPrintable(fbDevice), err);
123 return false;
124 }
125 }
126
127 if (mFbinfo.MMapSize) {
128 err = AllocateAnyMemoryRegionWithCookie(__ghs_VirtualMemoryRegionPool,
129 mFbinfo.MMapSize, &mVMR, &mVMRCookie);
130 if (err != Success) {
131 qErrnoWarning("Could not mmap: %d", err);
132 return false;
133 }
134
135 err = gh_FB_open_mmap(mFbd, &mFbinfo, mVMR, &mFbh);
136 } else {
137 err = gh_FB_open(mFbd, &mFbinfo, &mFbh);
138 }
139 if (err != Success) {
140 qErrnoWarning("Could not open framebuffer: %d", err);
141 return false;
142 }
143
144 CheckSuccess(gh_FB_get_info(mFbh, &mFbinfo));
145
146 mDepth = mFbinfo.BitsPerPixel;
147 mGeometry = QRect(0, 0, mFbinfo.Width, mFbinfo.Height);
148 mFormat = determineFormat(&mFbinfo);
149
150 const int dpi = 100;
151 int mmWidth = qRound((mFbinfo.Width * 25.4) / dpi);
152 int mmHeight = qRound((mFbinfo.Height * 25.4) / dpi);
153 mPhysicalSize = QSizeF(mmWidth, mmHeight);
154
155 QFbScreen::initializeCompositor();
156 mFbScreenImage = QImage((uchar *)mFbinfo.Start, mFbinfo.Width, mFbinfo.Height,
157 mFbinfo.BytesPerLine, mFormat);
158
159 mCursor = new QFbCursor(this);
160
161 return true;
162}
163
165{
166 QRegion touched = QFbScreen::doRedraw();
167
168 if (touched.isEmpty())
169 return touched;
170
171 if (!mBlitter)
172 mBlitter = new QPainter(&mFbScreenImage);
173
174 for (QRect rect : touched) {
175 FBRect fbrect = {
176 (uint32_t)rect.left(),
177 (uint32_t)rect.top(),
178 (uint32_t)rect.width(),
179 (uint32_t)rect.height()
180 };
181 mBlitter->drawImage(rect, mScreenImage, rect);
182 gh_FB_expose(mFbh, &fbrect, NULL);
183 }
184 return touched;
185}
186
187// grabWindow() grabs "from the screen" not from the backingstores.
188// In integrityfb's case it will also include the mouse cursor.
189QPixmap QIntegrityFbScreen::grabWindow(WId wid, int x, int y, int width, int height) const
190{
191 if (!wid) {
192 if (width < 0)
193 width = mFbScreenImage.width() - x;
194 if (height < 0)
195 height = mFbScreenImage.height() - y;
196 return QPixmap::fromImage(mFbScreenImage).copy(x, y, width, height);
197 }
198
199 QFbWindow *window = windowForId(wid);
200 if (window) {
201 const QRect geom = window->geometry();
202 if (width < 0)
203 width = geom.width() - x;
204 if (height < 0)
205 height = geom.height() - y;
206 QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height));
207 rect &= window->geometry();
208 return QPixmap::fromImage(mFbScreenImage).copy(rect);
209 }
210
211 return QPixmap();
212}
213
214QT_END_NAMESPACE
QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override
This function is called when Qt needs to be able to grab the content of a window.
QRegion doRedraw() override
Combined button and popup list for selecting options.
static QImage::Format determineFormat(const FBInfo *fbinfo)