* Re: Portrait display mode
2002-09-11 6:38 ` Geert Uytterhoeven
@ 2002-09-11 19:50 ` Antonino Daplas
0 siblings, 0 replies; 9+ messages in thread
From: Antonino Daplas @ 2002-09-11 19:50 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: otto.wyss, fbdev
[-- Attachment #1: Type: text/plain, Size: 2189 bytes --]
On Wed, 2002-09-11 at 14:38, Geert Uytterhoeven wrote:
> > > turnable display I rather see this feature implemented. I even may help but can
> > > spend much time. How difficult would it be?
> > >
> > It should not be too difficult to add per-driver support once the
>
> Can't this be moved up to generic code, so we don't have to modify all drivers?
>
I have thought about that, but since the patch was preliminary, I chose
not to disrupt the framework yet. The tricky part in making the support
generic is display panning.
Here is my train of thought. Moving support into fbgen might involve a
few assumptions. Firstly, info->var is assumed to be device specific
(ie, it does not care about the orientation). Secondly, the display->var
as well as those received from other sources (such as in an ioctl call)
are partly device independent. When a structure var is passed to the
driver, it will undergo conversion so the structure is sane from the
driver's perspective. The same is done vice-versa. I've introduced two
(exportable) functions, convert_var_to_physical(), and
convert_var_to_logical() that should do that.
All fbops functions should be passed with device-specific var except for
fb_set_var since I'm not too sure where to look for specific entry
points for fb_set_var. I guess fb_check_var and fb_pan_display are the
most critical ones, since the other fbops functions do not look at the
framelengths, nor the offsets.
With the changes, drivers that support fbcon_accel and gen_* functions
should have support for console rotation automatically.
For those that support fbcon_accel, but not gen_* functions, the driver
should not look at display->var anymore, but look instead into
info->var. If possible, use the convert_to_var functions when
passing/getting information to/from structure display.
For those, that don't support fbcon_accel, behaviour should remain as
usual.
I'm not too sure if this is the correct way of doing this, but it's the
best I can think of at the moment without causing very intrusive
changes.
Attached is a patch (fb_rotate2.diff). Please apply the patches I have
sent previously before applying this patch.
Tony
[-- Attachment #2: fb_rotate2.diff --]
[-- Type: text/x-patch, Size: 22504 bytes --]
diff -Naur linux-2.5.33/drivers/video/Config.in linux/drivers/video/Config.in
--- linux-2.5.33/drivers/video/Config.in Wed Sep 11 18:28:40 2002
+++ linux/drivers/video/Config.in Wed Sep 11 18:34:23 2002
@@ -227,7 +227,6 @@
tristate ' 24 bpp packed pixels support' CONFIG_FBCON_CFB24
tristate ' 32 bpp packed pixels support' CONFIG_FBCON_CFB32
tristate ' Hardware acceleration support' CONFIG_FBCON_ACCEL
- dep_tristate ' Console Display Rotation support' CONFIG_FBCON_ROTATE $CONFIG_FBCON_ACCEL
tristate ' Amiga bitplanes support' CONFIG_FBCON_AFB
tristate ' Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM
tristate ' Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
@@ -368,13 +367,6 @@
"$CONFIG_FB_CLPS711X" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_SGIVW" = "m" ]; then
define_tristate CONFIG_FBCON_ACCEL m
- fi
- fi
- if [ "$CONFIG_FB_VESA" = "y" ]; then
- define_tristate CONFIG_FBCON_ROTATE y
- else
- if [ "$CONFIG_FB_VESA" = "m" ]; then
- define_tristate CONFIG_FBCON_ROTATE m
fi
fi
if [ "$CONFIG_FB_AMIGA" = "y" ]; then
diff -Naur linux-2.5.33/drivers/video/Makefile linux/drivers/video/Makefile
--- linux-2.5.33/drivers/video/Makefile Wed Sep 11 18:28:49 2002
+++ linux/drivers/video/Makefile Wed Sep 11 18:36:23 2002
@@ -68,7 +68,7 @@
obj-$(CONFIG_FB_S3TRIO) += S3triofb.o
obj-$(CONFIG_FB_TGA) += tgafb.o
obj-$(CONFIG_FB_VESA) += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_VGA16) += vga16fb.o fbcon-vga-planes.o
+obj-$(CONFIG_FB_VGA16) += vga16fb.o fbcon-vga-planes.o
obj-$(CONFIG_FB_VIRGE) += virgefb.o
obj-$(CONFIG_FB_G364) += g364fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_FM2) += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
@@ -117,8 +117,7 @@
obj-$(CONFIG_FBCON_MFB) += fbcon-mfb.o
obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o
obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
-obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
-obj-$(CONFIG_FBCON_ROTATE) += fbcon-rotate.o
+obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o fbcon-rotate.o
include $(TOPDIR)/Rules.make
diff -Naur linux-2.5.33/drivers/video/cfbcopyarea.c linux/drivers/video/cfbcopyarea.c
--- linux-2.5.33/drivers/video/cfbcopyarea.c Wed Sep 11 18:29:01 2002
+++ linux/drivers/video/cfbcopyarea.c Wed Sep 11 18:30:53 2002
@@ -28,7 +28,6 @@
#include <asm/io.h>
#include <video/fbcon.h>
-#include "fbcon-rotate.h"
#define LONG_MASK (BITS_PER_LONG - 1)
@@ -329,12 +328,6 @@
vxres = p->var.xres_virtual;
vyres = p->var.yres_virtual;
-#ifdef FBCON_HAS_ROTATE
- if (p->var.vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
- vxres = p->var.yres_virtual;
- vyres = p->var.xres_virtual;
- }
-#endif
if (area->dx > vxres ||
area->sx > vxres ||
diff -Naur linux-2.5.33/drivers/video/cfbfillrect.c linux/drivers/video/cfbfillrect.c
--- linux-2.5.33/drivers/video/cfbfillrect.c Wed Sep 11 18:29:05 2002
+++ linux/drivers/video/cfbfillrect.c Wed Sep 11 18:30:58 2002
@@ -22,8 +22,6 @@
#include <asm/types.h>
#include <video/fbcon.h>
-#include "fbcon-rotate.h"
-
#if BITS_PER_LONG == 32
#define FB_WRITEL fb_writel
#define FB_READL fb_readl
@@ -53,12 +51,6 @@
vxres = p->var.xres_virtual;
vyres = p->var.yres_virtual;
-#ifdef FBCON_HAS_ROTATE
- if (p->var.vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
- vxres = p->var.yres_virtual;
- vyres = p->var.xres_virtual;
- }
-#endif
if (!rect->width || !rect->height ||
rect->dx > vxres ||
diff -Naur linux-2.5.33/drivers/video/cfbimgblt.c linux/drivers/video/cfbimgblt.c
--- linux-2.5.33/drivers/video/cfbimgblt.c Wed Sep 11 18:28:56 2002
+++ linux/drivers/video/cfbimgblt.c Wed Sep 11 18:30:48 2002
@@ -39,7 +39,6 @@
#include <asm/types.h>
#include <video/fbcon.h>
-#include "fbcon-rotate.h"
#define DEBUG
@@ -298,12 +297,6 @@
vxres = p->var.xres_virtual;
vyres = p->var.yres_virtual;
-#ifdef FBCON_HAS_ROTATE
- if (p->var.vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
- vxres = p->var.yres_virtual;
- vyres = p->var.xres_virtual;
- }
-#endif
/*
* We could use hardware clipping but on many cards you get around hardware
diff -Naur linux-2.5.33/drivers/video/fbcon-rotate.c linux/drivers/video/fbcon-rotate.c
--- linux-2.5.33/drivers/video/fbcon-rotate.c Wed Sep 11 18:33:04 2002
+++ linux/drivers/video/fbcon-rotate.c Wed Sep 11 18:32:32 2002
@@ -114,9 +114,9 @@
struct fb_info *info = p->fb_info;
struct fb_copyarea area;
- area.sx = info->var.yres_virtual - ((sy + height) * fontheight(p));
+ area.sx = info->var.xres_virtual - ((sy + height) * fontheight(p));
area.sy = sx * fontwidth(p);
- area.dx = info->var.yres_virtual - ((dy + height) * fontheight(p));
+ area.dx = info->var.xres_virtual - ((dy + height) * fontheight(p));
area.dy = dx * fontwidth(p);
area.width = height * fontheight(p);
area.height = width * fontwidth(p);
@@ -131,7 +131,7 @@
struct fb_fillrect region;
region.color = attr_bgcol_ec(p,vc);
- region.dx = info->var.yres_virtual - ((sy + height) * fontheight(p));
+ region.dx = info->var.xres_virtual - ((sy + height) * fontheight(p));
region.dy = sx * fontwidth(p);
region.height = width * fontwidth(p);
region.width = height * fontheight(p);
@@ -150,7 +150,7 @@
image.fg_color = attr_fgcol(p, c);
image.bg_color = attr_bgcol(p, c);
- image.dx = info->var.yres_virtual - ((yy * fontheight(p)) + fontheight(p));
+ image.dx = info->var.xres_virtual - ((yy * fontheight(p)) + fontheight(p));
image.dy = xx * fontwidth(p);
image.width = fontheight(p);
image.height = fontwidth(p);
@@ -170,7 +170,7 @@
image.fg_color = attr_fgcol(p, *s);
image.bg_color = attr_bgcol(p, *s);
- image.dx = info->var.yres_virtual - ((yy * fontheight(p)) + fontheight(p));
+ image.dx = info->var.xres_virtual - ((yy * fontheight(p)) + fontheight(p));
image.dy = xx * fontwidth(p);
image.width = fontheight(p);
image.height = fontwidth(p);
@@ -188,7 +188,7 @@
struct fb_fillrect region;
region.color = attr_fgcol_ec(p, p->conp);
- region.dx = info->var.yres_virtual - ((yy * fontheight(p)) + fontheight(p));
+ region.dx = info->var.xres_virtual - ((yy * fontheight(p)) + fontheight(p));
region.dy = xx * fontwidth(p);
region.width = fontheight(p);
region.height = fontwidth(p);
@@ -203,10 +203,10 @@
struct fb_info *info = p->fb_info;
unsigned int cw = fontwidth(p);
unsigned int ch = fontheight(p);
- unsigned int rw = info->var.xres % cw;
- unsigned int bh = info->var.yres % ch;
- unsigned int rs = info->var.xres - rw;
- unsigned int bs = info->var.yres - bh;
+ unsigned int rw = info->var.yres % cw;
+ unsigned int bh = info->var.xres % ch;
+ unsigned int rs = info->var.yres - rw;
+ unsigned int bs = info->var.xres - bh;
struct fb_fillrect region;
region.color = attr_bgcol_ec(p,vc);
@@ -214,15 +214,15 @@
if (rw && !bottom_only) {
region.dx = 0;
- region.dy = info->var.xoffset + rs;
+ region.dy = info->var.yoffset + rs;
region.height = rw;
region.width = info->var.yres_virtual;
info->fbops->fb_fillrect(info, ®ion);
}
if (bh) {
- region.dx = info->var.yres_virtual - (info->var.yoffset + bs + bh);
- region.dy = info->var.xoffset;
+ region.dx = info->var.xres_virtual - (info->var.xoffset + bs + bh);
+ region.dy = info->var.yoffset;
region.width = bh;
region.height = rs;
info->fbops->fb_fillrect(info, ®ion);
@@ -276,9 +276,9 @@
struct fb_copyarea area;
area.sx = sy * fontheight(p);
- area.sy = info->var.xres_virtual - ((sx + width) * fontwidth(p));
+ area.sy = info->var.yres_virtual - ((sx + width) * fontwidth(p));
area.dx = dy * fontheight(p);
- area.dy = info->var.xres_virtual - ((dx + width) * fontwidth(p));
+ area.dy = info->var.yres_virtual - ((dx + width) * fontwidth(p));
area.width = height * fontheight(p);
area.height = width * fontwidth(p);
@@ -293,7 +293,7 @@
region.color = attr_bgcol_ec(p,vc);
region.dx = sy * fontheight(p);
- region.dy = info->var.xres_virtual - ((sx + width) * fontwidth(p));
+ region.dy = info->var.yres_virtual - ((sx + width) * fontwidth(p));
region.height = width * fontwidth(p);
region.width = height * fontheight(p);
region.rop = ROP_COPY;
@@ -312,7 +312,7 @@
image.fg_color = attr_fgcol(p, c);
image.bg_color = attr_bgcol(p, c);
image.dx = yy * fontheight(p);
- image.dy = info->var.xres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
+ image.dy = info->var.yres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
image.width = fontheight(p);
image.height = fontwidth(p);
image.data = fontcache + (c & charmask)*fontheight(p) * width;
@@ -332,7 +332,7 @@
image.fg_color = attr_fgcol(p, *s);
image.bg_color = attr_bgcol(p, *s);
image.dx = yy * fontheight(p);
- image.dy = info->var.xres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
+ image.dy = info->var.yres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
image.width = fontheight(p);
image.height = fontwidth(p);
image.depth = 1;
@@ -350,7 +350,7 @@
region.color = attr_fgcol_ec(p, p->conp);
region.dx = yy * fontheight(p);
- region.dy = info->var.xres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
+ region.dy = info->var.yres_virtual - ((xx * fontwidth(p)) + fontwidth(p));
region.width = fontheight(p);
region.height = fontwidth(p);
region.rop = ROP_XOR;
@@ -364,10 +364,10 @@
struct fb_info *info = p->fb_info;
unsigned int cw = fontwidth(p);
unsigned int ch = fontheight(p);
- unsigned int rw = info->var.xres % cw;
- unsigned int bh = info->var.yres % ch;
- unsigned int rs = info->var.xres - rw;
- unsigned int bs = info->var.yres - bh;
+ unsigned int rw = info->var.yres % cw;
+ unsigned int bh = info->var.xres % ch;
+ unsigned int rs = info->var.yres - rw;
+ unsigned int bs = info->var.xres - bh;
struct fb_fillrect region;
region.color = attr_bgcol_ec(p,vc);
@@ -375,15 +375,15 @@
if (rw && !bottom_only) {
region.dx = 0;
- region.dy = info->var.xres_virtual - (info->var.xoffset + rs + rw);
+ region.dy = info->var.yres_virtual - (info->var.yoffset + rs + rw);
region.height = rw;
region.width = info->var.yres_virtual;
info->fbops->fb_fillrect(info, ®ion);
}
if (bh) {
- region.dx = info->var.yoffset + bs;
- region.dy = info->var.xres_virtual - (info->var.xoffset + rs + rw);
+ region.dx = info->var.xoffset + bs;
+ region.dy = info->var.yres_virtual - (info->var.yoffset + rs + rw);
region.width = bh;
region.height = rs;
info->fbops->fb_fillrect(info, ®ion);
diff -Naur linux-2.5.33/drivers/video/fbcon-rotate.h linux/drivers/video/fbcon-rotate.h
--- linux-2.5.33/drivers/video/fbcon-rotate.h Wed Sep 11 18:33:06 2002
+++ linux/drivers/video/fbcon-rotate.h Wed Sep 11 18:32:35 2002
@@ -7,16 +7,6 @@
#include <linux/config.h>
-#ifdef MODULE
-#if defined(CONFIG_FBCON_ROTATE) || defined(CONFIG_FBCON_ROTATE_MODULE)
-#define FBCON_HAS_ROTATE
-#endif
-#else
-#if defined(CONFIG_FBCON_ROTATE)
-#define FBCON_HAS_ROTATE
-#endif
-#endif
-
extern struct display_switch fbcon_rr;
extern void fbcon_rr_setup(struct display *p);
extern void fbcon_rr_bmove(struct display *p, int sy, int sx, int dy,
diff -Naur linux-2.5.33/drivers/video/fbgen.c linux/drivers/video/fbgen.c
--- linux-2.5.33/drivers/video/fbgen.c Wed Sep 11 18:28:35 2002
+++ linux/drivers/video/fbgen.c Wed Sep 11 18:30:23 2002
@@ -31,37 +31,119 @@
#include "fbcon-accel.h"
#include "fbcon-rotate.h"
+#define SWAP(x,y,z) do { (z) = (x); (x) = (y); (y) = (z); } while(0)
+
+void convert_var_to_phys(struct fb_var_screeninfo *var)
+{
+#ifdef FBCON_HAS_ACCEL
+ u32 tmp, xoffset, yoffset;
+
+ switch (var->vmode & FB_ROTATE_MASK) {
+ case FB_VMODE_ROTATE_CW:
+ xoffset = var->yres_virtual - (var->yres + var->yoffset);
+ yoffset = var->xoffset;
+ var->xoffset = xoffset;
+ var->yoffset = yoffset;
+ SWAP(var->xres, var->yres, tmp);
+ SWAP(var->xres_virtual, var->yres_virtual, tmp);
+ break;
+ case FB_VMODE_ROTATE_CCW:
+ xoffset = var->yoffset;
+ yoffset = var->xres_virtual - (var->xres + var->xoffset);
+ var->xoffset = xoffset;
+ var->yoffset = yoffset;
+ SWAP(var->xres, var->yres, tmp);
+ SWAP(var->xres_virtual, var->yres_virtual, tmp);
+ break;
+ case FB_VMODE_ROTATE_UD:
+ var->xoffset = var->xres_virtual - (var->xres + var->xoffset);
+ var->yoffset = var->yres_virtual - (var->yres + var->yoffset);
+ break;
+ }
+#endif
+}
+
+/*
+ * convert var from what hardware actually sees
+ */
+void convert_var_to_logical(struct fb_var_screeninfo *var)
+{
+#ifdef FBCON_HAS_ACCEL
+ u32 tmp, xoffset, yoffset;
+
+ switch (var->vmode & FB_ROTATE_MASK) {
+ case FB_VMODE_ROTATE_CW:
+ xoffset = var->yoffset;
+ yoffset = var->xres_virtual - (var->xres + var->xoffset);
+ var->xoffset = xoffset;
+ var->yoffset = yoffset;
+ SWAP(var->xres, var->yres, tmp);
+ SWAP(var->xres_virtual, var->yres_virtual, tmp);
+ break;
+ case FB_VMODE_ROTATE_CCW:
+ xoffset = var->yres_virtual - (var->yres + var->yoffset);
+ yoffset = var->xoffset;
+ var->xoffset = xoffset;
+ var->yoffset = yoffset;
+ SWAP(var->xres, var->yres, tmp);
+ SWAP(var->xres_virtual, var->yres_virtual, tmp);
+ break;
+ case FB_VMODE_ROTATE_UD:
+ var->xoffset = var->xres_virtual - (var->xres + var->xoffset);
+ var->yoffset = var->yres_virtual - (var->yres + var->yoffset);
+ break;
+ }
+#endif
+}
+
int gen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
- int err;
+ int err, xoffset, yoffset, vmode, activate;
+ /*
+ * FIXME: VESAFB crashes when switching orientation and
+ * xoffset/yoffset is not zero. This is what changevar
+ * does anyway.
+ */
+ var->xoffset = 0;
+ var->yoffset = 0;
+ convert_var_to_phys(var);
+ xoffset = var->xoffset;
+ yoffset = var->yoffset;
if (con < 0 || (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo)))) {
if (!info->fbops->fb_check_var) {
- *var = info->var;
- return 0;
+ activate = var->activate;
+ vmode = var->vmode;
+ *var = info->var;
+ var->vmode &= ~FB_ROTATE_MASK;
+ var->vmode |= vmode & FB_ROTATE_MASK;
+ var->activate &= ~FB_ACTIVATE_MASK;
+ var->activate |= activate & FB_ACTIVATE_MASK;
}
-
- if ((err = info->fbops->fb_check_var(var, info)))
+ else if ((err = info->fbops->fb_check_var(var, info)))
return err;
-
+
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+ var->xoffset = xoffset;
+ var->yoffset = yoffset;
info->var = *var;
if (con == info->currcon) {
if (info->fbops->fb_set_par)
info->fbops->fb_set_par(info);
- if (info->fbops->fb_pan_display)
+ if (info->fbops->fb_pan_display) {
info->fbops->fb_pan_display(&info->var, con, info);
-
+ }
gen_set_disp(con, info);
fb_set_cmap(&info->cmap, 1, info);
}
-
+
if (info->changevar)
info->changevar(con);
}
}
+ convert_var_to_logical(var);
return 0;
}
@@ -139,13 +221,16 @@
display->dispsw_data = info->pseudo_palette;
}
display->var = info->var;
+ convert_var_to_logical(&display->var);
/*
* If we are setting all the virtual consoles, also set
* the defaults used to create new consoles.
*/
- if (con < 0 || info->var.activate & FB_ACTIVATE_ALL)
- info->disp->var = info->var;
+ if (con < 0 || info->var.activate & FB_ACTIVATE_ALL) {
+ info->disp->var = info->var;
+ convert_var_to_logical(&info->disp->var);
+ }
if (info->var.bits_per_pixel == 24) {
#ifdef FBCON_HAS_CFB24
@@ -157,7 +242,6 @@
#ifdef FBCON_HAS_ACCEL
display->scrollmode = SCROLL_YNOMOVE;
-#ifdef FBCON_HAS_ROTATE
if (info->var.vmode & FB_VMODE_ROTATE_CW)
display->dispsw = &fbcon_rr;
else if (info->var.vmode & FB_VMODE_ROTATE_CCW)
@@ -165,7 +249,6 @@
else if (info->var.vmode & FB_VMODE_ROTATE_UD)
display->dispsw = &fbcon_ud;
else
-#endif /* FBCON_HAS_ROTATE */
display->dispsw = &fbcon_accel;
#else
display->dispsw = &fbcon_dummy;
@@ -201,11 +284,14 @@
int err;
if (con == info->currcon) {
+ convert_var_to_phys(&disp->var);
info->var.xoffset = disp->var.xoffset;
info->var.yoffset = disp->var.yoffset;
info->var.vmode = disp->var.vmode;
if (info->fbops->fb_pan_display) {
- if ((err = info->fbops->fb_pan_display(&info->var, con, info)))
+ err = info->fbops->fb_pan_display(&info->var, con, info);
+ convert_var_to_logical(&disp->var);
+ if (err)
return err;
}
}
@@ -224,6 +310,7 @@
* Save the old colormap and graphics mode.
*/
disp->var = info->var;
+ convert_var_to_logical(&disp->var);
if (disp->cmap.len)
fb_copy_cmap(&info->cmap, &disp->cmap, 0);
}
@@ -292,5 +379,7 @@
EXPORT_SYMBOL(gen_update_var);
EXPORT_SYMBOL(gen_switch);
EXPORT_SYMBOL(fbgen_blank);
+EXPORT_SYMBOL(convert_var_to_logical);
+EXPORT_SYMBOL(convert_var_to_phys);
MODULE_LICENSE("GPL");
diff -Naur linux-2.5.33/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- linux-2.5.33/drivers/video/fbmem.c Wed Sep 11 18:28:43 2002
+++ linux/drivers/video/fbmem.c Wed Sep 11 18:37:54 2002
@@ -476,7 +476,9 @@
return -ENODEV;
switch (cmd) {
case FBIOGET_VSCREENINFO:
- return copy_to_user((void *) arg, &info->var,
+ var = info->var;
+ convert_var_to_logical(&var);
+ return copy_to_user((void *) arg, &var,
sizeof(var)) ? -EFAULT : 0;
case FBIOPUT_VSCREENINFO:
if (copy_from_user(&var, (void *) arg, sizeof(var)))
@@ -504,8 +506,10 @@
return -EFAULT;
if (fb->fb_pan_display == NULL)
return (var.xoffset || var.yoffset) ? -EINVAL : 0;
+ convert_var_to_phys(&var);
if ((i=fb->fb_pan_display(&var, PROC_CONSOLE(info), info)))
return i;
+ convert_var_to_logical(&var);
if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT;
return i;
diff -Naur linux-2.5.33/drivers/video/vesafb.c linux/drivers/video/vesafb.c
--- linux-2.5.33/drivers/video/vesafb.c Wed Sep 11 18:29:11 2002
+++ linux/drivers/video/vesafb.c Wed Sep 11 18:31:02 2002
@@ -27,8 +27,6 @@
#include <video/fbcon.h>
-#include "fbcon-rotate.h"
-
#define dac_reg (0x3c8)
#define dac_val (0x3c9)
@@ -64,18 +62,12 @@
static void (*pmi_start)(void);
static void (*pmi_pal)(void);
-#ifdef FBCON_HAS_ROTATE
-static u32 xres;
-static u32 yres;
-static u32 vxres;
-static u32 vyres;
-#endif
/* --------------------------------------------------------------------- */
static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
- int offset, depth = (var->bits_per_pixel + 7)/8;
+ int offset;
if (!ypan)
return -EINVAL;
@@ -86,18 +78,6 @@
if ((ypan==1) && var->yoffset+var->yres > var->yres_virtual)
return -EINVAL;
-#ifdef FBCON_HAS_ROTATE
- if (var->vmode & FB_VMODE_ROTATE_CW)
- offset = ((var->xoffset * info->fix.line_length) +
- ((var->yres_virtual - (var->yoffset + var->yres))) * depth) / 4;
- else if (var->vmode & FB_VMODE_ROTATE_CCW)
- offset = (((var->xres_virtual - (var->xoffset + var->xres)) * info->fix.line_length) +
- (var->yoffset * depth)) / 4;
- else if (var->vmode & FB_VMODE_ROTATE_UD)
- offset = (((var->yres_virtual - (var->yoffset + var->yres)) * info->fix.line_length) +
- ((var->xres_virtual - (var->xoffset + var->xres))) * depth) / 4;
- else
-#endif
offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
__asm__ __volatile__(
@@ -193,43 +173,11 @@
return 0;
}
-static int vesafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-#ifdef FBCON_HAS_ROTATE
- u32 vmode;
-
- vmode = var->vmode;
- *var = info->var;
- if (vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
- var->xres = yres;
- var->yres = xres;
- var->xres_virtual = vyres;
- var->yres_virtual = vxres;
- }
- else {
- var->xres = xres;
- var->yres = yres;
- var->xres_virtual = vxres;
- var->yres_virtual = vyres;
- }
- vmode &= FB_ROTATE_MASK;
- vmode |= info->var.vmode & ~FB_ROTATE_MASK;
- var->vmode = vmode;
-#else
- *var = info->var;
-#endif
-
- var->xoffset = 0;
- var->yoffset = 0;
- return 0;
-}
-
static struct fb_ops vesafb_ops = {
.owner = THIS_MODULE,
.fb_set_var = gen_set_var,
.fb_get_cmap = gen_get_cmap,
.fb_set_cmap = gen_set_cmap,
- .fb_check_var = vesafb_check_var,
.fb_setcolreg = vesafb_setcolreg,
.fb_pan_display = vesafb_pan_display,
.fb_fillrect = cfb_fillrect,
@@ -352,19 +300,6 @@
ypan = 0;
}
-#ifdef FBCON_HAS_ROTATE
- xres = vesafb_defined.xres;
- yres = vesafb_defined.yres;
- vxres = vesafb_defined.xres_virtual;
- vyres = vesafb_defined.yres_virtual;
- if (vesafb_defined.vmode & (FB_VMODE_ROTATE_CW | FB_VMODE_ROTATE_CCW)) {
- vesafb_defined.xres = yres;
- vesafb_defined.yres = xres;
- vesafb_defined.xres_virtual = vyres;
- vesafb_defined.yres_virtual = vxres;
- }
-#endif
-
/* some dummy values for timing to make fbset happy */
vesafb_defined.pixclock = 10000000 / vesafb_defined.xres * 1000 / vesafb_defined.yres;
vesafb_defined.left_margin = (vesafb_defined.xres / 8) & 0xf8;
diff -Naur linux-2.5.33/include/linux/fb.h linux/include/linux/fb.h
--- linux-2.5.33/include/linux/fb.h Wed Sep 11 18:29:57 2002
+++ linux/include/linux/fb.h Wed Sep 11 18:32:01 2002
@@ -419,6 +419,8 @@
extern int fb_blank(int blank, struct fb_info *info);
extern int gen_switch(int con, struct fb_info *info);
extern void gen_set_disp(int con, struct fb_info *info);
+extern void convert_var_to_logical(struct fb_var_screeninfo *var);
+extern void convert_var_to_phys(struct fb_var_screeninfo *var);
/* drivers/video/fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info);
^ permalink raw reply [flat|nested] 9+ messages in thread