diff options
Diffstat (limited to 'lib/libvgl/mouse.c')
-rw-r--r-- | lib/libvgl/mouse.c | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/lib/libvgl/mouse.c b/lib/libvgl/mouse.c new file mode 100644 index 0000000..4f9dc62 --- /dev/null +++ b/lib/libvgl/mouse.c @@ -0,0 +1,285 @@ +/*- + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/signal.h> +#include <sys/consio.h> +#include <sys/fbio.h> +#include "vgl.h" + +#define X 0xff +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,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,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,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; +static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,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,0,X,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; +#undef X +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 *VGLMouseAndMask, *VGLMouseOrMask; +static byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE]; +static VGLBitmap VGLMouseSave = + VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map); +static int VGLMouseVisible = 0; +static int VGLMouseFrozen = 0; +static int VGLMouseShown = 0; +static int VGLMouseXpos = 0; +static int VGLMouseYpos = 0; +static int VGLMouseButtons = 0; + +void +VGLMousePointerShow() +{ + byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE]; + VGLBitmap buffer = + VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf); + byte crtcidx, crtcval, gdcidx, gdcval; + int pos; + + if (!VGLMouseVisible) { + VGLMouseVisible = 1; + crtcidx = inb(0x3c4); + crtcval = inb(0x3c5); + gdcidx = inb(0x3ce); + gdcval = inb(0x3cf); + __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos, + &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); + bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE); + for (pos = 0; pos < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++) + buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) | + VGLMouseOrMask->Bitmap[pos]; + __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay, + VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); + outb(0x3c4, crtcidx); + outb(0x3c5, crtcval); + outb(0x3ce, gdcidx); + outb(0x3cf, gdcval); + } +} + +void +VGLMousePointerHide() +{ + byte crtcidx, crtcval, gdcidx, gdcval; + + if (VGLMouseVisible) { + VGLMouseVisible = 0; + crtcidx = inb(0x3c4); + crtcval = inb(0x3c5); + gdcidx = inb(0x3ce); + gdcval = inb(0x3cf); + __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay, + VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); + outb(0x3c4, crtcidx); + outb(0x3c5, crtcval); + outb(0x3ce, gdcidx); + outb(0x3cf, gdcval); + } +} + +void +VGLMouseMode(int mode) +{ + if (mode == VGL_MOUSESHOW) { + if (VGLMouseShown == VGL_MOUSEHIDE) { + VGLMousePointerShow(); + VGLMouseShown = VGL_MOUSESHOW; + } + } + else { + if (VGLMouseShown == VGL_MOUSESHOW) { + VGLMousePointerHide(); + VGLMouseShown = VGL_MOUSEHIDE; + } + } +} + +void +VGLMouseAction(int dummy) +{ + struct mouse_info mouseinfo; + + if (VGLMouseFrozen) { + VGLMouseFrozen++; + return; + } + mouseinfo.operation = MOUSE_GETINFO; + ioctl(0, CONS_MOUSECTL, &mouseinfo); + if (VGLMouseShown == VGL_MOUSESHOW) + VGLMousePointerHide(); + VGLMouseXpos = mouseinfo.u.data.x; + VGLMouseYpos = mouseinfo.u.data.y; + VGLMouseButtons = mouseinfo.u.data.buttons; + if (VGLMouseShown == VGL_MOUSESHOW) + VGLMousePointerShow(); +} + +void +VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask) +{ + if (VGLMouseShown == VGL_MOUSESHOW) + VGLMousePointerHide(); + VGLMouseAndMask = AndMask; + VGLMouseOrMask = OrMask; + if (VGLMouseShown == VGL_MOUSESHOW) + VGLMousePointerShow(); +} + +void +VGLMouseSetStdImage() +{ + if (VGLMouseShown == VGL_MOUSESHOW) + VGLMousePointerHide(); + VGLMouseAndMask = &VGLMouseStdAndMask; + VGLMouseOrMask = &VGLMouseStdOrMask; + if (VGLMouseShown == VGL_MOUSESHOW) + VGLMousePointerShow(); +} + +int +VGLMouseInit(int mode) +{ + struct mouse_info mouseinfo; + int error; + + 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; +} + +int +VGLMouseStatus(int *x, int *y, char *buttons) +{ + signal(SIGUSR2, SIG_IGN); + *x = VGLMouseXpos; + *y = VGLMouseYpos; + *buttons = VGLMouseButtons; + signal(SIGUSR2, VGLMouseAction); + return VGLMouseShown; +} + +int +VGLMouseFreeze(int x, int y, int width, int hight, byte color) +{ + if (!VGLMouseFrozen) { + VGLMouseFrozen = 1; + if (width > 1 || hight > 1) { /* bitmap */ + if (VGLMouseShown == 1) { + int overlap; + + if (x > VGLMouseXpos) + overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x; + else + overlap = (x + width) - VGLMouseXpos; + if (overlap > 0) { + if (y > VGLMouseYpos) + overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y; + else + overlap = (y + hight) - VGLMouseYpos; + if (overlap > 0) + VGLMousePointerHide(); + } + } + } + else { /* bit */ + if (VGLMouseShown && + x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE && + y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) { + VGLMouseSave.Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)] = + (color); + if (VGLMouseAndMask->Bitmap + [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) { + return 1; + } + } + } + } + return 0; +} + +void +VGLMouseUnFreeze() +{ + if (VGLMouseFrozen > 1) { + VGLMouseFrozen = 0; + VGLMouseAction(0); + } + else { + VGLMouseFrozen = 0; + if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible) + VGLMousePointerShow(); + } +} |