59 if (userGeometry.isValid()) {
60 w = qMin(userGeometry.width(), fb.fb_width);
61 h = qMin(userGeometry.height(), fb.fb_height);
63 int xxoff = userGeometry.x(), yyoff = userGeometry.y();
64 if (xxoff != 0 || yyoff != 0) {
65 if (xxoff < 0 || xxoff + w > fb.fb_width)
66 xxoff = fb.fb_width - w;
67 if (yyoff < 0 || yyoff + h > fb.fb_height)
68 yyoff = fb.fb_height - h;
72 xoff += (fb.fb_width - w)/2;
73 yoff += (fb.fb_height - h)/2;
80 if (w == 0 || h == 0) {
81 qWarning(
"Unable to find screen geometry, using 320x240");
86 return QRect(xoff, yoff, w, h);
91 int mmWidth = mmSize.width();
92 int mmHeight = mmSize.height();
94 if (mmWidth <= 0 && mmHeight <= 0) {
96 mmWidth = qRound(res.width() * 25.4 / dpi);
97 mmHeight = qRound(res.height() * 25.4 / dpi);
98 }
else if (mmWidth > 0 && mmHeight <= 0) {
99 mmHeight = res.height() * mmWidth/res.width();
100 }
else if (mmHeight > 0 && mmWidth <= 0) {
101 mmWidth = res.width() * mmHeight/res.height();
104 return QSize(mmWidth, mmHeight);
122 QRegularExpression fbRx(
"fb=(.*)"_L1);
123 QRegularExpression mmSizeRx(
"mmsize=(\\d+)x(\\d+)"_L1);
124 QRegularExpression sizeRx(
"size=(\\d+)x(\\d+)"_L1);
125 QRegularExpression offsetRx(
"offset=(\\d+)x(\\d+)"_L1);
132 for (
const QString &arg : std::as_const(m_arguments)) {
133 QRegularExpressionMatch match;
134 if (arg.contains(mmSizeRx, &match))
135 userMmSize = QSize(match.captured(1).toInt(), match.captured(2).toInt());
136 else if (arg.contains(sizeRx, &match))
137 userGeometry.setSize(QSize(match.captured(1).toInt(), match.captured(2).toInt()));
138 else if (arg.contains(offsetRx, &match))
139 userGeometry.setTopLeft(QPoint(match.captured(1).toInt(), match.captured(2).toInt()));
140 else if (arg.contains(fbRx, &match))
141 fbDevice = match.captured(1);
144 if (!fbDevice.isEmpty()) {
146 m_framebufferFd = openFramebufferDevice(fbDevice);
148 m_framebufferFd = STDIN_FILENO;
151 if (m_framebufferFd == -1) {
152 qErrnoWarning(errno,
"Failed to open framebuffer %s", qPrintable(fbDevice));
157 if (ioctl(m_framebufferFd, FBIOGTYPE, &fb) != 0) {
158 qErrnoWarning(errno,
"Error reading framebuffer information");
163 if (ioctl(m_framebufferFd, FBIO_GETLINEWIDTH, &line_length) != 0) {
164 qErrnoWarning(errno,
"Error reading line length information");
168 mDepth = fb.fb_depth;
170 m_bytesPerLine = line_length;
171 const QRect geometry = determineGeometry(fb, userGeometry);
172 mGeometry = QRect(QPoint(0, 0), geometry.size());
175 mFormat = QImage::Format_RGB32;
178 mFormat = QImage::Format_RGB888;
183 mFormat = QImage::Format_RGB16;
186 mPhysicalSize = determinePhysicalSize(userMmSize, geometry.size());
189 const size_t pagemask = getpagesize() - 1;
190 m_mmap.size = (m_bytesPerLine * fb.fb_height + pagemask) & ~pagemask;
191 uchar *data =
static_cast<uchar*>(mmap(
nullptr, m_mmap.size, PROT_READ | PROT_WRITE, MAP_SHARED, m_framebufferFd, 0));
193 qErrnoWarning(errno,
"Failed to mmap framebuffer");
197 m_mmap.offset = geometry.y() * m_bytesPerLine + geometry.x() * mDepth / 8;
198 m_mmap.data = data + m_mmap.offset;
200 QFbScreen::initializeCompositor();
201 m_onscreenImage = QImage(m_mmap.data, geometry.width(), geometry.height(), m_bytesPerLine, mFormat);
203 mCursor =
new QFbCursor(
this);
228 width = m_onscreenImage.width() - x;
230 height = m_onscreenImage.height() - y;
231 return QPixmap::fromImage(m_onscreenImage).copy(x, y, width, height);
234 const QFbWindow *window = windowForId(wid);
236 const QRect geom = window->geometry();
238 width = geom.width() - x;
240 height = geom.height() - y;
241 QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height));
242 rect &= window->geometry();
243 return QPixmap::fromImage(m_onscreenImage).copy(rect);
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.