xserver: Branch 'server-1.3-branch' - 6 commits

Keith Packard keithp at kemper.freedesktop.org
Tue Mar 27 06:35:56 EEST 2007


 hw/xfree86/fbdevhw/fbdevhw.c |  160 +++++++++++++++++++++++++++++--------------
 1 files changed, 109 insertions(+), 51 deletions(-)

New commits:
diff-tree 96636598ee8a024b2fc93e2779b581446fa22d83 (from 7679b2c6139ee7345b4f65ab84384162bbd796ae)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Fri Jan 19 18:30:21 2007 +0100

    fbdevhw: Only deal with RGB weight if default visual is True- or DirectColor.
    (cherry picked from commit 14d6a9b327381a6bb2dac59c62728e5fd0f0bcfb)

diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 8b163be..a573b8f 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -187,9 +187,16 @@ xfree2fbdev_fblayout(ScrnInfoPtr pScrn, 
 			      pScrn->virtualX;
 	var->yres_virtual   = pScrn->virtualY;
 	var->bits_per_pixel = pScrn->bitsPerPixel;
-	var->red.length     = pScrn->weight.red;
-	var->green.length   = pScrn->weight.green;
-	var->blue.length    = pScrn->weight.blue;
+	if (pScrn->defaultVisual == TrueColor ||
+	    pScrn->defaultVisual == DirectColor) {
+	    var->red.length     = pScrn->weight.red;
+	    var->green.length   = pScrn->weight.green;
+	    var->blue.length    = pScrn->weight.blue;
+	} else {
+	    var->red.length     = 8;
+	    var->green.length   = 8;
+	    var->blue.length    = 8;
+	}
 }
 
 static void
@@ -746,15 +753,18 @@ fbdevHWModeInit(ScrnInfoPtr pScrn, Displ
 		return FALSE;
 	}
 
-	/* XXX: This is a hack, but it should be a NOP for all the setups that
-	 * worked before and actually seems to fix some others...
-	 */
-	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;
+	if (pScrn->defaultVisual == TrueColor ||
+	    pScrn->defaultVisual == DirectColor) {
+	    /* XXX: This is a hack, but it should be a NOP for all the setups that
+	     * worked before and actually seems to fix some others...
+	     */
+	    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;
+	}
 
 	return TRUE;
 }
diff-tree 7679b2c6139ee7345b4f65ab84384162bbd796ae (from 1c2793d3ec4c82c7205abb10a1f4d093864425ea)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Fri Jan 19 18:28:05 2007 +0100

    fbdevhw: Consider mode set equal to mode requested if virtual width is larger.
    (cherry picked from commit 27a01e100bff21ac0b70c6d72071d7226fc91264)

diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 8f78b85..8b163be 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -229,23 +229,23 @@ xfree2fbdev_timing(DisplayModePtr mode, 
 }
 
 static Bool
-fbdev_modes_equal(struct fb_var_screeninfo *one, struct fb_var_screeninfo *two)
+fbdev_modes_equal(struct fb_var_screeninfo *set, struct fb_var_screeninfo *req)
 {
-	return (one->xres_virtual == two->xres_virtual &&
-		one->yres_virtual == two->yres_virtual &&
-		one->bits_per_pixel == two->bits_per_pixel &&
-		one->red.length == two->red.length &&
-		one->green.length == two->green.length &&
-		one->blue.length == two->blue.length &&
-		one->xres == two->xres && one->yres == two->yres &&
-		one->pixclock == two->pixclock &&
-		one->right_margin == two->right_margin &&
-		one->hsync_len == two->hsync_len &&
-		one->left_margin == two->left_margin &&
-		one->lower_margin == two->lower_margin &&
-		one->vsync_len == two->vsync_len &&
-		one->upper_margin == two->upper_margin &&
-		one->sync == two->sync && one->vmode == two->vmode);
+	return (set->xres_virtual >= req->xres_virtual &&
+		set->yres_virtual == req->yres_virtual &&
+		set->bits_per_pixel == req->bits_per_pixel &&
+		set->red.length == req->red.length &&
+		set->green.length == req->green.length &&
+		set->blue.length == req->blue.length &&
+		set->xres == req->xres && set->yres == req->yres &&
+		set->pixclock == req->pixclock &&
+		set->right_margin == req->right_margin &&
+		set->hsync_len == req->hsync_len &&
+		set->left_margin == req->left_margin &&
+		set->lower_margin == req->lower_margin &&
+		set->vsync_len == req->vsync_len &&
+		set->upper_margin == req->upper_margin &&
+		set->sync == req->sync && set->vmode == req->vmode);
 }
 
 static void
diff-tree 1c2793d3ec4c82c7205abb10a1f4d093864425ea (from d7bcad9c694a13c702e429d8364035850d8f8bb7)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Dec 31 17:59:44 2006 +0100

    fbdevhw: Override RGB offsets and masks after setting initial mode.
    
    This is a hack, but it should be a NOP for all the setups that worked before
    and actually seems to fix some others...
    
    Based on a patch by Peter Teichmann from
    http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=338241 .
    (cherry picked from commit dc5eb4523298f966bd5fd9ae6672160034b5e82c)

diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index a9288a7..8f78b85 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -745,6 +745,17 @@ fbdevHWModeInit(ScrnInfoPtr pScrn, Displ
 			   "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
 		return FALSE;
 	}
+
+	/* XXX: This is a hack, but it should be a NOP for all the setups that
+	 * worked before and actually seems to fix some others...
+	 */
+	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;
+
 	return TRUE;
 }
 
diff-tree d7bcad9c694a13c702e429d8364035850d8f8bb7 (from 28af734cb7f2e5e40f6524411f77eba0e3960a8d)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Dec 31 17:23:31 2006 +0100

    fbdevhw: Use displayWidth for fbdev virtual width when appropriate.
    
    The fbdev API doesn't allow setting the pitch explicitly, so we have to set
    the virtual width to the pitch we're using for drawing. This fixes corruption
    after changing the virtual width with RandR.
    (cherry picked from commit d077c0da470ab7291e8d838eaace57b066477d6f)

diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 83b0dc1..a9288a7 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -183,7 +183,8 @@ print_xfree_mode(char *txt, DisplayModeP
 static void
 xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
 {
-	var->xres_virtual   = pScrn->virtualX;
+	var->xres_virtual   = pScrn->displayWidth ? pScrn->displayWidth :
+			      pScrn->virtualX;
 	var->yres_virtual   = pScrn->virtualY;
 	var->bits_per_pixel = pScrn->bitsPerPixel;
 	var->red.length     = pScrn->weight.red;
diff-tree 28af734cb7f2e5e40f6524411f77eba0e3960a8d (from c0459d7476f408806b1e7202b960ee0b3911774a)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sat Dec 30 16:44:31 2006 +0100

    fbdevhw: Fix some issues with the previous commit.
    
    Fix a TRACE_ENTER typo and only update the internal fbdev mode state cache
    after actually setting a mode.
    (cherry picked from commit c385bcf0bde38dd869f7065f859dd4b4126f5690)

diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 303ad14..83b0dc1 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -496,7 +496,7 @@ fbdevHWSetMode(ScrnInfoPtr pScrn, Displa
 	fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
 	struct fb_var_screeninfo req_var = fPtr->var, set_var;
 	
-	TRACE_ENTER("ModeInit");
+	TRACE_ENTER("SetMode");
 
 	xfree2fbdev_fblayout(pScrn, &req_var);
 	xfree2fbdev_timing(mode, &req_var);
@@ -528,7 +528,8 @@ fbdevHWSetMode(ScrnInfoPtr pScrn, Displa
 		return FALSE;
 	}
 
-	fPtr->var = set_var;
+	if (!check)
+		fPtr->var = set_var;
 
 	return TRUE;
 }
diff-tree c0459d7476f408806b1e7202b960ee0b3911774a (from 57e87e0d006cbf1f5b175fe02eeb981f741d92f0)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sat Dec 30 10:18:28 2006 +0100

    fbdevhw: Consolidate modeset ioctl calling, report failure if it modifies mode.
    
    The fbdev API allows the driver to 'accept' modes it doesn't really support by
    modifying it to the nearest supported mode. Without this check, e.g. vesafb
    would appear to accept all modes, even though it actually can't set any modes
    other than the bootup mode at all.
    (cherry picked from commit f6815cb68b0f6698497348fc6e4214dacef33b95)

diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 70bed62..303ad14 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -227,6 +227,26 @@ xfree2fbdev_timing(DisplayModePtr mode, 
 		var->vmode = FB_VMODE_NONINTERLACED;
 }
 
+static Bool
+fbdev_modes_equal(struct fb_var_screeninfo *one, struct fb_var_screeninfo *two)
+{
+	return (one->xres_virtual == two->xres_virtual &&
+		one->yres_virtual == two->yres_virtual &&
+		one->bits_per_pixel == two->bits_per_pixel &&
+		one->red.length == two->red.length &&
+		one->green.length == two->green.length &&
+		one->blue.length == two->blue.length &&
+		one->xres == two->xres && one->yres == two->yres &&
+		one->pixclock == two->pixclock &&
+		one->right_margin == two->right_margin &&
+		one->hsync_len == two->hsync_len &&
+		one->left_margin == two->left_margin &&
+		one->lower_margin == two->lower_margin &&
+		one->vsync_len == two->vsync_len &&
+		one->upper_margin == two->upper_margin &&
+		one->sync == two->sync && one->vmode == two->vmode);
+}
+
 static void
 fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
 {
@@ -470,13 +490,52 @@ fbdevHWGetVidmem(ScrnInfoPtr pScrn)
 	return fPtr->fix.smem_len;
 }
 
+static Bool
+fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
+{
+	fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+	struct fb_var_screeninfo req_var = fPtr->var, set_var;
+	
+	TRACE_ENTER("ModeInit");
+
+	xfree2fbdev_fblayout(pScrn, &req_var);
+	xfree2fbdev_timing(mode, &req_var);
+
+#if DEBUG
+	print_xfree_mode("init", mode);
+	print_fbdev_mode("init", &req_var);
+#endif
+
+	set_var = req_var;
+
+	if (check)
+		set_var.activate = FB_ACTIVATE_TEST;
+
+	if (0 != ioctl(fPtr->fd, FBIOPUT_VSCREENINFO, (void*)(&set_var))) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+		return FALSE;
+	}
+
+	if (!fbdev_modes_equal(&set_var, &req_var)) {
+		if (!check)
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+				   "FBIOPUT_VSCREENINFO succeeded but modified "
+				   "mode\n");
+#if DEBUG
+		print_fbdev_mode("returned", &set_var);
+#endif
+		return FALSE;
+	}
+
+	fPtr->var = set_var;
+
+	return TRUE;
+}
+
 void
 fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
 {
-	fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-	int virtX = pScrn->display->virtualX;
-	int virtY = pScrn->display->virtualY;
-	struct fb_var_screeninfo var;
 	char **modename;
 	DisplayModePtr mode,this,last = pScrn->modes;
 
@@ -484,6 +543,9 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
 	if (NULL == pScrn->display->modes)
 		return;
 
+	pScrn->virtualX = pScrn->display->virtualX;
+	pScrn->virtualY = pScrn->display->virtualY;
+
 	for (modename = pScrn->display->modes; *modename != NULL; modename++) {
 		for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next)
 			if (0 == strcmp(mode->name,*modename))
@@ -493,27 +555,20 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
 				   "\tmode \"%s\" not found\n", *modename);
 			continue;
 		}
