Refactor and simplify hiding the mouse cursor and fix bugs caused by

complications in the previous methods.

r346761 broke showing the mouse cursor after changing its state from
off to on (including initially), since showing the cursor uses the
state to decide whether to actually show and the state variable was
not changed until after null showing.  Moving the mouse or copying
under the cursor fixed the problem.  Fix this and similar problems for
the on to off transition by changing the state variable before drawing
the cursor.

r346641 failed to turn off the mouse cursor on exit from vgl.  It hid
the cursor only temporarily for clearing.  This doesn't change the state
variable, so unhiding the cursor after clearing restored the cursor if its
state was on.  Fix this by changing its state to VGL_MOUSEHIDE using the
application API for changing the state.

Remove the VGLMouseVisible state variable and the extra states given by it.
This was an optimization that was just an obfuscation in at least the
previous version.

Staticize VGLMouseAction().  Remove VGLMousePointerShow/Hide() except as
internals in __VGLMouseMode().  __VGLMouseMouseMode() is the same as the
application API VGLMouseMouseMode() except it returns the previous mode
which callers need to know to restore it after hiding the cursor.

Use the refactoring to make minor improvements in a simpler way than was
possible:
- in VGLMouseAction(), only hide and and unhide the mouse cursor if the
  mouse moved
- in VGLClear(), only hide and and unhide the mouse cursor if the clearing
  method would otherwise clear the cursor.
This commit is contained in:
bde 2019-04-29 14:13:53 +00:00
parent b6758fe7e2
commit 28164a5b31
4 changed files with 46 additions and 55 deletions

View File

