|
From: Thomas W. <th...@wi...> - 2003-03-06 08:52:07
|
Antonino Daplas wrote:
> fbcon_resize() is not that broken, it's only trying to do what it's
> supposed to do. It is indeed limited because it is trying to outguess
> the low-level drivers on the best resolution for a window size.
>
> However, the brokenness is really on the driver side. They are unable
> to change the video mode unless they are supplied with the correct
> timing parameters where in fact they actually have the best knowledge on
> how to calculate them.
Yes, BUT ONLY IF the driver has enough parameters to calculate it. This
requires at least x and y dimension AND A CLOCK (or a vertical refresh
rate, which I would prefer).
The driver is supposed to handle the "var"s it's fed. If that var is
like the ones that result from the current fbcon_resize, namely with a
new x and y res, but no valid clock, how on earth should the driver do
this then? It receives a var which looks correct, and in fact, *could*
be correct sometimes:
Suppose we have another application, say DirectFB, feeding the low level
drivers with complete and correct "var"s.
In both cases we have valid x any y resultions, and a non-zero clock field.
Should we then let the driver read the x and y resolution and forget
about the rest of that var? I hardly think that's what the public var is
for. It could be reduced to a struct { USHORT xres, USHORT yres } then.
> So the question: Do we let fbcon spoonfeed the timings to fbdev, or do
> we let the drivers calculate it for themselves? I go for the latter, as
> fbcon really should not have any business with hardware.
What about the following solution: What if fbcon_resize sets the clock
in the var to 0? We could use this to force low level drivers to decide
on the clock for themselves. Otherwise, ie if the clock field is
non-zero, they are supposed to take it as the desired clock.
Thomas
--
Thomas Winischhofer
Vienna/Austria
mailto:th...@wi... http://www.winischhofer.net/
|
|
From: Geert U. <ge...@li...> - 2003-03-06 09:14:27
|
On Thu, 6 Mar 2003, Thomas Winischhofer wrote:
> Antonino Daplas wrote:
> > fbcon_resize() is not that broken, it's only trying to do what it's
> > supposed to do. It is indeed limited because it is trying to outguess
> > the low-level drivers on the best resolution for a window size.
> >
> > However, the brokenness is really on the driver side. They are unable
> > to change the video mode unless they are supplied with the correct
> > timing parameters where in fact they actually have the best knowledge on
> > how to calculate them.
>
> Yes, BUT ONLY IF the driver has enough parameters to calculate it. This
> requires at least x and y dimension AND A CLOCK (or a vertical refresh
> rate, which I would prefer).
>
> The driver is supposed to handle the "var"s it's fed. If that var is
> like the ones that result from the current fbcon_resize, namely with a
> new x and y res, but no valid clock, how on earth should the driver do
> this then? It receives a var which looks correct, and in fact, *could*
> be correct sometimes:
>
> Suppose we have another application, say DirectFB, feeding the low level
> drivers with complete and correct "var"s.
>
> In both cases we have valid x any y resultions, and a non-zero clock field.
>
> Should we then let the driver read the x and y resolution and forget
> about the rest of that var? I hardly think that's what the public var is
> for. It could be reduced to a struct { USHORT xres, USHORT yres } then.
>
> > So the question: Do we let fbcon spoonfeed the timings to fbdev, or do
> > we let the drivers calculate it for themselves? I go for the latter, as
> > fbcon really should not have any business with hardware.
>
> What about the following solution: What if fbcon_resize sets the clock
> in the var to 0? We could use this to force low level drivers to decide
> on the clock for themselves. Otherwise, ie if the clock field is
> non-zero, they are supposed to take it as the desired clock.
What if fbcon implements a text console _on top of_ fbdev? I.e. it uses the
current resolution?
If you use stty to change the number of cols/rows, or change the font, or use
fbset, your text console may end up being smaller or larger than the real
screen size, in which case margins are cleared, or columns/lines are lost.
(Optionally, we can center the text console if it's smaller than the real
screen size.)
IMHO this is the most orthogonal approach. Fbcon takes care of the text
console, fbdev takes care of the graphics hardware and the video mode. Both
parts do (try to) not influence each other.
Optionally, fbset can call stty to change the number of cols/rows, if the user
wants that.
What do you think?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: Antonino D. <ad...@po...> - 2003-03-06 09:56:49
|
On Thu, 2003-03-06 at 17:12, Geert Uytterhoeven wrote: > > What if fbcon implements a text console _on top of_ fbdev? I.e. it uses the > current resolution? > > If you use stty to change the number of cols/rows, or change the font, or use > fbset, your text console may end up being smaller or larger than the real > screen size, in which case margins are cleared, or columns/lines are lost. > (Optionally, we can center the text console if it's smaller than the real > screen size.) > Which is basically what stty does for the standard console (except that lines are not lost, but wrapped, and margins are not cleared). So, we need to reimplement the clipping code. > IMHO this is the most orthogonal approach. Fbcon takes care of the text > console, fbdev takes care of the graphics hardware and the video mode. Both > parts do (try to) not influence each other. > > Optionally, fbset can call stty to change the number of cols/rows, if the user > wants that. > Or even a simple script that basically does "fbset 1024x768-60 && stty cols 128 rows 48". Of course, adding this to fbset itself will make it transparent to the user. Sounds very logical to me :-) Tony |
|
From: Geert U. <ge...@li...> - 2003-03-06 10:16:49
|
On 6 Mar 2003, Antonino Daplas wrote:
> On Thu, 2003-03-06 at 17:12, Geert Uytterhoeven wrote:
> > What if fbcon implements a text console _on top of_ fbdev? I.e. it uses the
> > current resolution?
> >
> > If you use stty to change the number of cols/rows, or change the font, or use
> > fbset, your text console may end up being smaller or larger than the real
> > screen size, in which case margins are cleared, or columns/lines are lost.
> > (Optionally, we can center the text console if it's smaller than the real
> > screen size.)
> >
>
> Which is basically what stty does for the standard console (except that
> lines are not lost, but wrapped, and margins are not cleared).
>
> So, we need to reimplement the clipping code.
In fbcon, I hope?
> > IMHO this is the most orthogonal approach. Fbcon takes care of the text
> > console, fbdev takes care of the graphics hardware and the video mode. Both
> > parts do (try to) not influence each other.
> >
> > Optionally, fbset can call stty to change the number of cols/rows, if the user
> > wants that.
>
> Or even a simple script that basically does "fbset 1024x768-60 && stty
> cols 128 rows 48". Of course, adding this to fbset itself will make it
> transparent to the user.
>
> Sounds very logical to me :-)
Yep ;-)
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: Antonino D. <ad...@po...> - 2003-03-06 10:28:51
|
On Thu, 2003-03-06 at 18:14, Geert Uytterhoeven wrote: > On 6 Mar 2003, Antonino Daplas wrote: > > On Thu, 2003-03-06 at 17:12, Geert Uytterhoeven wrote: > > > What if fbcon implements a text console _on top of_ fbdev? I.e. it uses the > > > current resolution? > > > > > > If you use stty to change the number of cols/rows, or change the font, or use > > > fbset, your text console may end up being smaller or larger than the real > > > screen size, in which case margins are cleared, or columns/lines are lost. > > > (Optionally, we can center the text console if it's smaller than the real > > > screen size.) > > > > > > > Which is basically what stty does for the standard console (except that > > lines are not lost, but wrapped, and margins are not cleared). > > > > So, we need to reimplement the clipping code. > > In fbcon, I hope? > Yes, it's easier to do this in fbcon. Tony |
|
From: Antonino D. <ad...@po...> - 2003-03-06 09:25:01
|
On Thu, 2003-03-06 at 16:49, Thomas Winischhofer wrote:
> Antonino Daplas wrote:
> > fbcon_resize() is not that broken, it's only trying to do what it's
> > supposed to do. It is indeed limited because it is trying to outguess
> > the low-level drivers on the best resolution for a window size.
> >
> > However, the brokenness is really on the driver side. They are unable
> > to change the video mode unless they are supplied with the correct
> > timing parameters where in fact they actually have the best knowledge on
> > how to calculate them.
>
> Yes, BUT ONLY IF the driver has enough parameters to calculate it. This
> requires at least x and y dimension AND A CLOCK (or a vertical refresh
> rate, which I would prefer).
The VESA GTF can calculate timings using only xres, yres and any of the
three...
1. desired pixelclock
2. desired refresh
3. desired hsync
... all of which can be chosen by the driver, or extracted from the monitor
(ie. DDC or uploaded by the user).
For non-GTF compatible monitors, you can choose any of the standard timings
table.
>
> The driver is supposed to handle the "var"s it's fed. If that var is
> like the ones that result from the current fbcon_resize, namely with a
> new x and y res, but no valid clock, how on earth should the driver do
> this then? It receives a var which looks correct, and in fact, *could*
> be correct sometimes:
>
Mode checking is not simply looking at xres and yres, but also looking
at htotal, and vtotal to derive hsync, vsync and pixelclock. These are
then compared to the monitor/graphics card's capability. If any of the
values fall outside the limits then the mode is not valid. Otherwise,
the new mode should still produce a usable display, perhaps not the one
the user wants (ie refresh rate is lower). By this time though, the
user can freely use fbset to fine tune all the timings.
For fixed-frequency monitors or analog TV (where timings are critical),
you can use very strict operating limits (like vsync_min = 60 and
vsync_max = 60). With strict limits, it's unlikely that the new timings
will be valid, so the driver will always be forced to calculate a new
mode.
> Suppose we have another application, say DirectFB, feeding the low level
> drivers with complete and correct "var"s.
>
> In both cases we have valid x any y resultions, and a non-zero clock field.
>
> Should we then let the driver read the x and y resolution and forget
> about the rest of that var? I hardly think that's what the public var is
> for. It could be reduced to a struct { USHORT xres, USHORT yres } then.
>
> > So the question: Do we let fbcon spoonfeed the timings to fbdev, or do
> > we let the drivers calculate it for themselves? I go for the latter, as
> > fbcon really should not have any business with hardware.
>
> What about the following solution: What if fbcon_resize sets the clock
> in the var to 0? We could use this to force low level drivers to decide
> on the clock for themselves. Otherwise, ie if the clock field is
> non-zero, they are supposed to take it as the desired clock.
>
Yes, that's another solution. Just invalidate the timings and force the
driver to compute a modeline each time.
Tony
|
|
From: Thomas W. <th...@wi...> - 2003-03-06 09:46:37
|
Antonino Daplas wrote: > On Thu, 2003-03-06 at 16:49, Thomas Winischhofer wrote: >>>However, the brokenness is really on the driver side. They are unable >>>to change the video mode unless they are supplied with the correct >>>timing parameters where in fact they actually have the best knowledge on >>>how to calculate them. >> >>Yes, BUT ONLY IF the driver has enough parameters to calculate it. This >>requires at least x and y dimension AND A CLOCK (or a vertical refresh >>rate, which I would prefer). > > The VESA GTF can calculate timings using only xres, yres and any of the > three... > > 1. desired pixelclock > 2. desired refresh > 3. desired hsync > > ... all of which can be chosen by the driver, or extracted from the monitor > (ie. DDC or uploaded by the user). See? Need a clock! My word! :) > Mode checking is not simply looking at xres and yres, but also looking > at htotal, and vtotal to derive hsync, vsync and pixelclock. These are > then compared to the monitor/graphics card's capability. If any of the > values fall outside the limits then the mode is not valid. Otherwise, > the new mode should still produce a usable display, perhaps not the one > the user wants (ie refresh rate is lower). By this time though, the > user can freely use fbset to fine tune all the timings. Perhaps I have not made myself clear: I start with a default 800x600-60. Pixelclock in var is now X. fbcon_resize adapts the xres and yres, leaving the pixelclock alone. The driver sees upon the check_var call: xres, yres and X - the old pixelclock (which is non-zero). That pixelclock *COULD* be valid, but it COULD also be invalid! There is no way of distinguishing! >>What about the following solution: What if fbcon_resize sets the clock >>in the var to 0? We could use this to force low level drivers to decide >>on the clock for themselves. Otherwise, ie if the clock field is >>non-zero, they are supposed to take it as the desired clock. > > Yes, that's another solution. Just invalidate the timings and force the > driver to compute a modeline each time. I think Geert came up with a better solution in the meantime. But a general rule should be anyway: Whenever passing a var to the driver which only changed in a few fields and through this invalidated the timing settings, the caller should set everthing else to ZERO, in other words: invalidate it in a recognizable way. That's IMHO the only way the driver can distinguish between intended and unintended settings. Thomas -- Thomas Winischhofer Vienna/Austria mailto:th...@wi... http://www.winischhofer.net/ |
|
From: Antonino D. <ad...@po...> - 2003-03-06 10:04:17
|
On Thu, 2003-03-06 at 17:43, Thomas Winischhofer wrote: > > Mode checking is not simply looking at xres and yres, but also looking > > at htotal, and vtotal to derive hsync, vsync and pixelclock. These are > > then compared to the monitor/graphics card's capability. If any of the > > values fall outside the limits then the mode is not valid. Otherwise, > > the new mode should still produce a usable display, perhaps not the one > > the user wants (ie refresh rate is lower). By this time though, the > > user can freely use fbset to fine tune all the timings. > > Perhaps I have not made myself clear: > > I start with a default 800x600-60. Pixelclock in var is now X. > > fbcon_resize adapts the xres and yres, leaving the pixelclock alone. > > The driver sees upon the check_var call: xres, yres and X - the old > pixelclock (which is non-zero). > > That pixelclock *COULD* be valid, but it COULD also be invalid! There is > no way of distinguishing! > Yes, there is. Using the "stale" pixelclock, htotal and vtotal, calculate hsync and vsync. Compare this with your monitor's limit -- if any fall outside, the entire mode, pixelclock and all is not valid. (see fb_get_mode() and fb_validate_mode() in fbmon.c) And if you use very narrow vsync and hsync ranges, then the "stale" pixelclock will always most certainly be invalid. Tony |
|
From: Sven L. <lu...@dp...> - 2003-03-06 10:33:14
|
On Thu, Mar 06, 2003 at 06:05:37PM +0800, Antonino Daplas wrote: > Yes, there is. Using the "stale" pixelclock, htotal and vtotal, > calculate hsync and vsync. Compare this with your monitor's limit -- if > any fall outside, the entire mode, pixelclock and all is not valid. > > (see fb_get_mode() and fb_validate_mode() in fbmon.c) > > And if you use very narrow vsync and hsync ranges, then the "stale" > pixelclock will always most certainly be invalid. BTW, do we have an easy way of knowing if it is an LCD or analog monitor which is attached to the card (or even a TV) ? I think the radeonfb knows how to do this, not sure though. Friendly, Sven Luther |
|
From: Antonino D. <ad...@po...> - 2003-03-06 10:47:06
|
On Thu, 2003-03-06 at 18:31, Sven Luther wrote: > On Thu, Mar 06, 2003 at 06:05:37PM +0800, Antonino Daplas wrote: > > Yes, there is. Using the "stale" pixelclock, htotal and vtotal, > > calculate hsync and vsync. Compare this with your monitor's limit -- if > > any fall outside, the entire mode, pixelclock and all is not valid. > > > > (see fb_get_mode() and fb_validate_mode() in fbmon.c) > > > > And if you use very narrow vsync and hsync ranges, then the "stale" > > pixelclock will always most certainly be invalid. > > BTW, do we have an easy way of knowing if it is an LCD or analog monitor > which is attached to the card (or even a TV) ? I think the radeonfb > knows how to do this, not sure though. > There's an EDID parser in fbmon.c. I think it will work only for the PPC. This is currently used by rivafb and radeonfb. For the rest, either we implement DDC or just have something similar to XF86Config's HorizSync and VertRefresh. We can load this either as a kernel/module option or passed via ioctl/sysfs. I'm already doing this with the i810fb (as boot/module option), which greatly simplified mode switching. Tony |
|
From: Antonino D. <ad...@po...> - 2003-03-06 10:50:43
|
On Thu, 2003-03-06 at 18:48, Antonino Daplas wrote: > On Thu, 2003-03-06 at 18:31, Sven Luther wrote: > > On Thu, Mar 06, 2003 at 06:05:37PM +0800, Antonino Daplas wrote: > > > Yes, there is. Using the "stale" pixelclock, htotal and vtotal, > > > calculate hsync and vsync. Compare this with your monitor's limit -- if > > > any fall outside, the entire mode, pixelclock and all is not valid. > > > > > > (see fb_get_mode() and fb_validate_mode() in fbmon.c) > > > > > > And if you use very narrow vsync and hsync ranges, then the "stale" > > > pixelclock will always most certainly be invalid. > > > > BTW, do we have an easy way of knowing if it is an LCD or analog monitor > > which is attached to the card (or even a TV) ? I think the radeonfb > > knows how to do this, not sure though. > > > > There's an EDID parser in fbmon.c. I think it will work only for the > PPC. This is currently used by rivafb and radeonfb. For the rest, either > we implement DDC or just have something similar to XF86Config's > HorizSync and VertRefresh. We can load this either as a kernel/module > option or passed via ioctl/sysfs. > > I'm already doing this with the i810fb (as boot/module option), which > greatly simplified mode switching. > Oops, totally missed your question :-) But yes, I think the EDID block contains information about the monitor type, not sure thogh. Tony |
|
From: James S. <jsi...@in...> - 2003-03-06 15:28:12
|
> > (see fb_get_mode() and fb_validate_mode() in fbmon.c) > > > > And if you use very narrow vsync and hsync ranges, then the "stale" > > pixelclock will always most certainly be invalid. > > BTW, do we have an easy way of knowing if it is an LCD or analog monitor > which is attached to the card (or even a TV) ? I think the radeonfb > knows how to do this, not sure though. Not that I know of. |
|
From: Thomas W. <th...@wi...> - 2003-03-07 12:12:13
|
Alright: I tested the newest fbdev patch. 1) Boot logo support: Does not compile, misses a script "p??tologo" or anything like that. 2) Changed sisfb to accept practically any mode, but it now adapts to the next larger supported mode if no exact mode based on rows and cols is found. Previously, this adaption was limited to 16 pixels. stty does not work at all now, because fbcon's fbcon_resize() checks the returned var from fb_set_var if the mode is off more than one character in height and width - and returns EINVAL in this case. Since stty calles the console code twice if rows and cols are provided, this fails miserably, because the first attempt (which for example requests 800x768 if switching from 1024x768 to 800x600) fails. So I changed fbcon from if(err || width != var.xres/fw || height != var.yres/fh) to if(err) and now it works. However, there is still (at least) one problem within the console layer. With my patch, I can now have a console of for instance 128x20 characters, on a 1024x768 screen. Scrolling mostly works, but sometimes console seems to forget to pan. I can't reproduce this on purpose, but printing eg. a directory with ls works in 90% of the cases (=scrolls correctly), but prints text beyond the current amount of rows in the remaining 10% of the cases. If I press enter until the last line of the console is on the very bottom of the 1024x768 screen, then it remembers its amount of rows and pans correctly. For estethical reasons, I would also recommend changing the order or panning and character drawing. Now, the characters seem to be drawn first, and panning is done later. That causes some flickering sometimes, and with a console smaller than the screen resolution (eg. screen is 1024x768, console uses only 20 rows), text is shown below the 20th row for a fraction of a second before the panning is done. I will send the current sisfb code to James later today. (It also fixes some non-fbdev-related mode switching problems on some Asus laptops) Thomas -- Thomas Winischhofer Vienna/Austria mailto:th...@wi... http://www.winischhofer.net/ |
|
From: Geert U. <ge...@li...> - 2003-03-07 12:23:56
|
On Fri, 7 Mar 2003, Thomas Winischhofer wrote:
> Alright: I tested the newest fbdev patch.
>
> 1) Boot logo support: Does not compile, misses a script "p??tologo" or
> anything like that.
--- linux-2.5.64/scripts/Makefile Wed Mar 5 10:07:45 2003
+++ linux-logo-2.5.64/scripts/Makefile Wed Mar 5 13:19:54 2003
@@ -9,7 +9,7 @@
# conmakehash: Create arrays for initializing the kernel console tables
host-progs := fixdep split-include conmakehash docproc kallsyms modpost \
- mk_elfconfig
+ mk_elfconfig pnmtologo
build-targets := $(host-progs) empty.o
modpost-objs := modpost.o file2alias.o
--- linux-2.5.64/scripts/pnmtologo.c Thu Jan 1 01:00:00 1970
+++ linux-logo-2.5.64/scripts/pnmtologo.c Fri Jan 24 17:19:33 2003
@@ -0,0 +1,507 @@
+
+/*
+ * Convert a logo in ASCII PNM format to C source suitable for inclusion in
+ * the Linux kernel
+ *
+ * (C) Copyright 2001-2003 by Geert Uytterhoeven <ge...@li...>
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static const char *programname;
+static const char *filename;
+static const char *logoname = "linux_logo";
+static const char *outputname;
+static FILE *out;
+
+
+#define LINUX_LOGO_MONO 1 /* monochrome black/white */
+#define LINUX_LOGO_VGA16 2 /* 16 colors VGA text palette */
+#define LINUX_LOGO_CLUT224 3 /* 224 colors */
+#define LINUX_LOGO_GRAY256 4 /* 256 levels grayscale */
+
+static const char *logo_types[LINUX_LOGO_GRAY256+1] = {
+ [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO",
+ [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16",
+ [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224",
+ [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256"
+};
+
+#define MAX_LINUX_LOGO_COLORS 224
+
+struct color {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+};
+
+static const struct color clut_vga16[16] = {
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0xaa },
+ { 0x00, 0xaa, 0x00 },
+ { 0x00, 0xaa, 0xaa },
+ { 0xaa, 0x00, 0x00 },
+ { 0xaa, 0x00, 0xaa },
+ { 0xaa, 0x55, 0x00 },
+ { 0xaa, 0xaa, 0xaa },
+ { 0x55, 0x55, 0x55 },
+ { 0x55, 0x55, 0xff },
+ { 0x55, 0xff, 0x55 },
+ { 0x55, 0xff, 0xff },
+ { 0xff, 0x55, 0x55 },
+ { 0xff, 0x55, 0xff },
+ { 0xff, 0xff, 0x55 },
+ { 0xff, 0xff, 0xff },
+};
+
+
+static int logo_type = LINUX_LOGO_CLUT224;
+static unsigned int logo_width;
+static unsigned int logo_height;
+static struct color **logo_data;
+static struct color logo_clut[MAX_LINUX_LOGO_COLORS];
+static unsigned int logo_clutsize = 0;
+
+static void die(const char *fmt, ...)
+ __attribute__ ((noreturn)) __attribute ((format (printf, 1, 2)));
+static void usage(void) __attribute ((noreturn));
+
+
+static unsigned int get_number(FILE *fp)
+{
+ int c, val;
+
+ /* Skip leading whitespace */
+ do {
+ c = fgetc(fp);
+ if (c == EOF)
+ die("%s: end of file\n", filename);
+ if (c == '#') {
+ /* Ignore comments 'till end of line */
+ do {
+ c = fgetc(fp);
+ if (c == EOF)
+ die("%s: end of file\n", filename);
+ } while (c != '\n');
+ }
+ } while (isspace(c));
+
+ /* Parse decimal number */
+ val = 0;
+ while (isdigit(c)) {
+ val = 10*val+c-'0';
+ c = fgetc(fp);
+ if (c == EOF)
+ die("%s: end of file\n", filename);
+ }
+ return val;
+}
+
+static unsigned int get_number255(FILE *fp, unsigned int maxval)
+{
+ unsigned int val = get_number(fp);
+ return (255*val+maxval/2)/maxval;
+}
+
+static void read_image(void)
+{
+ FILE *fp;
+ int i, j, magic;
+ unsigned int maxval;
+
+ /* open image file */
+ fp = fopen(filename, "r");
+ if (!fp)
+ die("Cannot open file %s: %s\n", filename, strerror(errno));
+
+ /* check file type and read file header */
+ magic = fgetc(fp);
+ if (magic != 'P')
+ die("%s is not a PNM file\n", filename);
+ magic = fgetc(fp);
+ switch (magic) {
+ case '1':
+ case '2':
+ case '3':
+ /* Plain PBM/PGM/PPM */
+ break;
+
+ case '4':
+ case '5':
+ case '6':
+ /* Binary PBM/PGM/PPM */
+ die("%s: Binary PNM is not supported\n"
+ "Use pnmnoraw(1) to convert it to ASCII PNM\n", filename);
+
+ default:
+ die("%s is not a PNM file\n", filename);
+ }
+ logo_width = get_number(fp);
+ logo_height = get_number(fp);
+
+ /* allocate image data */
+ logo_data = (struct color **)malloc(logo_height*sizeof(struct color *));
+ if (!logo_data)
+ die("%s\n", strerror(errno));
+ for (i = 0; i < logo_height; i++) {
+ logo_data[i] = malloc(logo_width*sizeof(struct color));
+ if (!logo_data[i])
+ die("%s\n", strerror(errno));
+ }
+
+ /* read image data */
+ switch (magic) {
+ case '1':
+ /* Plain PBM */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ logo_data[i][j].red = logo_data[i][j].green =
+ logo_data[i][j].blue = 255*(1-get_number(fp));
+ break;
+
+ case '2':
+ /* Plain PGM */
+ maxval = get_number(fp);
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ logo_data[i][j].red = logo_data[i][j].green =
+ logo_data[i][j].blue = get_number255(fp, maxval);
+ break;
+
+ case '3':
+ /* Plain PPM */
+ maxval = get_number(fp);
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ logo_data[i][j].red = get_number255(fp, maxval);
+ logo_data[i][j].green = get_number255(fp, maxval);
+ logo_data[i][j].blue = get_number255(fp, maxval);
+ }
+ break;
+ }
+
+ /* close file */
+ fclose(fp);
+}
+
+static inline int is_black(struct color c)
+{
+ return c.red == 0 && c.green == 0 && c.blue == 0;
+}
+
+static inline int is_white(struct color c)
+{
+ return c.red == 255 && c.green == 255 && c.blue == 255;
+}
+
+static inline int is_gray(struct color c)
+{
+ return c.red == c.green && c.red == c.blue;
+}
+
+static inline int is_equal(struct color c1, struct color c2)
+{
+ return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue;
+}
+
+static void write_header(void)
+{
+ /* open logo file */
+ if (outputname) {
+ out = fopen(outputname, "w");
+ if (!out)
+ die("Cannot create file %s: %s\n", outputname, strerror(errno));
+ } else {
+ out = stdout;
+ }
+
+ fputs("/*\n", out);
+ fputs(" * DO NOT EDIT THIS FILE!\n", out);
+ fputs(" *\n", out);
+ fprintf(out, " * It was automatically generated from %s\n", filename);
+ fputs(" *\n", out);
+ fprintf(out, " * Linux logo %s\n", logoname);
+ fputs(" */\n\n", out);
+ fputs("#include <linux/linux_logo.h>\n\n", out);
+ fprintf(out, "static const unsigned char %s_data[] __initdata = {\n",
+ logoname);
+}
+
+static void write_footer(void)
+{
+ fputs("\n};\n\n", out);
+ fprintf(out, "const struct linux_logo %s __initdata = {\n", logoname);
+ fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
+ fprintf(out, " .width\t= %d,\n", logo_width);
+ fprintf(out, " .height\t= %d,\n", logo_height);
+ if (logo_type == LINUX_LOGO_CLUT224) {
+ fprintf(out, " .clutsize\t= %d,\n", logo_clutsize);
+ fprintf(out, " .clut\t= %s_clut,\n", logoname);
+ }
+ fprintf(out, " .data\t= %s_data\n", logoname);
+ fputs("};\n\n", out);
+
+ /* close logo file */
+ if (outputname)
+ fclose(out);
+}
+
+static int write_hex_cnt = 0;
+
+static void write_hex(unsigned char byte)
+{
+ if (write_hex_cnt % 12)
+ fprintf(out, ", 0x%02x", byte);
+ else if (write_hex_cnt)
+ fprintf(out, ",\n\t0x%02x", byte);
+ else
+ fprintf(out, "\t0x%02x", byte);
+ write_hex_cnt++;
+}
+
+static void write_logo_mono(void)
+{
+ int i, j;
+ unsigned char val, bit;
+
+ /* validate image */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))
+ die("Image must be monochrome\n");
+
+ /* write file header */
+ write_header();
+
+ /* write logo data */
+ for (i = 0; i < logo_height; i++) {
+ for (j = 0; j < logo_width;) {
+ for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1)
+ if (logo_data[i][j].red)
+ val |= bit;
+ write_hex(val);
+ }
+ }
+
+ /* write logo structure and file footer */
+ write_footer();
+}
+
+static void write_logo_vga16(void)
+{
+ int i, j, k;
+ unsigned char val;
+
+ /* validate image */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ for (k = 0; k < 16; k++)
+ if (is_equal(logo_data[i][j], clut_vga16[k]))
+ break;
+ if (k == 16)
+ die("Image must use the 16 console colors only\n"
+ "Use ppmquant(1) -map clut_vga16.ppm to reduce the number "
+ "of colors\n");
+ }
+
+ /* write file header */
+ write_header();
+
+ /* write logo data */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ for (k = 0; k < 16; k++)
+ if (is_equal(logo_data[i][j], clut_vga16[k]))
+ break;
+ val = k<<4;
+ if (++j < logo_width) {
+ for (k = 0; k < 16; k++)
+ if (is_equal(logo_data[i][j], clut_vga16[k]))
+ break;
+ val |= k;
+ }
+ write_hex(val);
+ }
+
+ /* write logo structure and file footer */
+ write_footer();
+}
+
+static void write_logo_clut224(void)
+{
+ int i, j, k;
+
+ /* validate image */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ for (k = 0; k < logo_clutsize; k++)
+ if (is_equal(logo_data[i][j], logo_clut[k]))
+ break;
+ if (k == logo_clutsize) {
+ if (logo_clutsize == MAX_LINUX_LOGO_COLORS)
+ die("Image has more than %d colors\n"
+ "Use ppmquant(1) to reduce the number of colors\n",
+ MAX_LINUX_LOGO_COLORS);
+ logo_clut[logo_clutsize++] = logo_data[i][j];
+ }
+ }
+
+ /* write file header */
+ write_header();
+
+ /* write logo data */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++) {
+ for (k = 0; k < logo_clutsize; k++)
+ if (is_equal(logo_data[i][j], logo_clut[k]))
+ break;
+ write_hex(k+32);
+ }
+ fputs("\n};\n\n", out);
+
+ /* write logo clut */
+ fprintf(out, "static const unsigned char %s_clut[] __initdata = {\n",
+ logoname);
+ write_hex_cnt = 0;
+ for (i = 0; i < logo_clutsize; i++) {
+ write_hex(logo_clut[i].red);
+ write_hex(logo_clut[i].green);
+ write_hex(logo_clut[i].blue);
+ }
+
+ /* write logo structure and file footer */
+ write_footer();
+}
+
+static void write_logo_gray256(void)
+{
+ int i, j;
+
+ /* validate image */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ if (!is_gray(logo_data[i][j]))
+ die("Image must be grayscale\n");
+
+ /* write file header */
+ write_header();
+
+ /* write logo data */
+ for (i = 0; i < logo_height; i++)
+ for (j = 0; j < logo_width; j++)
+ write_hex(logo_data[i][j].red);
+
+ /* write logo structure and file footer */
+ write_footer();
+}
+
+static void die(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ exit(1);
+}
+
+static void usage(void)
+{
+ die("\n"
+ "Usage: %s [options] <filename>\n"
+ "\n"
+ "Valid options:\n"
+ " -h : display this usage information\n"
+ " -n <name> : specify logo name (default: linux_logo)\n"
+ " -o <output> : output to file <output> instead of stdout\n"
+ " -t <type> : specify logo type, one of\n"
+ " mono : monochrome black/white\n"
+ " vga16 : 16 colors VGA text palette\n"
+ " clut224 : 224 colors (default)\n"
+ " gray256 : 256 levels grayscale\n"
+ "\n", programname);
+}
+
+int main(int argc, char *argv[])
+{
+ int opt;
+
+ programname = argv[0];
+
+ opterr = 0;
+ while (1) {
+ opt = getopt(argc, argv, "hn:o:t:");
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'h':
+ usage();
+ break;
+
+ case 'n':
+ logoname = optarg;
+ break;
+
+ case 'o':
+ outputname = optarg;
+ break;
+
+ case 't':
+ if (!strcmp(optarg, "mono"))
+ logo_type = LINUX_LOGO_MONO;
+ else if (!strcmp(optarg, "vga16"))
+ logo_type = LINUX_LOGO_VGA16;
+ else if (!strcmp(optarg, "clut224"))
+ logo_type = LINUX_LOGO_CLUT224;
+ else if (!strcmp(optarg, "gray256"))
+ logo_type = LINUX_LOGO_GRAY256;
+ else
+ usage();
+ break;
+
+ default:
+ usage();
+ break;
+ }
+ }
+ if (optind != argc-1)
+ usage();
+
+ filename = argv[optind];
+
+ read_image();
+ switch (logo_type) {
+ case LINUX_LOGO_MONO:
+ write_logo_mono();
+ break;
+
+ case LINUX_LOGO_VGA16:
+ write_logo_vga16();
+ break;
+
+ case LINUX_LOGO_CLUT224:
+ write_logo_clut224();
+ break;
+
+ case LINUX_LOGO_GRAY256:
+ write_logo_gray256();
+ break;
+ }
+ exit(0);
+}
+
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@li...
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
|
|
From: James S. <jsi...@in...> - 2003-03-07 17:29:11
|
> On Fri, 7 Mar 2003, Thomas Winischhofer wrote: > > Alright: I tested the newest fbdev patch. > > > > 1) Boot logo support: Does not compile, misses a script "p??tologo" or > > anything like that. ??? That is getting annoying. Another patch is coming very soon. P.S Almost done with porting matroxfb. Still some more to go tho. |
|
From: Antonino D. <ad...@po...> - 2003-03-07 14:32:06
|
On Fri, 2003-03-07 at 20:08, Thomas Winischhofer wrote:
>
>
> However, there is still (at least) one problem within the console layer.
>
> With my patch, I can now have a console of for instance 128x20
> characters, on a 1024x768 screen. Scrolling mostly works, but sometimes
> console seems to forget to pan. I can't reproduce this on purpose, but
> printing eg. a directory with ls works in 90% of the cases (=scrolls
> correctly), but prints text beyond the current amount of rows in the
> remaining 10% of the cases. If I press enter until the last line of the
> console is on the very bottom of the 1024x768 screen, then it remembers
> its amount of rows and pans correctly.
>
Try this patch. The fbcon_resize test is more liberal and it now correctly
updates p->vrows and scroll_phys_max (for panning glitches).
Tony
diff -Naur linux-2.5.64-fbdev/drivers/video/console/fbcon.c linux-2.5.64/drivers/video/console/fbcon.c
--- linux-2.5.64-fbdev/drivers/video/console/fbcon.c 2003-03-06 01:29:29.000000000 +0000
+++ linux-2.5.64/drivers/video/console/fbcon.c 2003-03-07 13:54:04.000000000 +0000
@@ -580,8 +580,8 @@
struct fb_info *info = p->fb_info;
unsigned int cw = vc->vc_font.width;
unsigned int ch = vc->vc_font.height;
- unsigned int rw = info->var.xres % cw;
- unsigned int bh = info->var.yres % ch;
+ unsigned int rw = info->var.xres - (cw * vc->vc_cols);
+ unsigned int bh = info->var.yres - (ch * vc->vc_rows);
unsigned int rs = info->var.xres - rw;
unsigned int bs = info->var.yres - bh;
struct fb_fillrect region;
@@ -1815,14 +1815,14 @@
(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)
+ 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;
}
+ p->vrows = info->var.yres_virtual/fh;
return 0;
}
@@ -1857,6 +1857,7 @@
}
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;
@@ -1875,7 +1876,6 @@
info->currcon = unit;
- fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
update_var(unit, info);
fbcon_set_palette(vc, color_table);
|
|
From: Thomas W. <th...@wi...> - 2003-03-07 15:23:06
Attachments:
fbcon_patch
|
This works - perfectly, I must say.
However, the scrolling problem is still here, but I think I know the
reason for this:
Imagine a console of 120x40 (using the std 8x16 font), on a screen of
1024x768, using ypanning.
This uses only 40*16=640 pixels vertically instead of the 768 available.
The problem is the y panning, and is kind of both console's as well as
the driver's fault:
When the y panning area reaches its end, it's supposed to copy the
screen to the beginning of this area and pan to position 0.
However, fbcon calculates p->vrows by info->var.yres_virtual / fontheight.
This disregards the fact that the visible screen area is actually larger
than the area console is supposed to use.
Therefore, the calculation of vrows has to take the difference between
these two into account.
The attached patch fixes this for me but I have no idea if I cought all
possible itches. It will no apply cleanly, because I had made changes to
fbcon.c before making a backup copy - but it sure illustrates the problem.
Why you used info->var.yres_virtual (and not the adapted
var.yres_virtual) in fbcon_resize() is beyond me, BTW.
Thomas
Antonino Daplas wrote:
> On Fri, 2003-03-07 at 20:08, Thomas Winischhofer wrote:
>
>>
>>However, there is still (at least) one problem within the console layer.
>>
>>With my patch, I can now have a console of for instance 128x20
>>characters, on a 1024x768 screen. Scrolling mostly works, but sometimes
>>console seems to forget to pan. I can't reproduce this on purpose, but
>>printing eg. a directory with ls works in 90% of the cases (=scrolls
>>correctly), but prints text beyond the current amount of rows in the
>>remaining 10% of the cases. If I press enter until the last line of the
>>console is on the very bottom of the 1024x768 screen, then it remembers
>>its amount of rows and pans correctly.
>>
>
>
> Try this patch. The fbcon_resize test is more liberal and it now correctly
> updates p->vrows and scroll_phys_max (for panning glitches).
>
> Tony
>
>
> diff -Naur linux-2.5.64-fbdev/drivers/video/console/fbcon.c linux-2.5.64/drivers/video/console/fbcon.c
> --- linux-2.5.64-fbdev/drivers/video/console/fbcon.c 2003-03-06 01:29:29.000000000 +0000
> +++ linux-2.5.64/drivers/video/console/fbcon.c 2003-03-07 13:54:04.000000000 +0000
> @@ -580,8 +580,8 @@
> struct fb_info *info = p->fb_info;
> unsigned int cw = vc->vc_font.width;
> unsigned int ch = vc->vc_font.height;
> - unsigned int rw = info->var.xres % cw;
> - unsigned int bh = info->var.yres % ch;
> + unsigned int rw = info->var.xres - (cw * vc->vc_cols);
> + unsigned int bh = info->var.yres - (ch * vc->vc_rows);
> unsigned int rs = info->var.xres - rw;
> unsigned int bs = info->var.yres - bh;
> struct fb_fillrect region;
> @@ -1815,14 +1815,14 @@
> (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)
> + 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;
> }
> + p->vrows = info->var.yres_virtual/fh;
> return 0;
> }
>
> @@ -1857,6 +1857,7 @@
> }
> 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;
> @@ -1875,7 +1876,6 @@
>
> info->currcon = unit;
>
> - fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
> update_var(unit, info);
> fbcon_set_palette(vc, color_table);
>
>
>
--
Thomas Winischhofer
Vienna/Austria
mailto:th...@wi... http://www.winischhofer.net/
|
|
From: Antonino D. <ad...@po...> - 2003-03-07 16:18:59
|
On Fri, 2003-03-07 at 23:19, Thomas Winischhofer wrote: > > This works - perfectly, I must say. > > However, the scrolling problem is still here, but I think I know the > reason for this: > > Imagine a console of 120x40 (using the std 8x16 font), on a screen of > 1024x768, using ypanning. > > This uses only 40*16=640 pixels vertically instead of the 768 available. > > The problem is the y panning, and is kind of both console's as well as > the driver's fault: > > When the y panning area reaches its end, it's supposed to copy the > screen to the beginning of this area and pan to position 0. > > However, fbcon calculates p->vrows by info->var.yres_virtual / fontheight. > > This disregards the fact that the visible screen area is actually larger > than the area console is supposed to use. > > Therefore, the calculation of vrows has to take the difference between > these two into account. > > The attached patch fixes this for me but I have no idea if I cought all > possible itches. It will no apply cleanly, because I had made changes to > fbcon.c before making a backup copy - but it sure illustrates the problem. > Right, fbcon never dealt with margins greater than a character width/height before :-). I think your patch will do the Right Thing. As for the one you commented out as INCOMPLETE, my guess is it won't matter since that particular section of code is called only during initialization. An fbcon_switch() will be called later on, I think. > Why you used info->var.yres_virtual (and not the adapted > var.yres_virtual) in fbcon_resize() is beyond me, BTW. > Because info->var will _always_ contain the correct var, so we trust that above all. Tony |
|
From: James S. <jsi...@in...> - 2003-03-07 17:44:32
|
> Therefore, the calculation of vrows has to take the difference between > these two into account. > > The attached patch fixes this for me but I have no idea if I cought all > possible itches. It will no apply cleanly, because I had made changes to > fbcon.c before making a backup copy - but it sure illustrates the problem. > > Why you used info->var.yres_virtual (and not the adapted > var.yres_virtual) in fbcon_resize() is beyond me, BTW. My mistake. I applied your patch. |
|
From: Thomas W. <th...@wi...> - 2003-03-07 17:52:52
|
James Simmons wrote: >>Therefore, the calculation of vrows has to take the difference between >>these two into account. >> >>The attached patch fixes this for me but I have no idea if I cought all >>possible itches. It will no apply cleanly, because I had made changes to >>fbcon.c before making a backup copy - but it sure illustrates the problem. >> >>Why you used info->var.yres_virtual (and not the adapted >>var.yres_virtual) in fbcon_resize() is beyond me, BTW. > > > My mistake. I applied your patch. Reading first Toni's post (because it came one minute earlier) and now yours, what's true resp. correct now? Thomas PS: James, are you "entitled" to add maintainers to the MAINTAINERS file? I have actually been the maintainer of sisfb since a year back, so I think this should perhaps be mentioned..? SIS FRAMEBUFFER DRIVER P: Thomas Winischhofer M: th...@wi... W: http://www.winischhofer.net/linuxsisvga.shtml S: Maintained -- Thomas Winischhofer Vienna/Austria mailto:th...@wi... http://www.winischhofer.net/ |
|
From: James S. <jsi...@in...> - 2003-03-11 16:24:30
|
> PS: James, are you "entitled" to add maintainers to the MAINTAINERS > file? I have actually been the maintainer of sisfb since a year back, so > I think this should perhaps be mentioned..? > > SIS FRAMEBUFFER DRIVER > P: Thomas Winischhofer > M: th...@wi... > W: http://www.winischhofer.net/linuxsisvga.shtml > S: Maintained Added. |
|
From: James S. <jsi...@in...> - 2003-03-07 17:45:24
|
> Try this patch. The fbcon_resize test is more liberal and it now correctly > updates p->vrows and scroll_phys_max (for panning glitches). Applied. |
|
From: Antonino D. <ad...@po...> - 2003-03-07 20:11:56
|
On Fri, 2003-03-07 at 23:19, Thomas Winischhofer wrote:
>
> This works - perfectly, I must say.
>
> However, the scrolling problem is still here, but I think I know the
> reason for this:
>
> Imagine a console of 120x40 (using the std 8x16 font), on a screen of
> 1024x768, using ypanning.
>
> This uses only 40*16=640 pixels vertically instead of the 768 available.
>
> The problem is the y panning, and is kind of both console's as well as
> the driver's fault:
>
> When the y panning area reaches its end, it's supposed to copy the
> screen to the beginning of this area and pan to position 0.
>
> However, fbcon calculates p->vrows by info->var.yres_virtual / fontheight.
>
> This disregards the fact that the visible screen area is actually larger
> than the area console is supposed to use.
I've tested where the virtual window size is much smaller than the
physical dimensions, and I do see the glitch you mentioned. But it's
mainly due to clear_margins(). clear_margins always erases a constant
amount (physical_height - actual height). So if you happen to pan just
enough that there's not enough screen estate left, it will attempt to
clear past yres_virtual. Bad for drivers that do not implement
clipping. Perhaps, block moves are involved here also, I'm not sure.
So your patch has the correct idea, but here's a simpler one. It just
reserves enough screen estate equal to difference of physical height and
virtual height. I've tested this even using stty cols 2, and it works
okay.
NOTE: Since we need var->yres, this time, we need to refer to info->var
instead of the adjusted var.
BTW: I've tested moving clear_margins before panning, it still doesn't
remove the onrushing text past the virtual window height. This would
seem to need clipping to remove that eyesore.
If the patch doesn't apply cleanly, it should be easy enough to do so
manually.
Tony
diff -Naur linux-2.5.64-fbdev/drivers/video/console/fbcon.c linux-2.5.64/drivers/video/console/fbcon.c
--- linux-2.5.64-fbdev/drivers/video/console/fbcon.c 2003-03-07 15:03:06.000000000 +0000
+++ linux-2.5.64/drivers/video/console/fbcon.c 2003-03-07 20:06:39.000000000 +0000
@@ -1044,6 +1044,7 @@
vc->vc_rows = nr_rows;
}
p->vrows = info->var.yres_virtual / vc->vc_font.height;
+ p->vrows -= info->var.yres - vc->vc_rows;
if ((info->var.yres % vc->vc_font.height) &&
(info->var.yres_virtual % vc->vc_font.height <
info->var.yres % vc->vc_font.height))
@@ -1821,8 +1822,9 @@
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;
+ p->vrows -= (info->var.yres + (fh - 1))/fh - vc->vc_rows;
return 0;
}
@@ -2094,6 +2096,7 @@
/* reset wrap/pan */
info->var.xoffset = info->var.yoffset = p->yscroll = 0;
p->vrows = info->var.yres_virtual / h;
+ p->vrows -= info->var.yres/h - vc->vc_rows;
if ((info->var.yres % h)
&& (info->var.yres_virtual % h < info->var.yres % h))
p->vrows--;
|
|
From: Thomas W. <th...@wi...> - 2003-03-07 20:51:30
|
Antonino Daplas wrote: > On Fri, 2003-03-07 at 23:19, Thomas Winischhofer wrote: > >>This works - perfectly, I must say. >> >>However, the scrolling problem is still here, but I think I know the >>reason for this: >> >>Imagine a console of 120x40 (using the std 8x16 font), on a screen of >>1024x768, using ypanning. >> >>This uses only 40*16=640 pixels vertically instead of the 768 available. >> >>The problem is the y panning, and is kind of both console's as well as >>the driver's fault: >> >>When the y panning area reaches its end, it's supposed to copy the >>screen to the beginning of this area and pan to position 0. >> >>However, fbcon calculates p->vrows by info->var.yres_virtual / fontheight. >> >>This disregards the fact that the visible screen area is actually larger >>than the area console is supposed to use. > > > I've tested where the virtual window size is much smaller than the > physical dimensions, and I do see the glitch you mentioned. But it's > mainly due to clear_margins(). clear_margins always erases a constant > amount (physical_height - actual height). So if you happen to pan just > enough that there's not enough screen estate left, it will attempt to > clear past yres_virtual. Bad for drivers that do not implement > clipping. Perhaps, block moves are involved here also, I'm not sure. 1) Sisfb does no clipping, but there is plenty of video RAM past the virtual area. 2) I don't think we are talking about the same thing. Clear_margins() (which I haven't looked at, I confess) assumingly ... erm.. clears the margins. But why is it involved in scrolling any panning? > So your patch has the correct idea, but here's a simpler one. It just > reserves enough screen estate equal to difference of physical height and > virtual height. I've tested this even using stty cols 2, and it works > okay. I don't see why this is simpler, but I do see it wastes a lot of screen space :) BTW: p->vrows = info->var.yres_virtual / vc->vc_font.height; + p->vrows -= info->var.yres - vc->vc_rows; Look: rows = 40 yres = 768 yres_v = 2048 font height = 16 vrows = 2048 / 16 = 128 (character unit) 128 - (768 - 40) is negative... Personally, I'd go with my first patch from earlier today. I tested this intensively in the meantime, and it Simpy Works(tm). > NOTE: Since we need var->yres, this time, we need to refer to info->var > instead of the adjusted var. > > BTW: I've tested moving clear_margins before panning, it still doesn't > remove the onrushing text past the virtual window height. This would > seem to need clipping to remove that eyesore. Honestly, I don't consider this important... But I thought you'd simply exchange the order of calling pan_var and drawing the characters... (which IMHO would be the correct order, logically speaking) Thomas -- Thomas Winischhofer Vienna/Austria mailto:th...@wi... *** http://www.winischhofer.net |
|
From: Antonino D. <ad...@po...> - 2003-03-08 00:57:51
|
On Sat, 2003-03-08 at 04:51, Thomas Winischhofer wrote:
> I don't see why this is simpler, but I do see it wastes a lot of screen
> space :)
>
yep, it'a a typo.
Tony
diff -Naur linux-2.5.64-fbdev/drivers/video/console/fbcon.c linux-2.5.64/drivers/video/console/fbcon.c
--- linux-2.5.64-fbdev/drivers/video/console/fbcon.c 2003-03-07 15:03:06.000000000 +0000
+++ linux-2.5.64/drivers/video/console/fbcon.c 2003-03-08 00:49:09.000000000 +0000
@@ -1044,6 +1044,7 @@
vc->vc_rows = nr_rows;
}
p->vrows = info->var.yres_virtual / vc->vc_font.height;
+ p->vrows -= info->var.yres/h - vc->vc_rows;
if ((info->var.yres % vc->vc_font.height) &&
(info->var.yres_virtual % vc->vc_font.height <
info->var.yres % vc->vc_font.height))
@@ -1821,8 +1822,9 @@
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;
+ p->vrows -= (info->var.yres + (fh - 1))/fh - vc->vc_rows;
return 0;
}
@@ -2094,6 +2096,7 @@
/* reset wrap/pan */
info->var.xoffset = info->var.yoffset = p->yscroll = 0;
p->vrows = info->var.yres_virtual / h;
+ p->vrows -= info->var.yres/h - vc->vc_rows;
if ((info->var.yres % h)
&& (info->var.yres_virtual % h < info->var.yres % h))
p->vrows--;
|