|
From: Alexander K. <ale...@gm...> - 2003-01-19 18:57:02
Attachments:
fbcon.diff
|
---------- Weitergeleitete Nachricht ----------
Subject: [PATCH 2.5.59] fix for fbcon.c
Date: Sun, 19 Jan 2003 19:36:12 +0100
From: Alexander Kern <ale...@gm...>
To: fb-...@li...
Hello,
hier is a fix needed by 1400x1050 resolution. fbcon_resize() without fis =
set
resolution to 1400x1040 and confusing LCD vertical stretching.
Regards
Alex
PS: I have retest both kernel versions, here is a result.
COMPAQ ARMADA E500, ATI (Mach64) Rage 3D Mobility P/M
15" with native 1400x1050 pixel
2.4.21-pre3 2.5.59
640x400 perfect(LOGO) perfect
640x480 perfect(LOGO) perfect
800x600 perfect perfect
1024x768 h. overlapping(LOGO) h. overlapping
1152x864 h. overlapping h. overlapping
1280x1024 h. overlapping h. overlapping
1400x1050 perfect perfect (with this
fix)
LOGO by 640x4?0 means strange blue pixels as mirror of pinguin
LOGO by 1024x768 means shift to top, pinguin head is unvisible
h. overlapping means mostly stretching issue.
-------------------------------------------------------
|
|
From: Antonino D. <ad...@po...> - 2003-01-20 08:55:20
|
On Mon, 2003-01-20 at 02:56, Alexander Kern wrote:
[...]
> --- linux-2.5.orig/drivers/video/console/fbcon.c 2003-01-17 16:13:53.000000000 +0100
> +++ linux/drivers/video/console/fbcon.c 2003-01-19 19:17:23.000000000 +0100
> @@ -1876,17 +1876,23 @@
> struct display *p = &fb_display[vc->vc_num];
> struct fb_info *info = p->fb_info;
> struct fb_var_screeninfo var = info->var;
> - int err;
> + int err; int x_diff, y_diff;
>
> var.xres = width * vc->vc_font.width;
> var.yres = height * vc->vc_font.height;
> var.activate = FB_ACTIVATE_NOW;
> -
> + x_diff = info->var.xres - var.xres;
> + y_diff = info->var.yres - var.yres;
> + if(x_diff < 0 || x_diff > vc->vc_font.width ||
> + (y_diff < 0 || y_diff > vc->vc_font.height)) {
> + DPRINTK("resize now %ix%i\n", var.xres, var.yres);
> err = fb_set_var(&var, info);
> return (err || var.xres != info->var.xres ||
> - var.yres != info->var.yres) ?
> - -EINVAL : 0;
> -
> + var.yres != info->var.yres) ? -EINVAL : 0;
> + } else {
> + DPRINTK("prevent resize\n");
> + return 0;
> + }
> }
>
> static int fbcon_switch(struct vc_data *vc)
Yes, that will work, only if all your console have the same window
size. If the size of one of your console is different, then these tests
(x_diff > vc->vc_font.width || y_diff > vc->vc_font.height) will become
true each time you switch consoles, so you'll be back with a yres of
1040 instead of 1050. The best solution is for the driver to round up
to 1050 if 1040 is not acceptable.
Still, its much better than the old one :-). If you don't mind, I'll
add a few things to your patch:
a. We do not need to activate the hardware immediately if there is a
chance of failure.
b. The xres/yres returned from fb_set_var() will be acceptable as long
as the value is within a fontwidth/fontheight. This should fix hardware
that only has a limited set of video modes.
BTW, I'm also attaching a diff to fix vc_resize() in vt.c. In
vc_resize(), if con_resize() exits with an error, the new console
dimensions are not reset to the original, and memory from kmalloc() is
not freed.
Tony
PATCH 1: fbcon_resize
<< begin >>
diff -Naur linux-2.5.59/drivers/video/console/fbcon.c linux/drivers/video/console/fbcon.c
--- linux-2.5.59/drivers/video/console/fbcon.c 2003-01-20 08:19:50.000000000 +0000
+++ linux/drivers/video/console/fbcon.c 2003-01-20 08:37:06.000000000 +0000
@@ -1870,23 +1870,35 @@
}
-static int fbcon_resize(struct vc_data *vc, unsigned int width,
- unsigned int height)
+ static int fbcon_resize(struct vc_data *vc, unsigned int width,
+ unsigned int height)
{
struct display *p = &fb_display[vc->vc_num];
struct fb_info *info = p->fb_info;
struct fb_var_screeninfo var = info->var;
- int err;
-
- var.xres = width * vc->vc_font.width;
- var.yres = height * vc->vc_font.height;
- var.activate = FB_ACTIVATE_NOW;
-
- err = fb_set_var(&var, info);
- return (err || var.xres != info->var.xres ||
- var.yres != info->var.yres) ?
- -EINVAL : 0;
-
+ int err; int x_diff, y_diff;
+ int fw = vc->vc_font.width;
+ int fh = vc->vc_font.height;
+
+ var.xres = width * fw;
+ var.yres = height * fh;
+ x_diff = info->var.xres - var.xres;
+ y_diff = info->var.yres - var.yres;
+ if (x_diff < 0 || x_diff > fw ||
+ (y_diff < 0 || y_diff > fh)) {
+ var.activate = FB_ACTIVATE_TEST;
+ err = fb_set_var(&var, info);
+ if (err || width != var.xres/fw ||
+ height != var.yres/fh)
+ return -EINVAL;
+ DPRINTK("resize now %ix%i\n", var.xres, var.yres);
+ var.activate = FB_ACTIVATE_NOW;
+ fb_set_var(&var, info);
+ p->vrows = info->var.yres_virtual/fh;
+ } else {
+ DPRINTK("prevent resize\n");
+ }
+ return 0;
}
static int fbcon_switch(struct vc_data *vc)
<< end >>
PATCH 2: vc_resize
<< begin >>
diff -Naur linux-2.5.59/drivers/char/vt.c linux/drivers/char/vt.c
--- linux-2.5.59/drivers/char/vt.c 2003-01-20 08:18:11.000000000 +0000
+++ linux/drivers/char/vt.c 2003-01-20 08:17:37.000000000 +0000
@@ -732,6 +732,10 @@
if (new_cols == video_num_columns && new_rows == video_num_lines)
return 0;
+ err = resize_screen(currcons, new_cols, new_rows);
+ if (err)
+ return err;
+
newscreen = (unsigned short *) kmalloc(new_screen_size, GFP_USER);
if (!newscreen)
return -ENOMEM;
@@ -746,9 +750,6 @@
video_size_row = new_row_size;
screenbuf_size = new_screen_size;
- err = resize_screen(currcons, new_cols, new_rows);
- if (err)
- return err;
rlth = min(old_row_size, new_row_size);
rrem = new_row_size - rlth;
<< end >>
|
|
From: Alexander K. <ale...@gm...> - 2003-01-22 17:45:34
|
Hello,=20
thanks, it look good for me.
Regards
Alex Kern
Am Montag, 20. Januar 2003 09:45 schrieb Antonino Daplas:
> On Mon, 2003-01-20 at 02:56, Alexander Kern wrote:
> [...]
>
> > --- linux-2.5.orig/drivers/video/console/fbcon.c=092003-01-17
> > 16:13:53.000000000 +0100 +++
> > linux/drivers/video/console/fbcon.c=092003-01-19 19:17:23.000000000 +=
0100
> > @@ -1876,17 +1876,23 @@
> > =09struct display *p =3D &fb_display[vc->vc_num];
> > =09struct fb_info *info =3D p->fb_info;
> > =09struct fb_var_screeninfo var =3D info->var;
> > -=09int err;
> > +=09int err; int x_diff, y_diff;
> >
> > =09var.xres =3D width * vc->vc_font.width;
> > =09var.yres =3D height * vc->vc_font.height;
> > =09var.activate =3D FB_ACTIVATE_NOW;
> > -
> > +=09x_diff =3D info->var.xres - var.xres;
> > +=09y_diff =3D info->var.yres - var.yres;
> > +=09if(x_diff < 0 || x_diff > vc->vc_font.width ||
> > +=09 (y_diff < 0 || y_diff > vc->vc_font.height)) {
> > +=09=09DPRINTK("resize now %ix%i\n", var.xres, var.yres);
> > =09err =3D fb_set_var(&var, info);
> > =09return (err || var.xres !=3D info->var.xres ||
> > -=09=09 var.yres !=3D info->var.yres) ?
> > -=09=09-EINVAL : 0;
> > -
> > +=09=09=09var.yres !=3D info->var.yres) ? -EINVAL : 0;
> > +=09} else {
> > +=09=09DPRINTK("prevent resize\n");
> > +=09=09return 0;
> > +=09}
> > }
> >
> > static int fbcon_switch(struct vc_data *vc)
>
> Yes, that will work, only if all your console have the same window
> size. If the size of one of your console is different, then these test=
s
> (x_diff > vc->vc_font.width || y_diff > vc->vc_font.height) will become
> true each time you switch consoles, so you'll be back with a yres of
> 1040 instead of 1050. The best solution is for the driver to round up
> to 1050 if 1040 is not acceptable.
>
> Still, its much better than the old one :-). If you don't mind, I'll
> add a few things to your patch:
>
> a. We do not need to activate the hardware immediately if there is a
> chance of failure.
>
> b. The xres/yres returned from fb_set_var() will be acceptable as long
> as the value is within a fontwidth/fontheight. This should fix hardware
> that only has a limited set of video modes.
>
> BTW, I'm also attaching a diff to fix vc_resize() in vt.c. In
> vc_resize(), if con_resize() exits with an error, the new console
> dimensions are not reset to the original, and memory from kmalloc() is
> not freed.
>
> Tony
>
> PATCH 1: fbcon_resize
> << begin >>
>
> diff -Naur linux-2.5.59/drivers/video/console/fbcon.c
> linux/drivers/video/console/fbcon.c ---
> linux-2.5.59/drivers/video/console/fbcon.c=092003-01-20 08:19:50.000000=
000
> +0000 +++ linux/drivers/video/console/fbcon.c=092003-01-20 08:37:06.000=
000000
> +0000 @@ -1870,23 +1870,35 @@
> }
>
>
> -static int fbcon_resize(struct vc_data *vc, unsigned int width,
> -=09=09=09unsigned int height)
> + static int fbcon_resize(struct vc_data *vc, unsigned int width,
> +=09=09=09 unsigned int height)
> {
> =09struct display *p =3D &fb_display[vc->vc_num];
> =09struct fb_info *info =3D p->fb_info;
> =09struct fb_var_screeninfo var =3D info->var;
> -=09int err;
> -
> -=09var.xres =3D width * vc->vc_font.width;
> -=09var.yres =3D height * vc->vc_font.height;
> -=09var.activate =3D FB_ACTIVATE_NOW;
> -
> -=09err =3D fb_set_var(&var, info);
> -=09return (err || var.xres !=3D info->var.xres ||
> -=09=09 var.yres !=3D info->var.yres) ?
> -=09=09-EINVAL : 0;
> -
> +=09int err; int x_diff, y_diff;
> +=09int fw =3D vc->vc_font.width;
> +=09int fh =3D vc->vc_font.height;
> +
> +=09var.xres =3D width * fw;
> +=09var.yres =3D height * fh;
> +=09x_diff =3D info->var.xres - var.xres;
> +=09y_diff =3D info->var.yres - var.yres;
> +=09if (x_diff < 0 || x_diff > fw ||
> +=09 (y_diff < 0 || y_diff > fh)) {
> +=09=09var.activate =3D FB_ACTIVATE_TEST;
> +=09=09err =3D fb_set_var(&var, info);
> +=09=09if (err || width !=3D var.xres/fw ||
> +=09=09 height !=3D var.yres/fh)
> +=09=09=09return -EINVAL;
> +=09=09DPRINTK("resize now %ix%i\n", var.xres, var.yres);
> +=09=09var.activate =3D FB_ACTIVATE_NOW;
> +=09=09fb_set_var(&var, info);
> +=09=09p->vrows =3D info->var.yres_virtual/fh;
> +=09} else {
> +=09=09DPRINTK("prevent resize\n");
> +=09}
> +=09return 0;
> }
>
> static int fbcon_switch(struct vc_data *vc)
> << end >>
>
> PATCH 2: vc_resize
>
> << begin >>
>
> diff -Naur linux-2.5.59/drivers/char/vt.c linux/drivers/char/vt.c
> --- linux-2.5.59/drivers/char/vt.c=092003-01-20 08:18:11.000000000 +000=
0
> +++ linux/drivers/char/vt.c=092003-01-20 08:17:37.000000000 +0000
> @@ -732,6 +732,10 @@
> =09if (new_cols =3D=3D video_num_columns && new_rows =3D=3D video_num_=
lines)
> =09=09return 0;
>
> +=09err =3D resize_screen(currcons, new_cols, new_rows);
> +=09if (err)
> +=09=09return err;
> +
> =09newscreen =3D (unsigned short *) kmalloc(new_screen_size, GFP_USER)=
;
> =09if (!newscreen)
> =09=09return -ENOMEM;
> @@ -746,9 +750,6 @@
> =09video_size_row =3D new_row_size;
> =09screenbuf_size =3D new_screen_size;
>
> -=09err =3D resize_screen(currcons, new_cols, new_rows);
> -=09if (err)
> -=09=09return err;
>
> =09rlth =3D min(old_row_size, new_row_size);
> =09rrem =3D new_row_size - rlth;
> << end >>
>
>
>
> -------------------------------------------------------
> This SF.NET email is sponsored by: FREE SSL Guide from Thawte
> are you planning your Web Server Security? Click here to get a FREE
> Thawte SSL guide and find the answers to all your SSL security issues.
> http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0026en
> _______________________________________________
> Linux-fbdev-devel mailing list
> Lin...@li...
> https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel
|
|
From: Antonino D. <ad...@po...> - 2003-02-17 11:33:52
|
On Mon, 2003-01-20 at 16:45, Antonino Daplas wrote:
> On Mon, 2003-01-20 at 02:56, Alexander Kern wrote:
>
> Yes, that will work, only if all your console have the same window
> size. If the size of one of your console is different, then these tests
> (x_diff > vc->vc_font.width || y_diff > vc->vc_font.height) will become
> true each time you switch consoles, so you'll be back with a yres of
> 1040 instead of 1050. The best solution is for the driver to round up
> to 1050 if 1040 is not acceptable.
>
> Still, its much better than the old one :-). If you don't mind, I'll
> add a few things to your patch:
>
> a. We do not need to activate the hardware immediately if there is a
> chance of failure.
>
> b. The xres/yres returned from fb_set_var() will be acceptable as long
> as the value is within a fontwidth/fontheight. This should fix hardware
> that only has a limited set of video modes.
>
Here's an incremental patch (linux-2.5.61 + James' latest fbdev.diff)
1. adjust display->vrows unconditionally during fbcon_resize(). This
should prevent console corruption when var->yres_virtual was changed
behind the back of the console, ie using fbset.
2. call fbcon_resize() as early as possible during fbcon_switch().
Tony
diff -Naur linux-2.5.61-fbdev/drivers/video/console/fbcon.c linux-2.5.61/drivers/video/console/fbcon.c
--- linux-2.5.61-fbdev/drivers/video/console/fbcon.c 2003-02-16 21:01:01.000000000 +0000
+++ linux-2.5.61/drivers/video/console/fbcon.c 2003-02-16 22:20:31.000000000 +0000
@@ -1879,8 +1879,8 @@
DPRINTK("resize now %ix%i\n", var.xres, var.yres);
var.activate = FB_ACTIVATE_NOW;
fb_set_var(&var, info);
- p->vrows = info->var.yres_virtual/fh;
}
+ p->vrows = info->var.yres_virtual/fh;
return 0;
}
@@ -1915,6 +1915,9 @@
}
if (info)
info->var.yoffset = p->yscroll = 0;
+
+ fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
+
switch (p->scrollmode & __SCROLL_YMASK) {
case __SCROLL_YWRAP:
scrollback_phys_max = p->vrows - vc->vc_rows;
@@ -1933,7 +1936,6 @@
info->currcon = unit;
- fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
update_var(unit, info);
fbcon_set_palette(vc, color_table);
|