summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorJames Simmons <jsimmons@kozmo.(none)>2003-04-01 12:42:38 -0800
committerJames Simmons <jsimmons@kozmo.(none)>2003-04-01 12:42:38 -0800
commitc8fe90fdca768a9bf5b341f128cd7e623f41f9c3 (patch)
treec4b18dc5df578504cfdba8c6d522aa21799a408d /drivers/video
parent80da663a1c90e4fb830cf30d47ce16fe4a5a8ab0 (diff)
[FBDEV] Final cursor code cleanups. Now the burden of handling the cursor code lies on the driver side. The reason for this is that a invalid cursor might come from userland.
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/console/fbcon.c32
-rw-r--r--drivers/video/console/fbcon.h1
-rw-r--r--drivers/video/softcursor.c18
3 files changed, 28 insertions, 23 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index d815d9149a2d..882baa4974dd 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -197,6 +197,7 @@ static void fb_flashcursor(void *private)
if (!info || !info->cursor.enable)
return;
+ info->cursor.set = FB_CUR_SETCUR;
info->fbops->fb_cursor(info, &info->cursor);
}
@@ -220,7 +221,7 @@ static void cursor_timer_handler(unsigned long dev_addr)
struct fb_info *info = (struct fb_info *) dev_addr;
schedule_work(&info->queue);
- cursor_timer.expires = jiffies + HZ / 50;
+ cursor_timer.expires = jiffies + HZ / 5;
add_timer(&cursor_timer);
}
@@ -663,7 +664,6 @@ static const char *fbcon_startup(void)
irqres = request_irq(IRQ_VSYNCPULSE, fb_vbl_handler, SA_SHIRQ,
"framebuffer vbl", info);
#endif
-
if (irqres) {
cursor_blink_rate = DEFAULT_CURSOR_BLINK_RATE;
cursor_timer.expires = jiffies + HZ / 50;
@@ -986,13 +986,12 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
- int w = (vc->vc_font.width + 7) >> 3, c;
struct display *p = &fb_display[vc->vc_num];
+ int w = (vc->vc_font.width + 7) >> 3, c;
int y = real_y(p, vc->vc_y);
struct fb_cursor cursor;
- static char mask[64];
- static int shape;
-
+ char *mask = NULL;
+
if (mode & CM_SOFTBACK) {
mode &= ~CM_SOFTBACK;
if (softback_lines) {
@@ -1008,20 +1007,12 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
cursor.image.data = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
cursor.image.depth = 1;
-
+
switch (mode) {
case CM_ERASE:
if (info->cursor.rop == ROP_XOR) {
cursor.set = 0;
- cursor.image.dx = info->cursor.image.dx;
- cursor.image.dy = info->cursor.image.dy;
- cursor.image.width = info->cursor.image.width;
- cursor.image.height = info->cursor.image.height;
- cursor.image.fg_color = info->cursor.image.fg_color;
- cursor.image.bg_color = info->cursor.image.bg_color;
- cursor.mask = mask;
cursor.rop = ROP_COPY;
-
info->fbops->fb_cursor(info, &cursor);
}
break;
@@ -1050,10 +1041,13 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
cursor.set |= FB_CUR_SETSIZE;
}
- if ((vc->vc_cursor_type & 0x0f) != shape) {
+ if ((vc->vc_cursor_type & 0x0f) != p->cursor_shape) {
int cur_height, size, i = 0;
- shape = vc->vc_cursor_type & 0x0f;
+ mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
+ if (!mask) return;
+
+ p->cursor_shape = vc->vc_cursor_type & 0x0f;
cursor.set |= FB_CUR_SETSHAPE;
switch (vc->vc_cursor_type & 0x0f) {
@@ -1083,11 +1077,13 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
size = cur_height * w;
while (size--)
mask[i++] = 0xff;
+ cursor.mask = mask;
}
- cursor.mask = mask;
cursor.rop = ROP_XOR;
info->fbops->fb_cursor(info, &cursor);
+ if (mask)
+ kfree(mask);
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
break;
}
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 1ba314268084..97d7a1a74aa3 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -33,6 +33,7 @@ struct display {
u_short scrollmode; /* Scroll Method */
short yscroll; /* Hardware scrolling */
int vrows; /* number of virtual rows */
+ int cursor_shape;
};
/* drivers/video/console/fbcon.c */
diff --git a/drivers/video/softcursor.c b/drivers/video/softcursor.c
index e7d03ec12cc6..67ecd19c695a 100644
--- a/drivers/video/softcursor.c
+++ b/drivers/video/softcursor.c
@@ -25,7 +25,8 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
u8 *dst, src[64];
info->cursor.enable = (cursor->set & FB_CUR_SETCUR) ? 1 : 0;
-
+ info->cursor.rop = cursor->rop;
+
if (cursor->set & FB_CUR_SETSIZE) {
info->cursor.image.height = cursor->image.height;
info->cursor.image.width = cursor->image.width;
@@ -56,17 +57,25 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
size = d_pitch * info->cursor.image.height + buf_align;
size &= ~buf_align;
dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
+
+ if (cursor->set & FB_CUR_SETSHAPE) {
+ if (!cursor->mask) return -EINVAL;
+ if (info->cursor.mask)
+ kfree(info->cursor.mask);
+ info->cursor.mask = kmalloc(dsize, GFP_ATOMIC);
+ memcpy(info->cursor.mask, cursor->mask, dsize);
+ }
if (info->cursor.enable) {
- switch (cursor->rop) {
+ switch (info->cursor.rop) {
case ROP_XOR:
for (i = 0; i < size; i++)
- src[i] = cursor->image.data[i] ^ cursor->mask[i];
+ src[i] = cursor->image.data[i] ^ info->cursor.mask[i];
break;
case ROP_COPY:
default:
for (i = 0; i < size; i++)
- src[i] = cursor->image.data[i] & cursor->mask[i];
+ src[i] = cursor->image.data[i] & info->cursor.mask[i];
break;
}
} else {
@@ -76,7 +85,6 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
move_buf_aligned(info, dst, src, d_pitch, s_pitch,info->cursor.image.height);
info->cursor.image.data = dst;
- info->cursor.rop = cursor->rop;
info->fbops->fb_imageblit(info, &info->cursor.image);
atomic_dec(&info->pixmap.count);