* [PATCH] Fix cursor + selection
@ 2003-09-02 1:40 Chris Heath
2003-09-02 17:15 ` James Simmons
0 siblings, 1 reply; 2+ messages in thread
From: Chris Heath @ 2003-09-02 1:40 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: Chris Heath
I noticed that the framebuffer console overwrites the mouse pointer and
selected text when the cursor flashes.
The attached patch fixes that. It is rather long, but basically all
I've done is moved a huge chunk of code from fbcon_cursor into a helper
function, and called that helper from fbcon_putc and fbcon_putcs.
The patch is against James's latest fbdev patch that he posted to
linux-kernel.
Chris
--- linux-2.6.0-test4-fbdev/drivers/video/console/fbcon.c 2003-09-01 20:13:17.000000000 -0400
+++ linux-2.6.0-test4-cdh1/drivers/video/console/fbcon.c 2003-09-01 19:55:07.000000000 -0400
@@ -811,6 +811,116 @@
}
}
+static void update_cursor(struct vc_data *vc, struct fb_info *info, int c)
+{
+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ unsigned int scan_align = info->sprite.scan_align - 1;
+ unsigned int buf_align = info->sprite.buf_align - 1;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+ int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+ struct display *p = &fb_display[vc->vc_num];
+ int y = real_y(p, vc->vc_y), d_pitch, dsize;
+ int s_pitch = (vc->vc_font.width + 7) >> 3;
+ int size = s_pitch * vc->vc_font.height;
+ struct fb_cursor cursor;
+ u8 *src, *dst;
+
+ memset(&cursor, 0, sizeof(struct fb_cursor));
+ if (info->cursor.image.fg_color != attr_fgcol(fgshift, c) ||
+ info->cursor.image.bg_color != attr_bgcol(bgshift, c)) {
+ cursor.image.fg_color = attr_fgcol(fgshift, c);
+ cursor.image.bg_color = attr_bgcol(bgshift, c);
+ cursor.image.depth = 1;
+ cursor.set |= FB_CUR_SETCMAP;
+ }
+ src = vc->vc_font.data + ((c & charmask) * size);
+ if (info->cursor.image.fg_color != attr_fgcol(fgshift, c) ||
+ info->cursor.image.bg_color != attr_bgcol(bgshift, c)) {
+ cursor.image.fg_color = attr_fgcol(fgshift, c);
+ cursor.image.bg_color = attr_bgcol(bgshift, c);
+ cursor.image.depth = 1;
+ cursor.set |= FB_CUR_SETCMAP;
+ }
+
+ if ((info->cursor.image.dx != (vc->vc_font.width * vc->vc_x)) ||
+ (info->cursor.image.dy != (vc->vc_font.height * y))) {
+ cursor.image.dx = vc->vc_font.width * vc->vc_x;
+ cursor.image.dy = vc->vc_font.height * y;
+ cursor.set |= FB_CUR_SETPOS;
+ }
+
+ if (info->cursor.image.height != vc->vc_font.height ||
+ info->cursor.image.width != vc->vc_font.width) {
+ cursor.image.height = vc->vc_font.height;
+ cursor.image.width = vc->vc_font.width;
+ cursor.set |= FB_CUR_SETSIZE;
+ }
+
+ if (info->cursor.hot.x || info->cursor.hot.y) {
+ cursor.hot.x = cursor.hot.y = 0;
+ cursor.set |= FB_CUR_SETHOT;
+ }
+
+ d_pitch = (s_pitch + scan_align) & ~scan_align;
+ dsize = d_pitch * vc->vc_font.height + buf_align;
+ dsize &= ~buf_align;
+
+ if ((cursor.set & FB_CUR_SETSIZE) ||
+ ((vc->vc_cursor_type & 0x0f) != p->cursor_shape)) {
+ char *mask = kmalloc(dsize, GFP_ATOMIC);
+ int cur_height, i, j, k;
+
+ if (!mask)
+ return;
+
+ memset(mask, 0, dsize);
+
+ if (info->cursor.mask)
+ kfree(info->cursor.mask);
+ info->cursor.mask = mask;
+
+ p->cursor_shape = vc->vc_cursor_type & 0x0f;
+
+ switch (vc->vc_cursor_type & 0x0f) {
+ case CUR_NONE:
+ cur_height = 0;
+ break;
+ case CUR_UNDERLINE:
+ cur_height = (vc->vc_font.height < 10) ? 1 : 2;
+ break;
+ case CUR_LOWER_THIRD:
+ cur_height = vc->vc_font.height/3;
+ break;
+ case CUR_LOWER_HALF:
+ cur_height = vc->vc_font.height >> 1;
+ break;
+ case CUR_TWO_THIRDS:
+ cur_height = (vc->vc_font.height << 1)/3;
+ break;
+ case CUR_BLOCK:
+ default:
+ cur_height = vc->vc_font.height;
+ break;
+ }
+ i = (vc->vc_font.height - cur_height) * d_pitch;
+ for (j = 0; j < cur_height; j++) {
+ for (k = 0; k < s_pitch; k++)
+ mask[i++] = 0xff;
+ i += (d_pitch - s_pitch);
+ }
+ }
+ src = vc->vc_font.data + ((c & charmask) * size);
+ dst = fb_get_buffer_offset(info, &info->sprite, dsize);
+ move_buf_aligned(info, &info->sprite, dst, src, d_pitch, s_pitch,
+ vc->vc_font.height);
+ info->cursor.image.data = dst;
+ cursor.set |= FB_CUR_SETSHAPE;
+ info->cursor.rop = ROP_XOR;
+ info->fbops->fb_cursor(info, &cursor);
+ atomic_dec(&info->sprite.count);
+ smp_mb__after_atomic_dec();
+}
+
/* ====================================================================== */
@@ -917,6 +1027,9 @@
info->fbops->fb_imageblit(info, &image);
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
+
+ if (ypos == vc->vc_y && xpos == vc->vc_x)
+ update_cursor(vc, info, c);
}
static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
@@ -932,22 +1045,17 @@
return;
accel_putcs(vc, info, s, count, real_y(p, ypos), xpos);
+
+ if (ypos == vc->vc_y && xpos <= vc->vc_x && xpos + count > vc->vc_x)
+ update_cursor(vc, info, s[vc->vc_x - xpos]);
}
static void fbcon_cursor(struct vc_data *vc, int mode)
{
struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
- unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- unsigned int scan_align = info->sprite.scan_align - 1;
- unsigned int buf_align = info->sprite.buf_align - 1;
- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
- int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
struct display *p = &fb_display[vc->vc_num];
- int y = real_y(p, vc->vc_y), d_pitch, dsize;
- int s_pitch = (vc->vc_font.width + 7) >> 3;
- int size = s_pitch * vc->vc_font.height, c;
- struct fb_cursor cursor;
- u8 *src, *dst;
+ int y = real_y(p, vc->vc_y);
+ int c;
if (mode & CM_SOFTBACK) {
mode &= ~CM_SOFTBACK;
@@ -967,95 +1075,11 @@
}
if (mode != CM_ERASE) {
- memset(&cursor, 0, sizeof(struct fb_cursor));
info->cursor.enable = 1;
c = scr_readw((u16 *) vc->vc_pos);
+ update_cursor(vc, info, c);
- src = vc->vc_font.data + ((c & charmask) * size);
- if (info->cursor.image.fg_color != attr_fgcol(fgshift, c) ||
- info->cursor.image.bg_color != attr_bgcol(bgshift, c)) {
- cursor.image.fg_color = attr_fgcol(fgshift, c);
- cursor.image.bg_color = attr_bgcol(bgshift, c);
- cursor.image.depth = 1;
- cursor.set |= FB_CUR_SETCMAP;
- }
-
- if ((info->cursor.image.dx != (vc->vc_font.width * vc->vc_x)) ||
- (info->cursor.image.dy != (vc->vc_font.height * y))) {
- cursor.image.dx = vc->vc_font.width * vc->vc_x;
- cursor.image.dy = vc->vc_font.height * y;
- cursor.set |= FB_CUR_SETPOS;
- }
-
- if (info->cursor.image.height != vc->vc_font.height ||
- info->cursor.image.width != vc->vc_font.width) {
- cursor.image.height = vc->vc_font.height;
- cursor.image.width = vc->vc_font.width;
- cursor.set |= FB_CUR_SETSIZE;
- }
-
- if (info->cursor.hot.x || info->cursor.hot.y) {
- cursor.hot.x = cursor.hot.y = 0;
- cursor.set |= FB_CUR_SETHOT;
- }
-
- src = vc->vc_font.data + ((c & charmask) * size);
-
- d_pitch = (s_pitch + scan_align) & ~scan_align;
- dsize = d_pitch * vc->vc_font.height + buf_align;
- dsize &= ~buf_align;
- dst = fb_get_buffer_offset(info, &info->sprite, dsize);
- move_buf_aligned(info, &info->sprite, dst, src, d_pitch, s_pitch, vc->vc_font.height);
- info->cursor.image.data = dst;
- cursor.set |= FB_CUR_SETSHAPE;
-
- if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape)) {
- char *mask = kmalloc(dsize, GFP_ATOMIC);
- int cur_height, i, j, k;
-
- if (!mask) return;
-
- memset(mask, 0, dsize);
-
- if (info->cursor.mask)
- kfree(info->cursor.mask);
- info->cursor.mask = mask;
-
- p->cursor_shape = vc->vc_cursor_type & 0x0f;
-
- switch (vc->vc_cursor_type & 0x0f) {
- case CUR_NONE:
- cur_height = 0;
- break;
- case CUR_UNDERLINE:
- cur_height = (vc->vc_font.height < 10) ? 1 : 2;
- break;
- case CUR_LOWER_THIRD:
- cur_height = vc->vc_font.height/3;
- break;
- case CUR_LOWER_HALF:
- cur_height = vc->vc_font.height >> 1;
- break;
- case CUR_TWO_THIRDS:
- cur_height = (vc->vc_font.height << 1)/3;
- break;
- case CUR_BLOCK:
- default:
- cur_height = vc->vc_font.height;
- break;
- }
- i = (vc->vc_font.height - cur_height) * d_pitch;
- for (j = 0; j < cur_height; j++) {
- for (k = 0; k < s_pitch; k++)
- mask[i++] = 0xff;
- i += (d_pitch - s_pitch);
- }
- }
- info->cursor.rop = ROP_XOR;
- info->fbops->fb_cursor(info, &cursor);
- atomic_dec(&info->sprite.count);
- smp_mb__after_atomic_dec();
mod_timer(&cursor_timer, jiffies + HZ/5);
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
}
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Fix cursor + selection
2003-09-02 1:40 [PATCH] Fix cursor + selection Chris Heath
@ 2003-09-02 17:15 ` James Simmons
0 siblings, 0 replies; 2+ messages in thread
From: James Simmons @ 2003-09-02 17:15 UTC (permalink / raw)
To: Chris Heath; +Cc: linux-fbdev-devel
> I noticed that the framebuffer console overwrites the mouse pointer and
> selected text when the cursor flashes.
>
> The attached patch fixes that. It is rather long, but basically all
> I've done is moved a huge chunk of code from fbcon_cursor into a helper
> function, and called that helper from fbcon_putc and fbcon_putcs.
>
> The patch is against James's latest fbdev patch that he posted to
> linux-kernel.
Than you for the patch. Over the weekend I fixed up the cursor code and we
pretty much come to the same results. I ported ove rthe Mach64 cursor to
the new cursor api. Also the NVIDIA driver is done. A little more work is
needed and I have to rework the soft cursor.
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2003-09-02 17:16 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-09-02 1:40 [PATCH] Fix cursor + selection Chris Heath
2003-09-02 17:15 ` James Simmons
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).