diff options
Diffstat (limited to 'src/gui/embedded/qscreenlinuxfb_qws.cpp')
-rw-r--r-- | src/gui/embedded/qscreenlinuxfb_qws.cpp | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/src/gui/embedded/qscreenlinuxfb_qws.cpp b/src/gui/embedded/qscreenlinuxfb_qws.cpp index 8a21022..1effcfa 100644 --- a/src/gui/embedded/qscreenlinuxfb_qws.cpp +++ b/src/gui/embedded/qscreenlinuxfb_qws.cpp @@ -91,6 +91,7 @@ public: int startuph; int startupd; bool blank; + QLinuxFbScreen::DriverTypes driverType; bool doGraphicsMode; #ifdef QT_QWS_DEPTH_GENERIC @@ -165,6 +166,36 @@ void QLinuxFbScreenPrivate::closeTty() } /*! + \enum QLinuxFbScreen::DriverTypes + + This enum describes the driver type. + + \value GenericDriver Generic Linux framebuffer driver + \value EInk8Track e-Ink framebuffer driver using the 8Track chipset + */ + +/*! + \fn QLinuxFbScreen::fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo) + + Adjust the values returned by the framebuffer driver, to work + around driver bugs or nonstandard behavior in certain drivers. + \a finfo and \a vinfo specify the fixed and variable screen info + returned by the driver. + */ +void QLinuxFbScreen::fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo) +{ + // 8Track e-ink devices (as found in Sony PRS-505) lie + // about their bit depth -- they claim they're 1 bit per + // pixel while the only supported mode is 8 bit per pixel + // grayscale. + // Caused by this, they also miscalculate their line length. + if(!strcmp(finfo.id, "8TRACKFB") && vinfo.bits_per_pixel == 1) { + vinfo.bits_per_pixel = 8; + finfo.line_length = vinfo.xres; + } +} + +/*! \internal \class QLinuxFbScreen @@ -306,6 +337,8 @@ bool QLinuxFbScreen::connect(const QString &displaySpec) return false; } + d_ptr->driverType = strcmp(finfo.id, "8TRACKFB") ? GenericDriver : EInk8Track; + if (finfo.type == FB_TYPE_VGA_PLANES) { qWarning("VGA16 video mode not supported"); return false; @@ -318,6 +351,8 @@ bool QLinuxFbScreen::connect(const QString &displaySpec) return false; } + fixupScreenInfo(finfo, vinfo); + grayscale = vinfo.grayscale; d = vinfo.bits_per_pixel; if (d == 24) { @@ -664,11 +699,6 @@ bool QLinuxFbScreen::initDevice() vinfo.transp.msb_right); #endif - d_ptr->startupw=vinfo.xres; - d_ptr->startuph=vinfo.yres; - d_ptr->startupd=vinfo.bits_per_pixel; - grayscale = vinfo.grayscale; - if (ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) { perror("QLinuxFbScreen::initDevice"); qCritical("Error reading fixed information in card init"); @@ -677,6 +707,13 @@ bool QLinuxFbScreen::initDevice() return true; } + fixupScreenInfo(finfo, vinfo); + + d_ptr->startupw=vinfo.xres; + d_ptr->startuph=vinfo.yres; + d_ptr->startupd=vinfo.bits_per_pixel; + grayscale = vinfo.grayscale; + #ifdef __i386__ // Now init mtrr if(!::getenv("QWS_NOMTRR")) { @@ -1122,6 +1159,7 @@ void QLinuxFbScreen::setMode(int nw,int nh,int nd) qFatal("Error reading fixed information"); } + fixupScreenInfo(finfo, vinfo); disconnect(); connect(d_ptr->displaySpec); exposeRegion(region(), 0); @@ -1200,6 +1238,26 @@ int QLinuxFbScreen::sharedRamSize(void * end) /*! \reimp */ +void QLinuxFbScreen::setDirty(const QRect &r) +{ + if(d_ptr->driverType == EInk8Track) { + // e-Ink displays need a trigger to actually show what is + // in their framebuffer memory. The 8-Track driver does this + // by adding custom IOCTLs - FBIO_EINK_DISP_PIC (0x46a2) takes + // an argument specifying whether or not to flash the screen + // while updating. + // There doesn't seem to be a way to tell it to just update + // a subset of the screen. + if(r.left() == 0 && r.top() == 0 && r.width() == dw && r.height() == dh) + ioctl(d_ptr->fd, 0x46a2, 1); + else + ioctl(d_ptr->fd, 0x46a2, 0); + } +} + +/*! + \reimp +*/ void QLinuxFbScreen::blank(bool on) { if (d_ptr->blank == on) @@ -1315,7 +1373,9 @@ void QLinuxFbScreen::setPixelFormat(struct fb_var_screeninfo info) bool QLinuxFbScreen::useOffscreen() { - if ((mapsize - size) < 16*1024) + // Not done for 8Track because on e-Ink displays, + // everything is offscreen anyway + if (d_ptr->driverType == EInk8Track || ((mapsize - size) < 16*1024)) return false; return true; |