-		memset(&var,0,sizeof(var));
-		xfree2fbdev_timing(mode,&var);
-		var.xres_virtual = virtX;
-		var.yres_virtual = virtY;
-		var.bits_per_pixel = pScrn->bitsPerPixel;
-		var.red.length = pScrn->weight.red;
-		var.green.length = pScrn->weight.green;
-		var.blue.length = pScrn->weight.blue;
-
-		var.activate = FB_ACTIVATE_TEST;
-		if (var.xres_virtual < var.xres) var.xres_virtual = var.xres;
-		if (var.yres_virtual < var.yres) var.yres_virtual = var.yres;
-		if (-1 == ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&var))) {
+
+		if (!fbdevHWSetMode(pScrn, mode, TRUE)) {
 			xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 				   "\tmode \"%s\" test failed\n", *modename);
 			continue;
 		}
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 			   "\tmode \"%s\" ok\n", *modename);
-		if (virtX < var.xres) virtX = var.xres;
-		if (virtY < var.yres) virtY = var.yres;
+
+		if (pScrn->virtualX < mode->HDisplay)
+			pScrn->virtualX = mode->HDisplay;
+		if (pScrn->virtualY < mode->VDisplay)
+			pScrn->virtualY = mode->VDisplay;
+
 		if (NULL == pScrn->modes) {
 			pScrn->modes = xnfalloc(sizeof(DisplayModeRec));
 			this = pScrn->modes;
@@ -530,8 +585,6 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
 		}
 		last = this;
 	}
-	pScrn->virtualX     = virtX;
-	pScrn->virtualY     = virtY;
 }
 
 DisplayModePtr
@@ -673,21 +726,12 @@ fbdevHWModeInit(ScrnInfoPtr pScrn, Displ
 {	
 	fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
 	
-	TRACE_ENTER("ModeInit");
-	xfree2fbdev_fblayout(pScrn, &fPtr->var);
-	xfree2fbdev_timing(mode,  &fPtr->var);
-#if DEBUG
-	print_xfree_mode("init",mode);
-	print_fbdev_mode("init",&fPtr->var);
-#endif
 	pScrn->vtSema = TRUE;
 
 	/* set */
-	if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+	if (!fbdevHWSetMode(pScrn, mode, FALSE))
 		return FALSE;
-	}
+
 	/* read back */
 	if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -767,18 +811,12 @@ ModeStatus
 fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
 {
 	ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-	fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-	struct fb_var_screeninfo var;
 
 	TRACE_ENTER("ValidMode");
-	memcpy(&var,&fPtr->var,sizeof(var));
-	xfree2fbdev_timing(mode, &var);
-	var.activate = FB_ACTIVATE_TEST;
-	if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
-		xf86DrvMsg(scrnIndex, X_ERROR,
-			   "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+
+	if (!fbdevHWSetMode(pScrn, mode, TRUE))
 		return MODE_BAD;
-	}
+
 	return MODE_OK;
 }
 
@@ -786,15 +824,12 @@ Bool
 fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
 {
 	ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-	fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
 
 	TRACE_ENTER("SwitchMode");
-	xfree2fbdev_timing(mode, &fPtr->var);
-	if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
-		xf86DrvMsg(scrnIndex, X_ERROR,
-			   "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+
+	if (!fbdevHWSetMode(pScrn, mode, FALSE))
 		return FALSE;
-	}
+
 	return TRUE;
 }
 



More information about the xorg-commit mailing list