summaryrefslogtreecommitdiffstats
path: root/sys/dev/vt
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/vt')
-rw-r--r--sys/dev/vt/vt.h8
-rw-r--r--sys/dev/vt/vt_core.c84
-rw-r--r--sys/dev/vt/vt_sysmouse.c7
3 files changed, 68 insertions, 31 deletions
diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index f202540..7f19b0f 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -117,10 +117,10 @@ struct vt_device {
struct vt_window *vd_markedwin; /* (?) Copy/paste buf owner. */
const struct vt_driver *vd_driver; /* (c) Graphics driver. */
void *vd_softc; /* (u) Driver data. */
- uint16_t vd_mx; /* (?) Mouse X. */
- uint16_t vd_my; /* (?) Mouse Y. */
- vt_axis_t vd_mdirtyx; /* (?) Screen width. */
- vt_axis_t vd_mdirtyy; /* (?) Screen height. */
+ uint16_t vd_mx; /* (?) Current mouse X. */
+ uint16_t vd_my; /* (?) current mouse Y. */
+ vt_axis_t vd_moldx; /* (?) Mouse X as of last redraw. */
+ vt_axis_t vd_moldy; /* (?) Mouse Y as of last redraw. */
uint32_t vd_mstate; /* (?) Mouse state. */
term_pos_t vd_offset; /* (?) Pixel offset. */
vt_axis_t vd_width; /* (?) Screen width. */
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index a2ffe62..4d4ecd6 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -825,6 +825,45 @@ vt_flush(struct vt_device *vd)
if (vd->vd_flags & VDF_SPLASH || vw->vw_flags & VWF_BUSY)
return;
+#ifndef SC_NO_CUTPASTE
+ if ((vd->vd_flags & VDF_MOUSECURSOR) && /* Mouse support enabled. */
+ !(vw->vw_flags & VWF_MOUSE_HIDE)) { /* Cursor displayed. */
+ if (vd->vd_moldx != vd->vd_mx ||
+ vd->vd_moldy != vd->vd_my) {
+ /*
+ * Mark last mouse position as dirty to erase.
+ *
+ * FIXME: The font size could be different among
+ * all windows, so the column/row calculation
+ * below isn't correct for all windows.
+ *
+ * FIXME: The cursor can span more than one
+ * character cell. vtbuf_mouse_cursor_position
+ * marks surrounding cells as dirty. But due
+ * to font size possibly inconsistent across
+ * windows, this may not be sufficient. This
+ * causes part of the cursor to not be erased.
+ *
+ * FIXME: The vt_buf lock is acquired twice in a
+ * row.
+ */
+ vtbuf_mouse_cursor_position(&vw->vw_buf,
+ vd->vd_moldx / vf->vf_width,
+ vd->vd_moldy / vf->vf_height);
+ vtbuf_mouse_cursor_position(&vw->vw_buf,
+ vd->vd_mx / vf->vf_width,
+ vd->vd_my / vf->vf_height);
+
+ /*
+ * Save point of last mouse cursor to erase it
+ * later.
+ */
+ vd->vd_moldx = vd->vd_mx;
+ vd->vd_moldy = vd->vd_my;
+ }
+ }
+#endif
+
vtbuf_undirty(&vw->vw_buf, &tarea, &tmask);
vt_termsize(vd, vf, &size);
@@ -837,14 +876,6 @@ vt_flush(struct vt_device *vd)
vd->vd_flags &= ~VDF_INVALID;
}
-#ifndef SC_NO_CUTPASTE
- if ((vw->vw_flags & VWF_MOUSE_HIDE) == 0) {
- /* Mark last mouse position as dirty to erase. */
- vtbuf_mouse_cursor_position(&vw->vw_buf, vd->vd_mdirtyx,
- vd->vd_mdirtyy);
- }
-#endif
-
for (row = tarea.tr_begin.tp_row; row < tarea.tr_end.tp_row; row++) {
if (!VTBUF_DIRTYROW(&tmask, row))
continue;
@@ -884,9 +915,6 @@ vt_flush(struct vt_device *vd)
vd->vd_offset.tp_row + vd->vd_my,
vd->vd_offset.tp_col + vd->vd_mx,
w, h, TC_WHITE, TC_BLACK);
- /* Save point of last mouse cursor to erase it later. */
- vd->vd_mdirtyx = vd->vd_mx / vf->vf_width;
- vd->vd_mdirtyy = vd->vd_my / vf->vf_height;
}
#endif
}
@@ -1524,6 +1552,15 @@ vt_mouse_state(int show)
vw->vw_flags &= ~VWF_MOUSE_HIDE;
break;
}
+
+ /*
+ * Mark mouse position as dirty.
+ *
+ * FIXME: See comments in vt_flush().
+ */
+ vtbuf_mouse_cursor_position(&vw->vw_buf,
+ vd->vd_mx / vw->vw_font->vf_width,
+ vd->vd_my / vw->vw_font->vf_height);
}
#endif
@@ -1696,7 +1733,7 @@ skip_thunk:
/* XXX: other fields! */
return (0);
}
- case CONS_GETVERS:
+ case CONS_GETVERS:
*(int *)data = 0x200;
return (0);
case CONS_MODEINFO:
@@ -1706,20 +1743,28 @@ skip_thunk:
mouse_info_t *mouse = (mouse_info_t*)data;
/*
- * This has no effect on vt(4). We don't draw any mouse
- * cursor. Just ignore MOUSE_HIDE and MOUSE_SHOW to
- * prevent excessive errors. All the other commands
+ * All the commands except MOUSE_SHOW nd MOUSE_HIDE
* should not be applied to individual TTYs, but only to
* consolectl.
*/
switch (mouse->operation) {
case MOUSE_HIDE:
- vd->vd_flags &= ~VDF_MOUSECURSOR;
+ if (vd->vd_flags & VDF_MOUSECURSOR) {
+ vd->vd_flags &= ~VDF_MOUSECURSOR;
+#ifndef SC_NO_CUTPASTE
+ vt_mouse_state(VT_MOUSE_HIDE);
+#endif
+ }
return (0);
case MOUSE_SHOW:
- vd->vd_mx = vd->vd_width / 2;
- vd->vd_my = vd->vd_height / 2;
- vd->vd_flags |= VDF_MOUSECURSOR;
+ if (!(vd->vd_flags & VDF_MOUSECURSOR)) {
+ vd->vd_flags |= VDF_MOUSECURSOR;
+ vd->vd_mx = vd->vd_width / 2;
+ vd->vd_my = vd->vd_height / 2;
+#ifndef SC_NO_CUTPASTE
+ vt_mouse_state(VT_MOUSE_SHOW);
+#endif
+ }
return (0);
default:
return (EINVAL);
@@ -1742,7 +1787,6 @@ skip_thunk:
}
case GIO_SCRNMAP: {
scrmap_t *sm = (scrmap_t *)data;
- int i;
/* We don't have screen maps, so return a handcrafted one. */
for (i = 0; i < 256; i++)
diff --git a/sys/dev/vt/vt_sysmouse.c b/sys/dev/vt/vt_sysmouse.c
index 21b2400..189bcad 100644
--- a/sys/dev/vt/vt_sysmouse.c
+++ b/sys/dev/vt/vt_sysmouse.c
@@ -347,9 +347,6 @@ sysmouse_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
return (EINVAL);
sysmouse_level = level;
-#ifndef SC_NO_CUTPASTE
- vt_mouse_state((level == 0)?VT_MOUSE_SHOW:VT_MOUSE_HIDE);
-#endif
return (0);
}
case MOUSE_SETMODE: {
@@ -362,10 +359,6 @@ sysmouse_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
case 0:
case 1:
sysmouse_level = mode->level;
-#ifndef SC_NO_CUTPASTE
- vt_mouse_state((mode->level == 0)?VT_MOUSE_SHOW:
- VT_MOUSE_HIDE);
-#endif
break;
default:
return (EINVAL);
OpenPOWER on IntegriCloud