Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Sep 2014 13:40:02 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r271022 - stable/10/sys/dev/vt
Message-ID:  <201409031340.s83De2qs037559@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: emaste
Date: Wed Sep  3 13:40:02 2014
New Revision: 271022
URL: http://svnweb.freebsd.org/changeset/base/271022

Log:
  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

Modified:
  stable/10/sys/dev/vt/vt.h
  stable/10/sys/dev/vt/vt_core.c
  stable/10/sys/dev/vt/vt_sysmouse.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/vt/vt.h
==============================================================================
--- stable/10/sys/dev/vt/vt.h	Wed Sep  3 13:31:08 2014	(r271021)
+++ stable/10/sys/dev/vt/vt.h	Wed Sep  3 13:40:02 2014	(r271022)
@@ -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. */

Modified: stable/10/sys/dev/vt/vt_core.c
==============================================================================
--- stable/10/sys/dev/vt/vt_core.c	Wed Sep  3 13:31:08 2014	(r271021)
+++ stable/10/sys/dev/vt/vt_core.c	Wed Sep  3 13:40:02 2014	(r271022)
@@ -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++)

Modified: stable/10/sys/dev/vt/vt_sysmouse.c
==============================================================================
--- stable/10/sys/dev/vt/vt_sysmouse.c	Wed Sep  3 13:31:08 2014	(r271021)
+++ stable/10/sys/dev/vt/vt_sysmouse.c	Wed Sep  3 13:40:02 2014	(r271022)
@@ -347,9 +347,6 @@ sysmouse_ioctl(struct cdev *dev, u_long 
 			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 
 		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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409031340.s83De2qs037559>