Bug#338241: Wrong colours with the fbdev driver on framebuffer devices with unusual RGB ordering
Package: xserver-xorg
Version: 6.8.2.dfsg.1-7
Severity: important
Tags: patch
When setting a video mode, the framebuffer driver chooses also an order
of the RGB bits inside the pixel data and a number of bits per pixel
for truecolour video modi (15, 16 and 24 bpp). But these values can not
be chosen, they depend on the present hardware. If the hardware differs
from the framebuffers choice, wrong colours are the result, or even
total rubbish if it is a wrong number of bits per pixel. Both problems
happen for instance on some ARM-based machines, so that only 8bpp modi
have been usable up to now.
So, the framebuffer driver should fixup these values after setting the
video mode of the framebuffer device. A patch is include below. On my
ARM hardware (Castle Iyonix, Acorn RiscPC) it works fine.
Peter Teichmann
diff -urd xc.orig/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c
--- xc.orig/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c 2005-10-25 23:02:07.000000000 +0200
+++ xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c 2005-10-25 22:35:49.000000000 +0200
@@ -693,6 +693,26 @@
"FBIOGET_VSCREENINFO: %s\n", strerror(errno));
return FALSE;
}
+
+ /* fixup desired values that can not be chosen
+ but depend on the given framebuffer device */
+ pScrn->offset.red = fPtr->var.red.offset;
+ pScrn->offset.green = fPtr->var.green.offset;
+ pScrn->offset.blue = fPtr->var.blue.offset;
+ pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset;
+ pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset;
+ pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset;
+ pScrn->bitsPerPixel = fPtr->var.bits_per_pixel;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Setting screen mode:\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ " Resolution: %dx%d, Depth %d, BPP %d\n",
+ fPtr->var.xres, fPtr->var.yres, pScrn->depth, pScrn->bitsPerPixel);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ " RGB masks: %08x %08x %08x\n",
+ pScrn->mask.red, pScrn->mask.green, pScrn->mask.blue);
+
return TRUE;
}
Reply to: