linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* clipping
@ 2002-12-29 21:21 Geert Uytterhoeven
  2003-01-03 10:36 ` clipping Antonino Daplas
  0 siblings, 1 reply; 17+ messages in thread
From: Geert Uytterhoeven @ 2002-12-29 21:21 UTC (permalink / raw)
  To: Linux Frame Buffer Device Development


cfb_imageblit() takes care of clipping, but forgets to update fb_image.data if
fb_image.d[xy] was changed.

BTW, do we really need clipping in fb_ops.fb_{fillrect,copyarea,imageblit}()?

If these calls are accessible from user space through ioctl() (if anyone really
wants to do that?!?), I guess the answer is yes. For calls from kernel space,
I'd say it's not necessary since calling them with out-of-range parameters is a
bug anyway.
So we could move the clipping to the generic ioctl() handling in fbmem.c, if we
ever want to provide that functionality. Or is there a too high speed penalty
for graphics chips that do implement clipping in hardware?

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

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



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2002-12-29 21:21 clipping Geert Uytterhoeven
@ 2003-01-03 10:36 ` Antonino Daplas
  2003-01-07 21:08   ` clipping Geert Uytterhoeven
  0 siblings, 1 reply; 17+ messages in thread
From: Antonino Daplas @ 2003-01-03 10:36 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Linux Frame Buffer Device Development

On Mon, 2002-12-30 at 05:21, Geert Uytterhoeven wrote:
> 
> cfb_imageblit() takes care of clipping, but forgets to update fb_image.data if
> fb_image.d[xy] was changed.
> 
> BTW, do we really need clipping in fb_ops.fb_{fillrect,copyarea,imageblit}()?
Personally, I don't think we need clipping.  I tried removing it before
(circa linux-2.5.30+), but the console segfaults whenever I decrease
var->yres_virtual.  I haven't tried this again with the newest
framebuffer framework though.

Tony





-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-03 10:36 ` clipping Antonino Daplas
@ 2003-01-07 21:08   ` Geert Uytterhoeven
  2003-01-07 22:13     ` clipping James Simmons
  0 siblings, 1 reply; 17+ messages in thread
From: Geert Uytterhoeven @ 2003-01-07 21:08 UTC (permalink / raw)
  To: Antonino Daplas; +Cc: Linux Frame Buffer Device Development

On 3 Jan 2003, Antonino Daplas wrote:
> On Mon, 2002-12-30 at 05:21, Geert Uytterhoeven wrote:
> > cfb_imageblit() takes care of clipping, but forgets to update fb_image.data if
> > fb_image.d[xy] was changed.
> > 
> > BTW, do we really need clipping in fb_ops.fb_{fillrect,copyarea,imageblit}()?
> Personally, I don't think we need clipping.  I tried removing it before
> (circa linux-2.5.30+), but the console segfaults whenever I decrease
> var->yres_virtual.  I haven't tried this again with the newest
> framebuffer framework though.

Any definitive answer on this?

What happens if you resize the VT to such a large size that columns*fontwidth >
xres_virtual or rows*fontheight > yres_virtual? I guess clipping prevents a
crash there?

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

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



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-07 21:08   ` clipping Geert Uytterhoeven
@ 2003-01-07 22:13     ` James Simmons
  2003-01-08  9:54       ` clipping Geert Uytterhoeven
  0 siblings, 1 reply; 17+ messages in thread
From: James Simmons @ 2003-01-07 22:13 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Antonino Daplas, Linux Frame Buffer Device Development


> > > BTW, do we really need clipping in fb_ops.fb_{fillrect,copyarea,imageblit}()?
> > Personally, I don't think we need clipping.  I tried removing it before
> > (circa linux-2.5.30+), but the console segfaults whenever I decrease
> > var->yres_virtual.  I haven't tried this again with the newest
> > framebuffer framework though.
> 
> Any definitive answer on this?
> 
> What happens if you resize the VT to such a large size that columns*fontwidth >
> xres_virtual or rows*fontheight > yres_virtual? I guess clipping prevents a
> crash there?

Correct. Actually fbcon_resize checks to make sure the user doesn't do 
something stupid like this. So we might not needed. Hm.




-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-07 22:13     ` clipping James Simmons
@ 2003-01-08  9:54       ` Geert Uytterhoeven
  2003-01-08 16:26         ` clipping Antonino Daplas
  2003-01-09 21:09         ` clipping James Simmons
  0 siblings, 2 replies; 17+ messages in thread
From: Geert Uytterhoeven @ 2003-01-08  9:54 UTC (permalink / raw)
  To: James Simmons; +Cc: Antonino Daplas, Linux Frame Buffer Device Development

On Tue, 7 Jan 2003, James Simmons wrote:
> > > > BTW, do we really need clipping in fb_ops.fb_{fillrect,copyarea,imageblit}()?
> > > Personally, I don't think we need clipping.  I tried removing it before
> > > (circa linux-2.5.30+), but the console segfaults whenever I decrease
> > > var->yres_virtual.  I haven't tried this again with the newest
> > > framebuffer framework though.
> > 
> > Any definitive answer on this?
> > 
> > What happens if you resize the VT to such a large size that columns*fontwidth >
> > xres_virtual or rows*fontheight > yres_virtual? I guess clipping prevents a
> > crash there?
> 
> Correct. Actually fbcon_resize checks to make sure the user doesn't do 
> something stupid like this. So we might not needed. Hm.

And what if you use fbset to reduce the resolution below what's needed to
accomodate the current console size?

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

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



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-08  9:54       ` clipping Geert Uytterhoeven
@ 2003-01-08 16:26         ` Antonino Daplas
  2003-01-09 21:24           ` clipping James Simmons
  2003-01-09 21:09         ` clipping James Simmons
  1 sibling, 1 reply; 17+ messages in thread
From: Antonino Daplas @ 2003-01-08 16:26 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: James Simmons, Linux Frame Buffer Device Development

On Wed, 2003-01-08 at 17:54, Geert Uytterhoeven wrote:
> On Tue, 7 Jan 2003, James Simmons wrote:
> > > > > BTW, do we really need clipping in fb_ops.fb_{fillrect,copyarea,imageblit}()?
> > > > Personally, I don't think we need clipping.  I tried removing it before
> > > > (circa linux-2.5.30+), but the console segfaults whenever I decrease
> > > > var->yres_virtual.  I haven't tried this again with the newest
> > > > framebuffer framework though.
> > > 
> > > Any definitive answer on this?
> > > 
> > > What happens if you resize the VT to such a large size that columns*fontwidth >
> > > xres_virtual or rows*fontheight > yres_virtual? I guess clipping prevents a
> > > crash there?
> > 
> > Correct. Actually fbcon_resize checks to make sure the user doesn't do 
> > something stupid like this. So we might not needed. Hm.
> 
> And what if you use fbset to reduce the resolution below what's needed to
> accomodate the current console size?
> 
Then we do need clipping :-)  I think that happened to me, I just did
not recognize it.  I accidentally lowered the window size using fbset,
and suddenly I had a console where the tail end of each row of text
wraps to the next row.  I wasn't using cfb_imageblit then so this was
done by hardware.  If I was using cfb_imageblit, this will be clipped.

So, I think we do need clipping, but instead of implementing it in
fb_{fillrect,copyarea,imageblit}, we implement it higher up, in
accel_putcs() and family.  This should also protect drivers using 
hardware-based drawing. 

So perhaps, a function something like this:

void fb_clip(struct fb_fillrect *region, struct fb_fillrect *clip);

This should not be difficult to implement, and I'll code it if everyone
agrees.

The other option (which I don't like) is just to check the passed
fb_var_screeninfo in the put_var ioctl against the current console
window size.  But this is not foolproof as we will not be sure of the
resulting window size _after_ the fb_set_var() call.

Tony




-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-08  9:54       ` clipping Geert Uytterhoeven
  2003-01-08 16:26         ` clipping Antonino Daplas
@ 2003-01-09 21:09         ` James Simmons
  1 sibling, 0 replies; 17+ messages in thread
