summaryrefslogtreecommitdiffstats
path: root/sys/dev/vt
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2014-09-03 13:40:02 +0000
committeremaste <emaste@FreeBSD.org>2014-09-03 13:40:02 +0000
commita8ec7c36a31697d414a0126c83fea550ce6e0be5 (patch)
treeeda56cfa52f7137ceccd6fc49a5d120eb30f183c /sys/dev/vt
parent97f9055278bfaea0a736cacc6f58b1a794f9cb7e (diff)
downloadFreeBSD-src-a8ec7c36a31697d414a0126c83fea550ce6e0be5.zip
FreeBSD-src-a8ec7c36a31697d414a0126c83fea550ce6e0be5.tar.gz
MFC vt(4) mouse cursor improvements from dumbbell:
r270269: vt(4): Handle global and per-window mouse cursor toggle in one place Before the global flag was set/unset using the CONS_MOUSECTL ioctl, and the per-window flag through the MOUSE_SETLEVEL or MOUSE_SETMODE ioctls. Also, if the cursor is already enabled/disabled, return immediatly. This avoids to reset the cursor's position to the center of the screen. This matches syscons' behavior. While here, remove a trailing space and a redundant variable declaration. r270271: vt(4): Mark cursor old position as dirty before reading the dirty area Otherwise, the redraw is done during the next vt_flush run. r270272: vt(4): If the cursor is globally disabled, don't mark its position as dirty This avoids unnecessary redraw. In particular, during boot, where the cursor is disabled and its fake position is [0;0], this triggered a refresh of the whole screen each time vt_flush() is called. r270273: vt(4): If the cursor didn't move, don't mark its position as dirty Currently, this has no effect, because the cursor is always redrawn anyway. But this will be useful after improvements to the vd_bitbltchr_t callback API. The vt_device structure members used to store the position of the cursor as of the last redraw are renamed from vd_mdirty{x,y} to vd_mold{x,y}. The associated comment is fixed too. Also, their value is now expressed in pixels, not in character columns/row. r270275: vt(4): Mark the current cursor position as dirty Like r270273, this has no effect for now, because the cursor is always drawn. This is in preparation of future changes to vd_bitbltchr_t API. r270278: vt(4): Mark cursor position as dirty when we enable/disable it Sponsored by: The FreeBSD Foundation
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