diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 72d5833..5654e5f 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -69,6 +69,11 @@ QT_BEGIN_NAMESPACE +typedef struct { + QImage::Format format; + bool swapRgb; +} FbFormat; + static int openFramebufferDevice(const QString &dev) { int fd = -1; @@ -161,12 +166,14 @@ static QSizeF determinePhysicalSize(const fb_var_screeninfo &vinfo, const QSize return QSize(mmWidth, mmHeight); } -static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth) +static FbFormat determineFormat(const fb_var_screeninfo &info, int depth) { const fb_bitfield rgba[4] = { info.red, info.green, info.blue, info.transp }; - QImage::Format format = QImage::Format_Invalid; + FbFormat fbFormat; + fbFormat.format = QImage::Format_Invalid; + fbFormat.swapRgb = false; switch (depth) { case 32: { @@ -175,11 +182,12 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth) const fb_bitfield abgr8888[4] = {{0, 8, 0}, {8, 8, 0}, {16, 8, 0}, {24, 8, 0}}; if (memcmp(rgba, argb8888, 4 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_ARGB32; + fbFormat.format = QImage::Format_ARGB32; } else if (memcmp(rgba, argb8888, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB32; + fbFormat.format = QImage::Format_RGB32; } else if (memcmp(rgba, abgr8888, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB32; + fbFormat.format = QImage::Format_RGB32; + fbFormat.swapRgb = true; // pixeltype = BGRPixel; } break; @@ -190,9 +198,10 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth) const fb_bitfield bgr888[4] = {{0, 8, 0}, {8, 8, 0}, {16, 8, 0}, {0, 0, 0}}; if (memcmp(rgba, rgb888, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB888; + fbFormat.format = QImage::Format_RGB888; } else if (memcmp(rgba, bgr888, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB888; + fbFormat.format = QImage::Format_RGB888; + fbFormat.swapRgb = true; // pixeltype = BGRPixel; } break; @@ -201,7 +210,7 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth) const fb_bitfield rgb666[4] = {{12, 6, 0}, {6, 6, 0}, {0, 6, 0}, {0, 0, 0}}; if (memcmp(rgba, rgb666, 3 * sizeof(fb_bitfield)) == 0) - format = QImage::Format_RGB666; + fbFormat.format = QImage::Format_RGB666; break; } case 16: { @@ -210,9 +219,10 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth) const fb_bitfield bgr565[4] = {{0, 5, 0}, {5, 6, 0}, {11, 5, 0}, {0, 0, 0}}; if (memcmp(rgba, rgb565, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB16; + fbFormat.format = QImage::Format_RGB16; } else if (memcmp(rgba, bgr565, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB16; + fbFormat.format = QImage::Format_RGB16; + fbFormat.swapRgb = true; // pixeltype = BGRPixel; } break; @@ -223,9 +233,10 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth) const fb_bitfield bgr1555[4] = {{0, 5, 0}, {5, 5, 0}, {10, 5, 0}, {15, 1, 0}}; if (memcmp(rgba, rgb1555, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB555; + fbFormat.format = QImage::Format_RGB555; } else if (memcmp(rgba, bgr1555, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB555; + fbFormat.format = QImage::Format_RGB555; + fbFormat.swapRgb = true; // pixeltype = BGRPixel; } break; @@ -234,19 +245,19 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth) const fb_bitfield rgb444[4] = {{8, 4, 0}, {4, 4, 0}, {0, 4, 0}, {0, 0, 0}}; if (memcmp(rgba, rgb444, 3 * sizeof(fb_bitfield)) == 0) - format = QImage::Format_RGB444; + fbFormat.format = QImage::Format_RGB444; break; } case 8: break; case 1: - format = QImage::Format_Mono; //###: LSB??? + fbFormat.format = QImage::Format_Mono; //###: LSB??? break; default: break; } - return format; + return fbFormat; } static int openTtyDevice(const QString &device) @@ -298,7 +309,7 @@ static void blankScreen(int fd, bool on) } QLinuxFbScreen::QLinuxFbScreen(const QStringList &args) - : mArgs(args), mFbFd(-1), mBlitter(0) + : mArgs(args), mFbFd(-1), mBlitter(0), mSwapRgb(false) { } @@ -384,7 +395,9 @@ bool QLinuxFbScreen::initialize() mBytesPerLine = finfo.line_length; QRect geometry = determineGeometry(vinfo, userGeometry); mGeometry = QRect(QPoint(0, 0), geometry.size()); - mFormat = determineFormat(vinfo, mDepth); + FbFormat fbFormat = determineFormat(vinfo, mDepth); + mFormat = fbFormat.format; + mSwapRgb = fbFormat.swapRgb; mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, geometry.size()); // mmap the framebuffer @@ -443,8 +456,15 @@ QRegion QLinuxFbScreen::doRedraw() mBlitter = new QPainter(&mFbScreenImage); QVector rects = touched.rects(); - for (int i = 0; i < rects.size(); i++) - mBlitter->drawImage(rects[i], *mScreenImage, rects[i]); + for (int i = 0; i < rects.size(); i++) { + if (mSwapRgb) { + mBlitter->drawImage(rects[i], mScreenImage->rgbSwapped(), rects[i]); + } + else { + mBlitter->drawImage(rects[i], *mScreenImage, rects[i]); + } + + } return touched; } diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h index 32cd263..3a149a5 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h @@ -76,6 +76,7 @@ private: } mMmap; QPainter *mBlitter; + bool mSwapRgb; }; QT_END_NAMESPACE