Index: head/lib/libvgl/mouse.c =================================================================== --- head/lib/libvgl/mouse.c (revision 346894) +++ head/lib/libvgl/mouse.c (revision 346895) @@ -1,336 +1,426 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1991-1997 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include "vgl.h" static void VGLMouseAction(int dummy); #define BORDER 0xff /* default border -- light white in rgb 3:3:2 */ #define INTERIOR 0xa0 /* default interior -- red in rgb 3:3:2 */ +#define LARGE_MOUSE_IMG_XSIZE 19 +#define LARGE_MOUSE_IMG_YSIZE 32 +#define SMALL_MOUSE_IMG_XSIZE 10 +#define SMALL_MOUSE_IMG_YSIZE 16 #define X 0xff /* any nonzero in And mask means part of cursor */ #define B BORDER #define I INTERIOR -static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { - X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, - X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, - X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, - X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, - X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, - X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0, - X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, - X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0, - X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0, - X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, - X,X,X,0,X,X,X,X,0,0,0,0,0,0,0,0, - X,X,0,0,X,X,X,X,0,0,0,0,0,0,0,0, - 0,0,0,0,0,X,X,X,X,0,0,0,0,0,0,0, - 0,0,0,0,0,X,X,X,X,0,0,0,0,0,0,0, - 0,0,0,0,0,0,X,X,0,0,0,0,0,0,0,0, +static byte LargeAndMask[] = { + X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, + X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0, + X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0, + X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0, + X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, + X,X,X,X,X,X,0,X,X,X,X,X,X,0,0,0,0,0,0, + X,X,X,X,X,0,0,X,X,X,X,X,X,0,0,0,0,0,0, + X,X,X,X,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0, + X,X,X,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0, + X,X,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0, + 0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0, + 0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0, + 0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,0,0,0, }; -static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { - B,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - B,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0, - B,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0, - B,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0, - B,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0, - B,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0, - B,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0, - B,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0, - B,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0, - B,I,I,I,I,I,B,B,B,B,0,0,0,0,0,0, - B,I,I,B,I,I,B,0,0,0,0,0,0,0,0,0, - B,I,B,0,B,I,I,B,0,0,0,0,0,0,0,0, - B,B,0,0,B,I,I,B,0,0,0,0,0,0,0,0, - 0,0,0,0,0,B,I,I,B,0,0,0,0,0,0,0, - 0,0,0,0,0,B,I,I,B,0,0,0,0,0,0,0, - 0,0,0,0,0,0,B,B,0,0,0,0,0,0,0,0, +static byte LargeOrMask[] = { + B,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + B,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + B,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + B,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + B,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0, + B,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0, + B,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0, + B,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0, + B,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0, + B,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0, + B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0, + B,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0, + B,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0, + B,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0, + B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0, + B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0, + B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0, + B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B, + B,I,I,I,I,I,I,I,I,I,I,B,B,B,B,B,B,B,B, + B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0, + B,I,I,I,I,I,B,I,I,I,I,B,0,0,0,0,0,0,0, + B,I,I,I,I,B,0,B,I,I,I,I,B,0,0,0,0,0,0, + B,I,I,I,B,0,0,B,I,I,I,I,B,0,0,0,0,0,0, + B,I,I,B,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0, + B,I,B,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0, + B,B,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0, + 0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0, + 0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0, + 0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,B,B,B,B,0,0,0, }; +static byte SmallAndMask[] = { + X,X,0,0,0,0,0,0,0,0, + X,X,X,0,0,0,0,0,0,0, + X,X,X,X,0,0,0,0,0,0, + X,X,X,X,X,0,0,0,0,0, + X,X,X,X,X,X,0,0,0,0, + X,X,X,X,X,X,X,0,0,0, + X,X,X,X,X,X,X,X,0,0, + X,X,X,X,X,X,X,X,X,0, + X,X,X,X,X,X,X,X,X,X, + X,X,X,X,X,X,X,X,X,X, + X,X,X,X,X,X,X,0,0,0, + X,X,X,0,X,X,X,X,0,0, + X,X,0,0,X,X,X,X,0,0, + 0,0,0,0,0,X,X,X,X,0, + 0,0,0,0,0,X,X,X,X,0, + 0,0,0,0,0,0,X,X,0,0, +}; +static byte SmallOrMask[] = { + B,B,0,0,0,0,0,0,0,0, + B,I,B,0,0,0,0,0,0,0, + B,I,I,B,0,0,0,0,0,0, + B,I,I,I,B,0,0,0,0,0, + B,I,I,I,I,B,0,0,0,0, + B,I,I,I,I,I,B,0,0,0, + B,I,I,I,I,I,I,B,0,0, + B,I,I,I,I,I,I,I,B,0, + B,I,I,I,I,I,I,I,I,B, + B,I,I,I,I,I,B,B,B,B, + B,I,I,B,I,I,B,0,0,0, + B,I,B,0,B,I,I,B,0,0, + B,B,0,0,B,I,I,B,0,0, + 0,0,0,0,0,B,I,I,B,0, + 0,0,0,0,0,B,I,I,B,0, + 0,0,0,0,0,0,B,B,0,0, +}; #undef X #undef B #undef I -static VGLBitmap VGLMouseStdAndMask = - VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask); -static VGLBitmap VGLMouseStdOrMask = - VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask); +static VGLBitmap VGLMouseLargeAndMask = + VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE, + LargeAndMask); +static VGLBitmap VGLMouseLargeOrMask = + VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE, + LargeOrMask); +static VGLBitmap VGLMouseSmallAndMask = + VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE, + SmallAndMask); +static VGLBitmap VGLMouseSmallOrMask = + VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE, + SmallOrMask); static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask; static int VGLMouseShown = VGL_MOUSEHIDE; static int VGLMouseXpos = 0; static int VGLMouseYpos = 0; static int VGLMouseButtons = 0; static volatile sig_atomic_t VGLMintpending; static volatile sig_atomic_t VGLMsuppressint; #define INTOFF() (VGLMsuppressint++) #define INTON() do { \ if (--VGLMsuppressint == 0 && VGLMintpending) \ VGLMouseAction(0); \ } while (0) int __VGLMouseMode(int mode) { int oldmode; INTOFF(); oldmode = VGLMouseShown; if (mode == VGL_MOUSESHOW) { if (VGLMouseShown == VGL_MOUSEHIDE) { VGLMouseShown = VGL_MOUSESHOW; - __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, VGLDisplay, - VGLMouseXpos, VGLMouseYpos, - MOUSE_IMG_SIZE, -MOUSE_IMG_SIZE); + __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, + VGLDisplay, VGLMouseXpos, VGLMouseYpos, + VGLMouseAndMask->VXsize, -VGLMouseAndMask->VYsize); } } else { if (VGLMouseShown == VGL_MOUSESHOW) { VGLMouseShown = VGL_MOUSEHIDE; - __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, VGLDisplay, - VGLMouseXpos, VGLMouseYpos, - MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); + __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, + VGLDisplay, VGLMouseXpos, VGLMouseYpos, + VGLMouseAndMask->VXsize, VGLMouseAndMask->VYsize); } } INTON(); return oldmode; } void VGLMouseMode(int mode) { __VGLMouseMode(mode); } static void VGLMouseAction(int dummy) { struct mouse_info mouseinfo; int mousemode; if (VGLMsuppressint) { VGLMintpending = 1; return; } again: INTOFF(); VGLMintpending = 0; mouseinfo.operation = MOUSE_GETINFO; ioctl(0, CONS_MOUSECTL, &mouseinfo); if (VGLMouseXpos != mouseinfo.u.data.x || VGLMouseYpos != mouseinfo.u.data.y) { mousemode = __VGLMouseMode(VGL_MOUSEHIDE); VGLMouseXpos = mouseinfo.u.data.x; VGLMouseYpos = mouseinfo.u.data.y; __VGLMouseMode(mousemode); } VGLMouseButtons = mouseinfo.u.data.buttons; /* * Loop to handle any new (suppressed) signals. This is INTON() without * recursion. !SA_RESTART prevents recursion in signal handling. So the * maximum recursion is 2 levels. */ VGLMsuppressint = 0; if (VGLMintpending) goto again; } void VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask) { int mousemode; mousemode = __VGLMouseMode(VGL_MOUSEHIDE); VGLMouseAndMask = AndMask; if (VGLMouseOrMask != NULL) { free(VGLMouseOrMask->Bitmap); free(VGLMouseOrMask); } VGLMouseOrMask = VGLBitmapCreate(MEMBUF, OrMask->VXsize, OrMask->VYsize, 0); VGLBitmapAllocateBits(VGLMouseOrMask); VGLBitmapCvt(OrMask, VGLMouseOrMask); __VGLMouseMode(mousemode); } void VGLMouseSetStdImage() { - VGLMouseSetImage(&VGLMouseStdAndMask, &VGLMouseStdOrMask); + if (VGLDisplay->VXsize > 800) + VGLMouseSetImage(&VGLMouseLargeAndMask, &VGLMouseLargeOrMask); + else + VGLMouseSetImage(&VGLMouseSmallAndMask, &VGLMouseSmallOrMask); } int VGLMouseInit(int mode) { struct mouse_info mouseinfo; + VGLBitmap *ormask; int andmask, border, error, i, interior; switch (VGLModeInfo.vi_mem_model) { case V_INFO_MM_PACKED: case V_INFO_MM_PLANAR: andmask = 0x0f; border = 0x0f; interior = 0x04; break; case V_INFO_MM_VGAX: andmask = 0x3f; border = 0x3f; interior = 0x24; break; default: andmask = 0xff; border = BORDER; interior = INTERIOR; break; } if (VGLModeInfo.vi_mode == M_BG640x480) border = 0; /* XXX (palette makes 0x04 look like 0x0f) */ if (getenv("VGLMOUSEBORDERCOLOR") != NULL) border = strtoul(getenv("VGLMOUSEBORDERCOLOR"), NULL, 0); if (getenv("VGLMOUSEINTERIORCOLOR") != NULL) interior = strtoul(getenv("VGLMOUSEINTERIORCOLOR"), NULL, 0); - for (i = 0; i < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; i++) - VGLMouseStdOrMask.Bitmap[i] = VGLMouseStdOrMask.Bitmap[i] == BORDER ? - border : VGLMouseStdOrMask.Bitmap[i] == INTERIOR ? interior : 0; + ormask = &VGLMouseLargeOrMask; + for (i = 0; i < ormask->VXsize * ormask->VYsize; i++) + ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ? border : + ormask->Bitmap[i] == INTERIOR ? interior : 0; + ormask = &VGLMouseSmallOrMask; + for (i = 0; i < ormask->VXsize * ormask->VYsize; i++) + ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ? border : + ormask->Bitmap[i] == INTERIOR ? interior : 0; VGLMouseSetStdImage(); mouseinfo.operation = MOUSE_MODE; mouseinfo.u.mode.signal = SIGUSR2; if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo))) return error; signal(SIGUSR2, VGLMouseAction); mouseinfo.operation = MOUSE_GETINFO; ioctl(0, CONS_MOUSECTL, &mouseinfo); VGLMouseXpos = mouseinfo.u.data.x; VGLMouseYpos = mouseinfo.u.data.y; VGLMouseButtons = mouseinfo.u.data.buttons; VGLMouseMode(mode); return 0; } void VGLMouseRestore(void) { struct mouse_info mouseinfo; INTOFF(); mouseinfo.operation = MOUSE_GETINFO; if (ioctl(0, CONS_MOUSECTL, &mouseinfo) == 0) { mouseinfo.operation = MOUSE_MOVEABS; mouseinfo.u.data.x = VGLMouseXpos; mouseinfo.u.data.y = VGLMouseYpos; ioctl(0, CONS_MOUSECTL, &mouseinfo); } INTON(); } int VGLMouseStatus(int *x, int *y, char *buttons) { INTOFF(); *x = VGLMouseXpos; *y = VGLMouseYpos; *buttons = VGLMouseButtons; INTON(); return VGLMouseShown; } void VGLMouseFreeze(void) { INTOFF(); } int VGLMouseFreezeXY(int x, int y) { INTOFF(); if (VGLMouseShown != VGL_MOUSESHOW) return 0; - if (x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE && - y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE && - VGLMouseAndMask->Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) + if (x >= VGLMouseXpos && x < VGLMouseXpos + VGLMouseAndMask->VXsize && + y >= VGLMouseYpos && y < VGLMouseYpos + VGLMouseAndMask->VYsize && + VGLMouseAndMask->Bitmap[(y-VGLMouseYpos)*VGLMouseAndMask->VXsize+ + (x-VGLMouseXpos)]) return 1; return 0; } int VGLMouseOverlap(int x, int y, int width, int hight) { int overlap; if (VGLMouseShown != VGL_MOUSESHOW) return 0; if (x > VGLMouseXpos) - overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x; + overlap = (VGLMouseXpos + VGLMouseAndMask->VXsize) - x; else overlap = (x + width) - VGLMouseXpos; if (overlap <= 0) return 0; if (y > VGLMouseYpos) - overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y; + overlap = (VGLMouseYpos + VGLMouseAndMask->VYsize) - y; else overlap = (y + hight) - VGLMouseYpos; return overlap > 0; } void VGLMouseMerge(int x, int y, int width, byte *line) { int pos, x1, xend, xstart; xstart = x; if (xstart < VGLMouseXpos) xstart = VGLMouseXpos; xend = x + width; - if (xend > VGLMouseXpos + MOUSE_IMG_SIZE) - xend = VGLMouseXpos + MOUSE_IMG_SIZE; + if (xend > VGLMouseXpos + VGLMouseAndMask->VXsize) + xend = VGLMouseXpos + VGLMouseAndMask->VXsize; for (x1 = xstart; x1 < xend; x1++) { - pos = (y - VGLMouseYpos) * MOUSE_IMG_SIZE + x1 - VGLMouseXpos; + pos = (y - VGLMouseYpos) * VGLMouseAndMask->VXsize + x1 - VGLMouseXpos; if (VGLMouseAndMask->Bitmap[pos]) bcopy(&VGLMouseOrMask->Bitmap[pos * VGLDisplay->PixelBytes], &line[(x1 - x) * VGLDisplay->PixelBytes], VGLDisplay->PixelBytes); } } void VGLMouseUnFreeze() { INTON(); }