
From: "Antonino A. Daplas" <adaplas@hotpop.com>

- Add support for fonts bigger thatn 16x32 by dynamically allocating buffer
  based on font dimensions instead of statically allocating at 64 bytes.

- use softcursor if cursor size exceeds 32x32.

- fix rivafb_cursor if cursor width is not divisible by 2

Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/video/riva/fbdev.c |   72 ++++++++++++++++++++++---------------
 1 files changed, 43 insertions(+), 29 deletions(-)

diff -puN drivers/video/riva/fbdev.c~fbdev-support-for-bigger-than-16x32-fonts-in-rivafb-cursor drivers/video/riva/fbdev.c
--- 25/drivers/video/riva/fbdev.c~fbdev-support-for-bigger-than-16x32-fonts-in-rivafb-cursor	2004-11-10 18:36:11.996574592 -0800
+++ 25-akpm/drivers/video/riva/fbdev.c	2004-11-10 18:36:12.001573832 -0800
@@ -444,6 +444,8 @@ static void rivafb_load_cursor_image(str
 	bg = le16_to_cpu(bg);
 	fg = le16_to_cpu(fg);
 
+	w = (w + 1) & ~1;
+
 	for (i = 0; i < h; i++) {
 		b = *data++;
 		reverse_order(&b);
@@ -1577,6 +1579,10 @@ static int rivafb_cursor(struct fb_info 
 	u16 fg, bg;
 	int i, set = cursor->set;
 
+	if (cursor->image.width > MAX_CURS ||
+	    cursor->image.height > MAX_CURS)
+		return soft_cursor(info, cursor);
+
 	par->riva.ShowHideCursor(&par->riva, 0);
 
 	if (par->cursor_reset) {
@@ -1606,38 +1612,46 @@ static int rivafb_cursor(struct fb_info 
 		u32 d_pitch = MAX_CURS/8;
 		u8 *dat = (u8 *) cursor->image.data;
 		u8 *msk = (u8 *) cursor->mask;
-		u8 src[64];	
-		
-		switch (cursor->rop) {
-		case ROP_XOR:
-			for (i = 0; i < s_pitch * cursor->image.height;
-			     i++)
-				src[i] = dat[i] ^ msk[i];
-			break;
-		case ROP_COPY:
-		default:
-			for (i = 0; i < s_pitch * cursor->image.height;
-			     i++)
-				src[i] = dat[i] & msk[i];
-			break;
-		}
+		u8 *src;
 		
-		fb_sysmove_buf_aligned(info, &info->pixmap, data, d_pitch, src,
-				       s_pitch, cursor->image.height);
+		src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);
 
-		bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
-		     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
-		     ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
-
-		fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
-		     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
-		     ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
-
-		par->riva.LockUnlock(&par->riva, 0);
+		if (src) {
+			switch (cursor->rop) {
+			case ROP_XOR:
+				for (i = 0; i < s_pitch * cursor->image.height;
+				     i++)
+					src[i] = dat[i] ^ msk[i];
+				break;
+			case ROP_COPY:
+			default:
+				for (i = 0; i < s_pitch * cursor->image.height;
+				     i++)
+					src[i] = dat[i] & msk[i];
+				break;
+			}
 
-		rivafb_load_cursor_image(par, data, bg, fg,
-					 cursor->image.width,
-					 cursor->image.height);
+			fb_sysmove_buf_aligned(info, &info->pixmap, data,
+					       d_pitch, src, s_pitch,
+					       cursor->image.height);
+
+			bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
+				((info->cmap.green[bg_idx] & 0xf8) << 2) |
+				((info->cmap.blue[bg_idx] & 0xf8) >> 3) |
+				1 << 15;
+
+			fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
+				((info->cmap.green[fg_idx] & 0xf8) << 2) |
+				((info->cmap.blue[fg_idx] & 0xf8) >> 3) |
+				1 << 15;
+
+			par->riva.LockUnlock(&par->riva, 0);
+
+			rivafb_load_cursor_image(par, data, bg, fg,
+						 cursor->image.width,
+						 cursor->image.height);
+			kfree(src);
+		}
 	}
 
 	if (cursor->enable)
_