From: James Simmons @ 2003-01-09 21:09 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Antonino Daplas, Linux Frame Buffer Device Development


> > > What happens if you resize the VT to such a large size that columns*fontwidth >
> > > xres_virtual or rows*fontheight > yres_virtual? I guess clipping prevents a
> > > crash there?
> > 
> > Correct. Actually fbcon_resize checks to make sure the user doesn't do 
> > something stupid like this. So we might not needed. Hm.
> 
> And what if you use fbset to reduce the resolution below what's needed to
> accomodate the current console size?

I haven't fixed that issue yet. One the last close of /dev/fb the tty 
should be set back to its original state before /dev/fb was first open.



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-08 16:26         ` clipping Antonino Daplas
@ 2003-01-09 21:24           ` James Simmons
  2003-01-09 21:46             ` clipping Geert Uytterhoeven
  2003-01-10 10:27             ` clipping Antonino Daplas
  0 siblings, 2 replies; 17+ messages in thread
From: James Simmons @ 2003-01-09 21:24 UTC (permalink / raw)
  To: Antonino Daplas; +Cc: Geert Uytterhoeven, Linux Frame Buffer Device Development


> So perhaps, a function something like this:
> 
> void fb_clip(struct fb_fillrect *region, struct fb_fillrect *clip);
> 
> This should not be difficult to implement, and I'll code it if everyone
> agrees.
 
I thought about this. Originally I did have this function but removed it.
WHat do you think Geert?

> The other option (which I don't like) is just to check the passed
> fb_var_screeninfo in the put_var ioctl against the current console
> window size.  But this is not foolproof as we will not be sure of the
> resulting window size _after_ the fb_set_var() call.

Yuck!!! The other way is better.



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-09 21:24           ` clipping James Simmons
@ 2003-01-09 21:46             ` Geert Uytterhoeven
  2003-01-10 13:55               ` [RESEND] clipping Antonino Daplas
  2003-01-10 19:39               ` clipping James Simmons
  2003-01-10 10:27             ` clipping Antonino Daplas
  1 sibling, 2 replies; 17+ messages in thread
From: Geert Uytterhoeven @ 2003-01-09 21:46 UTC (permalink / raw)
  To: James Simmons; +Cc: Antonino Daplas, Linux Frame Buffer Device Development

On Thu, 9 Jan 2003, James Simmons wrote:
> > So perhaps, a function something like this:
> > 
> > void fb_clip(struct fb_fillrect *region, struct fb_fillrect *clip);
> > 
> > This should not be difficult to implement, and I'll code it if everyone
> > agrees.
>  
> I thought about this. Originally I did have this function but removed it.
> WHat do you think Geert?

Yes, that's OK.

But I was most concerned about fb_ops.fb_imageblit(), since clipping impacts
fb_image.data as well. IIRC, all (most?) current clipping implementations
modify fb_image.{dx,dy,width,height} only, without updating fb_image.data.

> > The other option (which I don't like) is just to check the passed
> > fb_var_screeninfo in the put_var ioctl against the current console
> > window size.  But this is not foolproof as we will not be sure of the
> > resulting window size _after_ the fb_set_var() call.
> 
> Yuck!!! The other way is better.

Well, in between the calls to fb_ops.fb_check_var() and fb_ops.set_par() you
can still perform that check. But it's indeed ugly.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

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



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-09 21:24           ` clipping James Simmons
  2003-01-09 21:46             ` clipping Geert Uytterhoeven
@ 2003-01-10 10:27             ` Antonino Daplas
  2003-01-10 10:45               ` clipping Geert Uytterhoeven
  1 sibling, 1 reply; 17+ messages in thread
From: Antonino Daplas @ 2003-01-10 10:27 UTC (permalink / raw)
  To: James Simmons; +Cc: Geert Uytterhoeven, Linux Frame Buffer Device Development

On Fri, 2003-01-10 at 05:24, James Simmons wrote:
> 
> > So perhaps, a function something like this:
> > 
> > void fb_clip(struct fb_fillrect *region, struct fb_fillrect *clip);
> > 
> > This should not be difficult to implement, and I'll code it if everyone
> > agrees.
>  
> I thought about this. Originally I did have this function but removed it.
> WHat do you think Geert?
> 
> > The other option (which I don't like) is just to check the passed
> > fb_var_screeninfo in the put_var ioctl against the current console
> > window size.  But this is not foolproof as we will not be sure of the
> > resulting window size _after_ the fb_set_var() call.
> 
> Yuck!!! The other way is better.
> 

Yes, I thought so too :-).

I think one scenario why we need clipping is changing bits_per_pixel,
ie, changing from 8->16 will drop your vyres by half and it's difficult
to determine this unless you do another check before the set_par(), as
Geert mentioned.  Worse still, there is little if no valid memory past
vyres but the console thinks there is.  That's where you will get a
segfault.

Whereas explicitly doing fbset -vyres 768 will not cause a segfault,
because you still have valid framebuffer memory past y=768.

Tony



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-10 10:27             ` clipping Antonino Daplas
@ 2003-01-10 10:45               ` Geert Uytterhoeven
  0 siblings, 0 replies; 17+ messages in thread
From: Geert Uytterhoeven @ 2003-01-10 10:45 UTC (permalink / raw)
  To: Antonino Daplas; +Cc: James Simmons, Linux Frame Buffer Device Development

On 10 Jan 2003, Antonino Daplas wrote:
> On Fri, 2003-01-10 at 05:24, James Simmons wrote:
> > > So perhaps, a function something like this:
> > > 
> > > void fb_clip(struct fb_fillrect *region, struct fb_fillrect *clip);
> > > 
> > > This should not be difficult to implement, and I'll code it if everyone
> > > agrees.
> >  
> > I thought about this. Originally I did have this function but removed it.
> > WHat do you think Geert?
> > 
> > > The other option (which I don't like) is just to check the passed
> > > fb_var_screeninfo in the put_var ioctl against the current console
> > > window size.  But this is not foolproof as we will not be sure of the
> > > resulting window size _after_ the fb_set_var() call.
> > 
> > Yuck!!! The other way is better.
> > 
> 
> Yes, I thought so too :-).
> 
> I think one scenario why we need clipping is changing bits_per_pixel,
> ie, changing from 8->16 will drop your vyres by half and it's difficult
> to determine this unless you do another check before the set_par(), as
> Geert mentioned.  Worse still, there is little if no valid memory past
> vyres but the console thinks there is.  That's where you will get a
> segfault.
> 
> Whereas explicitly doing fbset -vyres 768 will not cause a segfault,
> because you still have valid framebuffer memory past y=768.

That depends. On unified memory architectures or if the graphics memory is
shared by two heads, you may still corrupt someone's memory.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

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



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
       [not found] <1042172278.933.145.camel@localhost.localdomain>
@ 2003-01-10 10:49 ` Geert Uytterhoeven
  0 siblings, 0 replies; 17+ messages in thread
From: Geert Uytterhoeven @ 2003-01-10 10:49 UTC (permalink / raw)
  To: Antonino Daplas; +Cc: James Simmons, Geert Uytterhoeven

On 10 Jan 2003, Antonino Daplas wrote:
> For putcs and putc, I just made it mandatory that when one character is
> to be out of bounds, it just won't get drawn.  A cleaner implementation
> is, of course, to clip the destination window + the passed bitmap.

Except for the geek value, why would it be cleaner to draw half of a character
near the border?

> Do we need to clip the fb_set_logo() too?

I don't think so. The current code already draws only the number of logos that
really fit on the screen. Unless you want to see half penguins as well :-)