@ -77,7 +77,7 @@ struct vt_mode smode;
signal(SIGUSR2, SIG_IGN); signal(SIGUSR2, SIG_IGN);
VGLSwitchPending = 0; VGLSwitchPending = 0;
VGLAbortPending = 0; VGLAbortPending = 0;
VGLMousePointerHide(); VGLMouseMode(VGL_MOUSEHIDE);
if (VGLMem != MAP_FAILED) { if (VGLMem != MAP_FAILED) {
VGLClear(VGLDisplay, 0); VGLClear(VGLDisplay, 0);

View File

@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$");
#include <sys/fbio.h> #include <sys/fbio.h>
#include "vgl.h" #include "vgl.h"
static void VGLMouseAction(int dummy);
#define BORDER 0xff /* default border -- light white in rgb 3:3:2 */ #define BORDER 0xff /* default border -- light white in rgb 3:3:2 */
#define INTERIOR 0xa0 /* default interior -- red in rgb 3:3:2 */ #define INTERIOR 0xa0 /* default interior -- red in rgb 3:3:2 */
#define X 0xff /* any nonzero in And mask means part of cursor */ #define X 0xff /* any nonzero in And mask means part of cursor */
@ -88,7 +90,6 @@ static VGLBitmap VGLMouseStdAndMask =
static VGLBitmap VGLMouseStdOrMask = static VGLBitmap VGLMouseStdOrMask =
VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask); VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask);
static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask; static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
static int VGLMouseVisible = 0;
static int VGLMouseShown = VGL_MOUSEHIDE; static int VGLMouseShown = VGL_MOUSEHIDE;
static int VGLMouseXpos = 0; static int VGLMouseXpos = 0;
static int VGLMouseYpos = 0; static int VGLMouseYpos = 0;
@ -102,51 +103,44 @@ static volatile sig_atomic_t VGLMsuppressint;
VGLMouseAction(0); \ VGLMouseAction(0); \
} while (0) } while (0)
void int
VGLMousePointerShow() __VGLMouseMode(int mode)
{ {
if (!VGLMouseVisible) { int oldmode;
INTOFF();
VGLMouseVisible = 1;
__VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, VGLDisplay,
VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, -MOUSE_IMG_SIZE);
INTON();
}
}
void
VGLMousePointerHide()
{
if (VGLMouseVisible) {
INTOFF(); INTOFF();
VGLMouseVisible = 0; oldmode = VGLMouseShown;
if (mode == VGL_MOUSESHOW) {
if (VGLMouseShown == VGL_MOUSEHIDE) {
VGLMouseShown = VGL_MOUSESHOW;
__VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, VGLDisplay, __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, VGLDisplay,
VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); VGLMouseXpos, VGLMouseYpos,
INTON(); MOUSE_IMG_SIZE, -MOUSE_IMG_SIZE);
} }
}
else {
if (VGLMouseShown == VGL_MOUSESHOW) {
VGLMouseShown = VGL_MOUSEHIDE;
__VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, VGLDisplay,
VGLMouseXpos, VGLMouseYpos,
MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
}
}
INTON();
return oldmode;
} }
void void
VGLMouseMode(int mode) VGLMouseMode(int mode)
{ {
if (mode == VGL_MOUSESHOW) { __VGLMouseMode(mode);
if (VGLMouseShown == VGL_MOUSEHIDE) {
VGLMousePointerShow();
VGLMouseShown = VGL_MOUSESHOW;
}
}
else {
if (VGLMouseShown == VGL_MOUSESHOW) {
VGLMousePointerHide();
VGLMouseShown = VGL_MOUSEHIDE;
}
}
} }
void static void
VGLMouseAction(int dummy) VGLMouseAction(int dummy)
{ {
struct mouse_info mouseinfo; struct mouse_info mouseinfo;
int mousemode;
if (VGLMsuppressint) { if (VGLMsuppressint) {
VGLMintpending = 1; VGLMintpending = 1;
@ -157,13 +151,14 @@ VGLMouseAction(int dummy)
VGLMintpending = 0; VGLMintpending = 0;
mouseinfo.operation = MOUSE_GETINFO; mouseinfo.operation = MOUSE_GETINFO;
ioctl(0, CONS_MOUSECTL, &mouseinfo); ioctl(0, CONS_MOUSECTL, &mouseinfo);
if (VGLMouseShown == VGL_MOUSESHOW) if (VGLMouseXpos != mouseinfo.u.data.x ||
VGLMousePointerHide(); VGLMouseYpos != mouseinfo.u.data.y) {
mousemode = __VGLMouseMode(VGL_MOUSEHIDE);
VGLMouseXpos = mouseinfo.u.data.x; VGLMouseXpos = mouseinfo.u.data.x;
VGLMouseYpos = mouseinfo.u.data.y; VGLMouseYpos = mouseinfo.u.data.y;
__VGLMouseMode(mousemode);
}
VGLMouseButtons = mouseinfo.u.data.buttons; VGLMouseButtons = mouseinfo.u.data.buttons;
if (VGLMouseShown == VGL_MOUSESHOW)
VGLMousePointerShow();
/* /*
* Loop to handle any new (suppressed) signals. This is INTON() without * Loop to handle any new (suppressed) signals. This is INTON() without
@ -178,8 +173,9 @@ VGLMouseAction(int dummy)
void void
VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask) VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
{ {
if (VGLMouseShown == VGL_MOUSESHOW) int mousemode;
VGLMousePointerHide();
mousemode = __VGLMouseMode(VGL_MOUSEHIDE);
VGLMouseAndMask = AndMask; VGLMouseAndMask = AndMask;
@ -191,8 +187,7 @@ VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
VGLBitmapAllocateBits(VGLMouseOrMask); VGLBitmapAllocateBits(VGLMouseOrMask);
VGLBitmapCvt(OrMask, VGLMouseOrMask); VGLBitmapCvt(OrMask, VGLMouseOrMask);
if (VGLMouseShown == VGL_MOUSESHOW) __VGLMouseMode(mousemode);
VGLMousePointerShow();
} }
void void

View File

@ -465,14 +465,11 @@ void
VGLClear(VGLBitmap *object, u_long color) VGLClear(VGLBitmap *object, u_long color)
{ {
VGLBitmap src; VGLBitmap src;
int i, len, mouseoverlap, offset; int i, len, mousemode, offset;
VGLCheckSwitch(); VGLCheckSwitch();
if (object == VGLDisplay) { if (object == VGLDisplay) {
VGLMouseFreeze(); VGLMouseFreeze();
mouseoverlap = VGLMouseOverlap(0, 0, object->VXsize, object->VYsize);
if (mouseoverlap)
VGLMousePointerHide();
VGLClear(&VGLVDisplay, color); VGLClear(&VGLVDisplay, color);
} else if (object->Type != MEMBUF) } else if (object->Type != MEMBUF)
return; /* invalid */ return; /* invalid */
@ -503,14 +500,17 @@ VGLClear(VGLBitmap *object, u_long color)
break; break;
case VIDBUF8X: case VIDBUF8X:
mousemode = __VGLMouseMode(VGL_MOUSEHIDE);
/* XXX works only for Xsize % 4 = 0 */ /* XXX works only for Xsize % 4 = 0 */
outb(0x3c6, 0xff); outb(0x3c6, 0xff);
outb(0x3c4, 0x02); outb(0x3c5, 0x0f); outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
memset(object->Bitmap, (byte)color, VGLAdpInfo.va_line_width*object->VYsize); memset(object->Bitmap, (byte)color, VGLAdpInfo.va_line_width*object->VYsize);
__VGLMouseMode(mousemode);
break; break;
case VIDBUF4: case VIDBUF4:
case VIDBUF4S: case VIDBUF4S:
mousemode = __VGLMouseMode(VGL_MOUSEHIDE);
/* XXX works only for Xsize % 8 = 0 */ /* XXX works only for Xsize % 8 = 0 */
outb(0x3c4, 0x02); outb(0x3c5, 0x0f); outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */ outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */
@ -524,13 +524,11 @@ VGLClear(VGLBitmap *object, u_long color)
offset += len; offset += len;
} }
outb(0x3ce, 0x05); outb(0x3cf, 0x00); outb(0x3ce, 0x05); outb(0x3cf, 0x00);
__VGLMouseMode(mousemode);
break; break;
} }
if (object == VGLDisplay) { if (object == VGLDisplay)
if (mouseoverlap)
VGLMousePointerShow();
VGLMouseUnFreeze(); VGLMouseUnFreeze();
}
} }
static inline u_long static inline u_long

View File

@ -125,10 +125,8 @@ int VGLSetVScreenSize(VGLBitmap *object, int VXsize, int VYsize);
int VGLPanScreen(VGLBitmap *object, int x, int y); int VGLPanScreen(VGLBitmap *object, int x, int y);
int VGLSetSegment(unsigned int offset); int VGLSetSegment(unsigned int offset);
/* mouse.c */ /* mouse.c */
void VGLMousePointerShow(void); int __VGLMouseMode(int mode);
void VGLMousePointerHide(void);
void VGLMouseMode(int mode); void VGLMouseMode(int mode);
void VGLMouseAction(int dummy);
void VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask); void VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask);
void VGLMouseSetStdImage(void); void VGLMouseSetStdImage(void);
int VGLMouseInit(int mode); int VGLMouseInit(int mode);