summaryrefslogtreecommitdiffstats
path: root/src/gui/embedded/qscreenlinuxfb_qws.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/embedded/qscreenlinuxfb_qws.cpp')
-rw-r--r--src/gui/embedded/qscreenlinuxfb_qws.cpp72
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;