diff options
Diffstat (limited to 'drivers/video')
| -rw-r--r-- | drivers/video/console/fbcon.c | 32 | ||||
| -rw-r--r-- | drivers/video/console/fbcon.h | 1 | ||||
| -rw-r--r-- | drivers/video/softcursor.c | 18 |
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); |