> The patch may be a bit difficult to swallow because it is pretty much
> invasive and not so clean :-(, so it's okay if you don't take it.
> But it has the advantage of clipping the coordinates for hardware that 
> does not support clipping (like the i810fb).  For hardware that does 
> support clipping, or wants to implement its own clipping code, we require 
> a 'caps' (capabilities) field in fb_info or fb_fix_screeninfo.  This is 
> checked first and if set, the default clipping code is bypassed.

I prefer fb_info, since user space doesn't need to know.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

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




-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RESEND] clipping
  2003-01-09 21:46             ` clipping Geert Uytterhoeven
@ 2003-01-10 13:55               ` Antonino Daplas
  2003-01-10 19:39               ` clipping James Simmons
  1 sibling, 0 replies; 17+ messages in thread
From: Antonino Daplas @ 2003-01-10 13:55 UTC (permalink / raw)
  To: James Simmons; +Cc: Linux Fbdev development list

On Fri, 2003-01-10 at 05:46, Geert Uytterhoeven wrote:
> On Thu, 9 Jan 2003, James Simmons wrote:
> > > So perhaps, a function something like this:
> > > 
> > > void fb_clip(struct fb_fillrect *region, struct fb_fillrect *clip);
> > > 
> > > This should not be difficult to implement, and I'll code it if everyone
> > > agrees.
> >  
> > I thought about this. Originally I did have this function but removed it.
> > WHat do you think Geert?
> 
> Yes, that's OK.
> 
> But I was most concerned about fb_ops.fb_imageblit(), since clipping impacts
> fb_image.data as well. IIRC, all (most?) current clipping implementations
> modify fb_image.{dx,dy,width,height} only, without updating fb_image.data.
> 
> > > The other option (which I don't like) is just to check the passed
> > > fb_var_screeninfo in the put_var ioctl against the current console
> > > window size.  But this is not foolproof as we will not be sure of the
> > > resulting window size _after_ the fb_set_var() call.
> > 
> > Yuck!!! The other way is better.
> 
> Well, in between the calls to fb_ops.fb_check_var() and fb_ops.set_par() you
> can still perform that check. But it's indeed ugly.
> 

Geert, James

I've attached a patch that implements clipping in the fbcon layer using
2 generic clipping functions:

fb_clip_region() - one area to clip; and
fb_clip_region2() - two areas to clip (source and destination) as in
copyarea()

The above functions use this:

struct fb_region {
	__u32 dx;
	__u32 dy;
	__u32 width;
	__u32 height;
};

which is just a subset of fb_{image,copyarea,fillrect}.  Good thing that
you arranged those fields in the right order :-).

fb_clip_region() is a standard clipping implementation, whereas
fb_clip_region2() is a bit trickier because it has to clip _both_ the
source and destination against each other.  Most of 2 operand clipping
operations always assume that the source area need not be clipped.

For putcs and putc, I just made it mandatory that when one character is
to be out of bounds, it just won't get drawn.  A cleaner implementation
is, of course, to clip the destination window + the passed bitmap.

For accel_cursor(), if it's going out of bounds, I place it at
screenpos(0,0) and hide it.  Hopefully no one notices :-)

Do we need to clip the fb_set_logo() too?

I've also modified the cfb_{fillrect,copyarea,imageblit}: removed
clipping code and so it does not modify the passed parameters.  

The patch may be a bit difficult to swallow because it is pretty much
invasive and not so clean :-(, so it's okay if you don't take it.
But it has the advantage of clipping the coordinates for hardware that 
does not support clipping (like the i810fb).  For hardware that does 
support clipping, or wants to implement its own clipping code, we require 
a 'caps' (capabilities) field in fb_info or fb_fix_screeninfo.  This is 
checked first and if set, the default clipping code is bypassed.

Here's how it currently works in my system:

1.  reduce xres_virtual - works as expected, the tail end of the chars
are truncated.

2.  reduce yres_virtual - works as expected but display is useless as the 
screen is located deep down towards the end of yres_virtual.

In all cases, the screen can be restored when switching from another
console and back.  

Tony

diff -Naur linux-2.5.54/drivers/video/cfbcopyarea.c linux/drivers/video/cfbcopyarea.c
--- linux-2.5.54/drivers/video/cfbcopyarea.c	2003-01-09 13:58:14.000000000 +0000
+++ linux/drivers/video/cfbcopyarea.c	2003-01-09 13:57:43.000000000 +0000
@@ -321,7 +321,6 @@
 
 void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
 {
-	int x2, y2, old_dx, old_dy, vxres, vyres;
 	unsigned long next_line = p->fix.line_length;
 	int dst_idx = 0, src_idx = 0, rev_copy = 0;
 	unsigned long *dst = NULL, *src = NULL;
@@ -330,40 +329,6 @@
 	if (!p->fbops->fb_rotate && p->var.rotate) {
 	}	
 	
-	vxres = p->var.xres_virtual;
-	vyres = p->var.yres_virtual;
-
-	if (area->dx > vxres || area->sx > vxres || 
-	    area->dy > vyres || area->sy > vyres)
-		return;
-
-	/* clip the destination */
-	old_dx = area->dx;
-	old_dy = area->dy;
-
-	/*
-	 * We could use hardware clipping but on many cards you get around
-	 * hardware clipping by writing to framebuffer directly.
-	 */
-	x2 = area->dx + area->width;
-	y2 = area->dy + area->height;
-	area->dx = area->dx > 0 ? area->dx : 0;
-	area->dy = area->dy > 0 ? area->dy : 0;
-	x2 = x2 < vxres ? x2 : vxres;
-	y2 = y2 < vyres ? y2 : vyres;
-	area->width = x2 - area->dx;
-	area->height = y2 - area->dy;
-
-	/* update sx1,sy1 */
-	area->sx += (area->dx - old_dx);
-	area->sy += (area->dy - old_dy);
-
-	/* the source must be completely inside the virtual screen */
-	if (area->sx < 0 || area->sy < 0 ||
-	    (area->sx + area->width) > vxres ||
-	    (area->sy + area->height) > vyres)
-		return;
-	
 	if (area->dy > area->sy || (area->dy == area->sy && area->dx > area->sx)) {
 		area->dy += area->height;
 		area->sy += area->height;
diff -Naur linux-2.5.54/drivers/video/cfbfillrect.c linux/drivers/video/cfbfillrect.c
--- linux-2.5.54/drivers/video/cfbfillrect.c	2003-01-09 13:58:10.000000000 +0000
+++ linux/drivers/video/cfbfillrect.c	2003-01-09 13:57:44.000000000 +0000
@@ -361,7 +361,6 @@
 void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
 {
 	unsigned long height, fg;
-	unsigned long x2, y2, vxres, vyres;
 	unsigned long *dst;
 	int dst_idx, left;
 	u32 bpp = p->var.bits_per_pixel;
@@ -370,21 +369,7 @@
 	if (!p->fbops->fb_rotate && p->var.rotate) {
 	}	
 	
-	vxres = p->var.xres_virtual;
-	vyres = p->var.yres_virtual;
-
-	if (!rect->width || !rect->height || rect->dx > vxres || rect->dy > vyres)
-		return;
-
-	/* We could use hardware clipping but on many cards you get around
-	 * hardware clipping by writing to framebuffer directly. */
-	
-	x2 = rect->dx + rect->width;
-	y2 = rect->dy + rect->height;
-	x2 = x2 < vxres ? x2 : vxres;
-	y2 = y2 < vyres ? y2 : vyres;
-	rect->width = x2 - rect->dx;
-	height = y2 - rect->dy;
+	height = rect->height;
 	
 	if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
 	    p->fix.visual == FB_VISUAL_DIRECTCOLOR )
diff -Naur linux-2.5.54/drivers/video/cfbimgblt.c linux/drivers/video/cfbimgblt.c
--- linux-2.5.54/drivers/video/cfbimgblt.c	2003-01-09 13:58:19.000000000 +0000
+++ linux/drivers/video/cfbimgblt.c	2003-01-09 15:52:14.000000000 +0000
@@ -88,11 +88,13 @@
 
 #if defined (__BIG_ENDIAN)
 #define LEFT_POS(bpp)          (BITS_PER_LONG - bpp)
+#define LEFT_POS32(bpp)        (32 - bpp)
 #define NEXT_POS(pos, bpp)     ((pos) -= (bpp))
 #define SHIFT_HIGH(val, bits)  ((val) >> (bits))
 #define SHIFT_LOW(val, bits)   ((val) << (bits))
 #else
 #define LEFT_POS(bpp)          (0)
+#define LEFT_POS32(bpp)        (0)
 #define NEXT_POS(pos, bpp)     ((pos) += (bpp))
 #define SHIFT_HIGH(val, bits)  ((val) << (bits))
 #define SHIFT_LOW(val, bits)   ((val) >> (bits))
@@ -224,25 +226,25 @@
 }
 
 static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1, 
-				  unsigned long fgcolor, unsigned long bgcolor) 
+				  u32 fgcolor, u32 bgcolor) 
 {
 	int i, j, k, l = 8, n;
-	unsigned long bit_mask, end_mask, eorx; 
-	unsigned long fgx = fgcolor, bgx = bgcolor, pad, bpp = p->var.bits_per_pixel;
-	unsigned long tmp = (1 << bpp) - 1;
-	unsigned long ppw = BITS_PER_LONG/bpp, ppos;
-	unsigned long *dst;
+	u32 bit_mask, end_mask, eorx; 
+	u32 fgx = fgcolor, bgx = bgcolor, pad, bpp = p->var.bits_per_pixel;
+	u32 tmp = (1 << bpp) - 1;
+	u32 ppw = 32/bpp, ppos;
+	u32 *dst;
 	u32 *tab = NULL;
 	char *src = image->data;
 		
-	switch (ppw) {
-	case 4:
+	switch (bpp) {
+	case 8:
 		tab = cfb_tab8;
 		break;
-	case 2:
+	case 16:
 		tab = cfb_tab16;
 		break;
-	case 1:
+	case 32:
 		tab = cfb_tab32;
 		break;
 	}
@@ -264,17 +266,17 @@
 	k = image->width/ppw;
 
 	for (i = image->height; i--; ) {
-		dst = (unsigned long *) dst1;
+		dst = (u32 *) dst1;
 		
 		for (j = k; j--; ) {
 			l -= ppw;
 			end_mask = tab[(*src >> l) & bit_mask]; 
-			FB_WRITEL((end_mask & eorx)^bgx, dst++);
+			fb_writel((end_mask & eorx)^bgx, dst++);
 			if (!l) { l = 8; src++; }
 		}
 		if (n) {
 			end_mask = 0;	
-			ppos = LEFT_POS(bpp);
+			ppos = LEFT_POS32(bpp);
 			for (j = n; j > 0; j--) {
 				l--;
 				if (*src & (1 << l))
@@ -282,7 +284,7 @@
 				NEXT_POS(ppos, bpp);
 				if (!l) { l = 8; src++; }
 			}
-			FB_WRITEL((end_mask & eorx)^bgx, dst++);
+			fb_writel((end_mask & eorx)^bgx, dst++);
 		}
 		l -= pad;		
 		dst1 += p->fix.line_length;	
@@ -291,30 +293,10 @@
 	
 void cfb_imageblit(struct fb_info *p, struct fb_image *image)
 {
-	int x2, y2, vxres, vyres;
 	unsigned long fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
 	unsigned long bpl = sizeof(unsigned long), bpp = p->var.bits_per_pixel;
 	u8 *dst1;
 
-	vxres = p->var.xres_virtual;
-	vyres = p->var.yres_virtual;
-	/* 
-	 * We could use hardware clipping but on many cards you get around hardware
-	 * clipping by writing to framebuffer directly like we are doing here. 
-	 */
-	if (image->dx > vxres ||
-	    image->dy > vyres)
-		return;
-
-	x2 = image->dx + image->width;
-	y2 = image->dy + image->height;
-	image->dx = image->dx > 0 ? image->dx : 0;
-	image->dy = image->dy > 0 ? image->dy : 0;
-	x2 = x2 < vxres ? x2 : vxres;
-	y2 = y2 < vyres ? y2 : vyres;
-	image->width  = x2 - image->dx;
-	image->height = y2 - image->dy;
-
 	bitstart = (image->dy * p->fix.line_length * 8) + (image->dx * bpp);
 	start_index = bitstart & (BITS_PER_LONG - 1);
 	pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
@@ -337,7 +319,8 @@
 		    bpp >= 8 && bpp <= 32 && (image->width & 7) == 0) 
 			fast_imageblit(image, p, dst1, fgcolor, bgcolor);
 		else 
-			slow_imageblit(image, p, dst1, fgcolor, bgcolor, start_index, pitch_index);
+			slow_imageblit(image, p, dst1, (u32) fgcolor, (u32) bgcolor, 
+				       start_index, pitch_index);
 	}
 	else if (image->depth == bpp) 
 		color_imageblit(image, p, dst1, start_index, pitch_index);
diff -Naur linux-2.5.54/drivers/video/console/fbcon.c linux/drivers/video/console/fbcon.c
--- linux-2.5.54/drivers/video/console/fbcon.c	2003-01-09 13:52:34.000000000 +0000
+++ linux/drivers/video/console/fbcon.c	2003-01-10 02:50:37.000000000 +0000
@@ -351,6 +351,7 @@
 	struct fb_info *info = p->fb_info;
 	struct vc_data *vc = p->conp;
 	struct fb_copyarea area;
+	struct fb_region clip, s_region, d_region;
 
 	area.sx = sx * vc->vc_font.width;
 	area.sy = sy * vc->vc_font.height;
@@ -359,6 +360,33 @@
 	area.height = height * vc->vc_font.height;
 	area.width = width * vc->vc_font.width;
 
+	if (!(info->caps & FB_CAPS_CLIPPING) && 
+	    (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+	     vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+		clip.dx = clip.dy = 0;
+		clip.width = info->var.xres_virtual;
+		clip.height = info->var.yres_virtual;
+		
+		s_region.dx = area.sx;
+		s_region.dy = area.sy;
+		d_region.dx = area.dx;
+		d_region.dy = area.dy;
+		s_region.width = d_region.width = area.width;
+		s_region.height = d_region.height = area.height;
+
+		fb_clip_region2(&d_region, &s_region, &clip);
+
+		if (!d_region.width || !d_region.height)
+			return;
+	       
+		area.dx = d_region.dx;
+		area.dy = d_region.dy;
+		area.sx = s_region.dx;
+		area.sy = s_region.dy;
+		area.width = d_region.width;
+		area.height = d_region.height;
+	}
+
 	info->fbops->fb_copyarea(info, &area);
 }
 
@@ -367,6 +395,7 @@
 {
 	struct fb_info *info = p->fb_info;
 	struct fb_fillrect region;
+	struct fb_region clip;
 
 	region.color = attr_bgcol_ec(p, vc);
 	region.dx = sx * vc->vc_font.width;
@@ -375,9 +404,36 @@
 	region.height = height * vc->vc_font.height;
 	region.rop = ROP_COPY;
 
+	if (!(info->caps & FB_CAPS_CLIPPING) && 
+	    (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+	     vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+		clip.dx = clip.dy = 0;
+		clip.width = info->var.xres_virtual;
+		clip.height = info->var.yres_virtual;
+		fb_clip_region((struct fb_region *) &region, &clip);
+		if (!region.width || !region.height)
+			return;
+	}
+
 	info->fbops->fb_fillrect(info, &region);
 }	
 
+static int test_clip(struct fb_region *clip,
+		     struct fb_region *src)
+{
+	struct fb_region region =  *src;
+
+	fb_clip_region(&region, clip);
+
+	if (region.dx != src->dx ||
+	    region.dy != src->dy ||
+	    region.width != src->width ||
+	    region.height != src->height) 
+		return 1;
+
+	return 0;
+}
+
 #define FB_PIXMAPSIZE 8192
 void accel_putcs(struct vc_data *vc, struct display *p,
 			const unsigned short *s, int count, int yy, int xx)
@@ -386,7 +442,9 @@
 	unsigned short charmask = p->charmask;
 	unsigned int width = ((vc->vc_font.width + 7)/8);
 	unsigned int cellsize = vc->vc_font.height * width;
+	unsigned int do_clip = 0;
 	struct fb_image image;
+	struct fb_region clip;
 	u16 c = scr_readw(s);
 	static u8 pixmap[FB_PIXMAPSIZE];
 	
@@ -397,7 +455,26 @@
 	image.height = vc->vc_font.height;
 	image.depth = 1;
 
-	if (!(vc->vc_font.width & 7)) {
+	if (!(info->caps & FB_CAPS_CLIPPING) && 
+	    (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+	     vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+		clip.dx = clip.dy = 0;
+		clip.width = info->var.xres_virtual;
+		clip.height = info->var.yres_virtual;
+		do_clip = 1;
+		/* we do some cheating here... If the bitmap will
+		 * be clipped, we just pass it to the slower method
+		 * of 1 imageblit per character.
+		 */
+		if (!(vc->vc_font.width & 7)) {
+			struct fb_region *region = (struct fb_region *) &image;
+
+			image.width = count * vc->vc_font.width;
+			do_clip = (test_clip(&clip, region)) ? 2 : do_clip;
+		}
+	}
+
+	if (!(vc->vc_font.width & 7) && do_clip != 2) { 
 		unsigned int pitch, cnt, i, j, k;
 		unsigned int maxcnt = FB_PIXMAPSIZE/(vc->vc_font.height * width);
 		char *src, *dst, *dst0;
@@ -429,11 +506,14 @@
 			count -= cnt;
 		}
 	} else {
+		struct fb_region *region = (struct fb_region *) &image;
 		image.width = vc->vc_font.width;
 		while (count--) {
 			image.data = p->fontdata + 
 				(scr_readw(s++) & charmask) * 
 				vc->vc_font.height * width;
+			if (do_clip && test_clip(&clip, region))
+				return;
 			info->fbops->fb_imageblit(info, &image);
 			image.dx += vc->vc_font.width;
 		}	
@@ -450,16 +530,32 @@
 	unsigned int bh = info->var.yres % ch;
 	unsigned int rs = info->var.xres - rw;
 	unsigned int bs = info->var.yres - bh;
+	unsigned int do_clip = 0;
 	struct fb_fillrect region;
+	struct fb_region clip;
 
 	region.color = attr_bgcol_ec(p, vc);
 	region.rop = ROP_COPY;
 
+	if (!(info->caps & FB_CAPS_CLIPPING) && 
+	    (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+	     vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+		clip.dx = clip.dy = 0;
+		clip.width = info->var.xres_virtual;
+		clip.height = info->var.yres_virtual;
+		do_clip = 1;
+	}
+
 	if (rw & !bottom_only) {
 		region.dx = info->var.xoffset + rs;
 		region.dy = 0;
 		region.width = rw;
 		region.height = info->var.yres_virtual;
+		if (do_clip) {
+			fb_clip_region((struct fb_region *) &region, &clip);
+			if (!region.width || !region.height)
+				return;
+		}
 		info->fbops->fb_fillrect(info, &region);
 	}
 
@@ -468,6 +564,11 @@
 		region.dy = info->var.yoffset + bs;
 		region.width = rs;
 		region.height = bh;
+		if (do_clip) {
+			fb_clip_region((struct fb_region *) &region, &clip);
+			if (!region.width || !region.height)
+				return;
+		}
 		info->fbops->fb_fillrect(info, &region);
 	}	
 }	
@@ -490,6 +591,28 @@
 		cursor.set |= FB_CUR_SETSIZE;
 	}	
 
+	if (!(info->caps & FB_CAPS_CLIPPING) && 
+	    (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+	     vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+		struct fb_region clip, test;
+
+		clip.dx = clip.dy = 0;
+		clip.width = info->var.xres_virtual;
+		clip.height = info->var.yres_virtual;
+		test.dx = xx * width;
+		test.dy = yy * height;
+		test.width = width;
+		test.height = height;
+		
+		/*
+		 * we place cursor at screenpos(0,0) and hide it :-)
+		 */
+		if (test_clip(&clip, &test)) {
+			xx = 0; yy = 0;
+			flags &= ~FB_CUR_SETCUR;
+		}
+	}
+
 	if ((vc->vc_cursor_type & 0x0f) != shape) {
 		shape = vc->vc_cursor_type & 0x0f;
 		cursor.set |= FB_CUR_SETSHAPE;
@@ -1173,6 +1296,18 @@
 	image.depth = 1;
 	image.data = p->fontdata + (c & charmask) * vc->vc_font.height * width;
 
+	if (!(info->caps & FB_CAPS_CLIPPING) && 
+	    (vc->vc_cols * vc->vc_font.width > info->var.xres_virtual ||
+	     vc->vc_rows * vc->vc_font.height > info->var.yres_virtual)) {
+		struct fb_region clip;
+
+		clip.dx = clip.dy = 0;
+		clip.width = info->var.xres_virtual;
+		clip.height = info->var.yres_virtual;
+		if (test_clip(&clip, (struct fb_region *) &image))
+			return;
+	}
+
 	info->fbops->fb_imageblit(info, &image);
 
 	if (redraw_cursor)
@@ -1917,7 +2052,9 @@
 			conp2->vc_top = 0;
 		logo_shown = -1;
 	}
-	if (info)
+        fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
+	p->vrows = info->var.yres_virtual/vc->vc_font.height;
+	if (info) 
 		info->var.yoffset = p->yscroll = 0;
 	switch (p->scrollmode & __SCROLL_YMASK) {
 	case __SCROLL_YWRAP:
@@ -1937,7 +2074,6 @@
 
 	info->currcon = unit;
 	
-        fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
 	update_var(unit, info);
 	fbcon_set_palette(vc, color_table); 	
 
diff -Naur linux-2.5.54/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- linux-2.5.54/drivers/video/fbmem.c	2003-01-09 13:52:13.000000000 +0000
+++ linux/drivers/video/fbmem.c	2003-01-10 03:40:17.000000000 +0000
@@ -368,6 +368,134 @@
 #define LOGO_H		80
 #define LOGO_W		80
 
+/**
+ * fb_clip_region: software clipping
+ * @region: area to clip
+ * @clip: clipping coordinates
+ */
+void fb_clip_region(struct fb_region *region, 
+		    const struct fb_region *clip)
+{
+	u32 clipx2 = clip->dx + clip->width;
+	u32 clipy2 = clip->dy + clip->height;
+
+	if (region->dx > clipx2) {
+		region->dx = clipx2;
+		region->width = 0;
+	}
+
+	if (region->dy > clipy2) {
+		region->dy = clipy2;
+		region->height = 0;
+	}
+
+	if (region->dx < clip->dx) 
+		region->dx = clip->dx;
+
+	if (clipx2 < region->dx + region->width)
+		region->width = clipx2 - region->dx;
+
+	if (region->dy < clip->dy) 
+		region->dy = clip->dy - region->dy;
+
+	if (clipy2 < region->dy + region->height)
+		region->height = clipy2 - clip->dy;
+}
+		
+/**
+ * fb_clip_region2: software clipping
+ * @d_region: dst area to clip
+ * @s_region: src area to clip
+ * @clip: clipping coordinates
+ */
+void fb_clip_region2(struct fb_region *d_region,
+		     struct fb_region *s_region,
+		     const struct fb_region *clip)
+{
+	u32 clipx2 = clip->dx + clip->width;
+	u32 clipy2 = clip->dy + clip->height;
+	u32 dx2, dy2, sx2, sy2;
+
+	if (d_region->dx > clipx2) {
+		d_region->dx = clipx2;
+		d_region->width = 0;
+	}
+
+	if (d_region->dy > clipy2) {
+		d_region->dy = clipy2;
+		d_region->height = 0;
+	}
+
+	if (s_region->dx > clipx2) {
+		s_region->dx = clipx2;
+		s_region->width = 0;
+	}
+
+	if (s_region->dy > clipy2) {
+		s_region->dy = clipy2;
+		s_region->height = 0;
+	}
+
+	/* clip source, against destination */
+	if (d_region->dx < clip->dx) {
+		dx2 = d_region->dx + d_region->width;
+		s_region->width = (clip->width < dx2 - clip->dx) ?
+			clip->width : dx2 - clip->dx;
+		s_region->dx += clip->dx - d_region->dx;
+		d_region->dx = clip->dx;
+	}
+
+	dx2 = d_region->dx + s_region->width;
+	if (clipx2 < dx2) 
+		s_region->width = clipx2 - d_region->dx;
+
+	d_region->width = s_region->width;
+
+	if (d_region->dy < clip->dy) {
+		dy2 = d_region->dy + d_region->height;
+		s_region->height = (clip->height < dy2 - clip->dy) ?
+			clip->height : dy2 - clip->dy;
+		s_region->dy += clip->dy - d_region->dy;
+		d_region->dy = clip->dy;
+	}
+
+	dy2 = d_region->dy + s_region->height;
+	if (clipy2 < dy2) 
+		s_region->height = clipx2 - d_region->dy;
+
+	d_region->height = s_region->height;
+
+	/* not guaranteed that source is within bounds, so... */
+	/* clip destination, against source */
+	if (s_region->dx < clip->dx) {
+		sx2 = s_region->dx + s_region->width;
+		d_region->width = (clip->width < sx2 - clip->dx) ?
+			clip->width : sx2 - clip->dx;
+		d_region->dx += clip->dx - s_region->dx;
+		s_region->dx = clip->dx;
+	}
+
+	sx2 = s_region->dx + d_region->width;
+	if (clipx2 < sx2) 
+		d_region->width = clipx2 - s_region->dx;
+
+	s_region->width = d_region->width;
+
+	if (s_region->dy < clip->dy) {
+		sy2 = s_region->dy + s_region->height;
+		d_region->height = (clip->height < sy2 - clip->dy) ?
+			clip->height : sy2 - clip->dy;
+		d_region->dy += clip->dy - s_region->dy;
+		s_region->dy = clip->dy;
+	}
+
+	sy2 = s_region->dy + d_region->height;
+	if (clipy2 < sy2) 
+		d_region->height = clipx2 - s_region->dy;
+
+	s_region->height = d_region->height;
+}
+
 static inline unsigned safe_shift(unsigned d, int n)
 {
 	return n < 0 ? d >> -n : d << n;
@@ -1189,5 +1317,7 @@
 EXPORT_SYMBOL(fb_set_var);
 EXPORT_SYMBOL(fb_blank);
 EXPORT_SYMBOL(fb_pan_display);
+EXPORT_SYMBOL(fb_clip_region);
+EXPORT_SYMBOL(fb_clip_region2);
 
 MODULE_LICENSE("GPL");
diff -Naur linux-2.5.54/include/linux/fb.h linux/include/linux/fb.h
--- linux-2.5.54/include/linux/fb.h	2003-01-09 13:52:49.000000000 +0000
+++ linux/include/linux/fb.h	2003-01-09 13:51:41.000000000 +0000
@@ -173,6 +173,9 @@
 #define FB_VMODE_SMOOTH_XPAN	512	/* smooth xpan possible (internally used) */
 #define FB_VMODE_CONUPDATE	512	/* don't update x/yoffset	*/
 
+/* Driver Capability */
+#define FB_CAPS_CLIPPING        1       /* hardware can do clipping */
+
 #define PICOS2KHZ(a) (1000000000UL/(a))
 #define KHZ2PICOS(a) (1000000000UL/(a))
 
@@ -394,6 +397,7 @@
    void *pseudo_palette;                /* Fake palette of 16 colors and 
 					   the cursor's color for non
                                            palette mode */
+   int caps;                            /* Driver capability, see FB_CAPS_* */
    /* From here on everything is device dependent */
    void *par;	
 };
@@ -461,6 +465,11 @@
 extern int register_framebuffer(struct fb_info *fb_info);
 extern int unregister_framebuffer(struct fb_info *fb_info);
 extern int fb_show_logo(struct fb_info *fb_info);
+extern void fb_clip_region(struct fb_region *region, 
+			   const struct fb_region *clip);
+extern void fb_clip_region2(struct fb_region *s_region,
+			    struct fb_region *d_region,
+			    const struct fb_region *clip);
 extern struct fb_info *registered_fb[FB_MAX];
 extern int num_registered_fb;
 



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-09 21:46             ` clipping Geert Uytterhoeven
  2003-01-10 13:55               ` [RESEND] clipping Antonino Daplas
@ 2003-01-10 19:39               ` James Simmons
  2003-01-10 19:48                 ` clipping Geert Uytterhoeven
  2003-01-11  5:12                 ` clipping Antonino Daplas
  1 sibling, 2 replies; 17+ messages in thread
From: James Simmons @ 2003-01-10 19:39 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Antonino Daplas, Linux Frame Buffer Device Development


> > I thought about this. Originally I did have this function but removed it.
> > WHat do you think Geert?
> 
> Yes, that's OK.
> 
> But I was most concerned about fb_ops.fb_imageblit(), since clipping impacts
> fb_image.data as well. IIRC, all (most?) current clipping implementations
> modify fb_image.{dx,dy,width,height} only, without updating fb_image.data.

Good point. Of course we could ignore pieces of data in that image instead 
of altering the data. Altering the entire data would be expensive.

> > > The other option (which I don't like) is just to check the passed
> > > fb_var_screeninfo in the put_var ioctl against the current console
> > > window size.  But this is not foolproof as we will not be sure of the
> > > resulting window size _after_ the fb_set_var() call.
> > 
> > Yuck!!! The other way is better.
> 
> Well, in between the calls to fb_ops.fb_check_var() and fb_ops.set_par() you
> can still perform that check. But it's indeed ugly.

Altering to the framebuffer via /dev/fb that would effect the tty should 
not remain after the final close of /dev/fb. Instead the console should 
reset to its previous state before we first opened /dev/fb.



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-10 19:39               ` clipping James Simmons
@ 2003-01-10 19:48                 ` Geert Uytterhoeven
  2003-01-11  5:12                 ` clipping Antonino Daplas
  1 sibling, 0 replies; 17+ messages in thread
From: Geert Uytterhoeven @ 2003-01-10 19:48 UTC (permalink / raw)
  To: James Simmons; +Cc: Antonino Daplas, Linux Frame Buffer Device Development

On Fri, 10 Jan 2003, James Simmons wrote:
> > > I thought about this. Originally I did have this function but removed it.
> > > WHat do you think Geert?
> > 
> > Yes, that's OK.
> > 
> > But I was most concerned about fb_ops.fb_imageblit(), since clipping impacts
> > fb_image.data as well. IIRC, all (most?) current clipping implementations
> > modify fb_image.{dx,dy,width,height} only, without updating fb_image.data.
> 
> Good point. Of course we could ignore pieces of data in that image instead 
> of altering the data. Altering the entire data would be expensive.

Actually I thought about modifying the fb_image.data pointer only. But indeed,
for monochrome expansion you may have to modify the data, since pixel
boundaries in a bitmap don't correspond to byte boundaries.

Alternatively, if fb_image would countain sx and sy fields (cfr. fb_copyarea),
we can just alter (a copy of) sx and sy when clipping.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

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



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
  2003-01-10 19:39               ` clipping James Simmons
  2003-01-10 19:48                 ` clipping Geert Uytterhoeven
@ 2003-01-11  5:12                 ` Antonino Daplas
  1 sibling, 0 replies; 17+ messages in thread
From: Antonino Daplas @ 2003-01-11  5:12 UTC (permalink / raw)
  To: James Simmons; +Cc: Geert Uytterhoeven, Linux Frame Buffer Device Development

On Sat, 2003-01-11 at 03:39, James Simmons wrote:
> 
> > > I thought about this. Originally I did have this function but removed it.
> > > WHat do you think Geert?
> > 
> > Yes, that's OK.
> > 
> > But I was most concerned about fb_ops.fb_imageblit(), since clipping impacts
> > fb_image.data as well. IIRC, all (most?) current clipping implementations
> > modify fb_image.{dx,dy,width,height} only, without updating fb_image.data.
> 
> Good point. Of course we could ignore pieces of data in that image instead 
> of altering the data. Altering the entire data would be expensive.
> 
> > > > The other option (which I don't like) is just to check the passed
> > > > fb_var_screeninfo in the put_var ioctl against the current console
> > > > window size.  But this is not foolproof as we will not be sure of the
> > > > resulting window size _after_ the fb_set_var() call.
> > > 
> > > Yuck!!! The other way is better.
> > 
> > Well, in between the calls to fb_ops.fb_check_var() and fb_ops.set_par() you
> > can still perform that check. But it's indeed ugly.
> 
> Altering to the framebuffer via /dev/fb that would effect the tty should 
> not remain after the final close of /dev/fb. Instead the console should 
> reset to its previous state before we first opened /dev/fb.
> 

Right :-) I believe this is nearer the correct solution.  Clipping is
typically used to maximize graphics/video bandwidth, but fbcon is using
it to "cover up" possible bugs in the code.

If we can have a correctly working fbcon, without the clipping code, it
will be proof to its robustness.

So, basically, on the first open we save xres, yres, xres_virtual,
yres_virtual and bits_per_pixel, and restore them on the last close, is
this correct?  Any other parameters that will affect the actual and
virtual window size?

Tony





-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: clipping
       [not found] <Pine.LNX.4.44.0301102030310.30522-100000@phoenix.infradead.org>
@ 2003-01-11  5:12 ` Antonino Daplas
  0 siblings, 0 replies; 17+ messages in thread
From: Antonino Daplas @ 2003-01-11  5:12 UTC (permalink / raw)
  To: James Simmons; +Cc: Geert Uytterhoeven, Linux Fbdev development list

On Sat, 2003-01-11 at 04:31, James Simmons wrote:
> 
> > > > Except for the geek value, why would it be cleaner to draw half of a character
> > > > near the border?
> > > 
> > > This is one of the reasons why I moved from fbset to setting the console 
> > > resolution via the console layer. You can't end up with half characters. 
> > > Via fbset you could but fbcon had extra code to prevent such foolishness. 
> > > But it still looked silly to have half line on the bottom of the screen 
> > > that nothing ever drawed in.
> > 
> > What else can you do? My notebook has a fixed LCD of 1024x768. With the 12x22
> > font, I have a text console of 85x34, using only 1020x748 pixels. Shrinking the
> > resolution to 1020x748 is not an option.
> 
> Ug. I guess we handle it the best way we can. Also we can try BenH 
> suggesting of incorpating scaling. 
> 

Or we can modify fbcon_resize() so it just checks if the resulting
resolution is enough to accomodate the console window size...

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, x, y;

	var.xres = x = width * vc->vc_font.width;
	var.yres = y = height * vc->vc_font.height;
	var.activate = FB_ACTIVATE_TEST;
	err = fb_set_var(&var, info);
	if (err || var.xres < x || var.yres < y)
		return -EINVAL;

	var.activate = FB_ACTIVATE_NOW;
	err = fb_set_var(&var, info);
	p->vrows = info->var.yres_virtual/vc->vc_font.height;
	return err; 
}

...which implies that we also have to modify accel_clear_margins() so it
clears more than just a fraction of a character's width and height...

void accel_clear_margins(struct vc_data *vc, struct display *p,
				int bottom_only)
{
	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 - vc->vc_cols * cw;
	unsigned int bh = info->var.yres - vc->vc_rows * ch;
	unsigned int rs = info->var.xres - rw;
	unsigned int bs = info->var.yres - bh;
	struct fb_fillrect region;

	region.color = attr_bgcol_ec(p, vc);
	region.rop = ROP_COPY;

	if (rw & !bottom_only) {
		region.dx = info->var.xoffset + rs;
		region.dy = 0;
		region.width = rw;
		region.height = info->var.yres_virtual;
		info->fbops->fb_fillrect(info, &region);
	}

	if (bh) {
		region.dx = info->var.xoffset;
		region.dy = info->var.yoffset + bs;
		region.width = rs;
		region.height = bh;
		info->fbops->fb_fillrect(info, &region);
	}	
}	

... which exposed a bug in vc_resize() in vt.c.  In vc_resize(), the
global variables:

	video_num_lines;
	video_num_columns;
	video_size_row;
	screenbuf_size;

are modified before calling consw->con_resize() which, if it returns
with an error, are left with invalid numbers. So attached is a patch.

It behaves correctly now.  When the resulting resolution is bigger than
the console window size, it's left with a small window at the upper left
corner.  So stty must be called so rows and cols are enough but no
bigger than the supported resolution.

This works pretty well if panning is disabled.  With panning, I get a
cursor "dissynchronous" with the display and where the virtual screen is
randomly placed anywhere within the display window.

We might need to fix for scrolling + panning here.

Tony

diff -Naur linux-2.5.54/drivers/char/vt.c linux/drivers/char/vt.c
--- linux-2.5.54/drivers/char/vt.c	2003-01-11 04:47:02.000000000 +0000
+++ linux/drivers/char/vt.c	2003-01-11 04:47:49.000000000 +0000
@@ -732,24 +732,24 @@
 	if (new_cols == video_num_columns && new_rows == video_num_lines)
 		return 0;
 
-	newscreen = (unsigned short *) kmalloc(new_screen_size, GFP_USER);
-	if (!newscreen)
-		return -ENOMEM;
-
 	old_rows = video_num_lines;
 	old_cols = video_num_columns;
 	old_row_size = video_size_row;
 	old_screen_size = screenbuf_size;
 
+	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;
+
 	video_num_lines = new_rows;
 	video_num_columns = new_cols;
 	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;
 	old_origin = origin;





-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2003-01-11  5:23 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-29 21:21 clipping Geert Uytterhoeven
2003-01-03 10:36 ` clipping Antonino Daplas
2003-01-07 21:08   ` clipping Geert Uytterhoeven
2003-01-07 22:13     ` clipping James Simmons
2003-01-08  9:54       ` clipping Geert Uytterhoeven
2003-01-08 16:26         ` clipping Antonino Daplas
2003-01-09 21:24           ` clipping James Simmons
2003-01-09 21:46             ` clipping Geert Uytterhoeven
2003-01-10 13:55               ` [RESEND] clipping Antonino Daplas
2003-01-10 19:39               ` clipping James Simmons
2003-01-10 19:48                 ` clipping Geert Uytterhoeven
2003-01-11  5:12                 ` clipping Antonino Daplas
2003-01-10 10:27             ` clipping Antonino Daplas
2003-01-10 10:45               ` clipping Geert Uytterhoeven
2003-01-09 21:09         ` clipping James Simmons
     [not found] <1042172278.933.145.camel@localhost.localdomain>
2003-01-10 10:49 ` clipping Geert Uytterhoeven
     [not found] <Pine.LNX.4.44.0301102030310.30522-100000@phoenix.infradead.org>
2003-01-11  5:12 ` clipping Antonino Daplas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).