19a57b7d2SSøren Schmidt /*- 25e53a4f9SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 35e53a4f9SPedro F. Giffuni * 4bf3f9db6SUlrich Spörlein * Copyright (c) 1991-1997 Søren Schmidt 59a57b7d2SSøren Schmidt * All rights reserved. 69a57b7d2SSøren Schmidt * 79a57b7d2SSøren Schmidt * Redistribution and use in source and binary forms, with or without 89a57b7d2SSøren Schmidt * modification, are permitted provided that the following conditions 99a57b7d2SSøren Schmidt * are met: 109a57b7d2SSøren Schmidt * 1. Redistributions of source code must retain the above copyright 119a57b7d2SSøren Schmidt * notice, this list of conditions and the following disclaimer 129a57b7d2SSøren Schmidt * in this position and unchanged. 139a57b7d2SSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 149a57b7d2SSøren Schmidt * notice, this list of conditions and the following disclaimer in the 159a57b7d2SSøren Schmidt * documentation and/or other materials provided with the distribution. 169a57b7d2SSøren Schmidt * 3. The name of the author may not be used to endorse or promote products 1721dc7d4fSJens Schweikhardt * derived from this software without specific prior written permission 189a57b7d2SSøren Schmidt * 199a57b7d2SSøren Schmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 209a57b7d2SSøren Schmidt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 219a57b7d2SSøren Schmidt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 229a57b7d2SSøren Schmidt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 239a57b7d2SSøren Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 249a57b7d2SSøren Schmidt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 259a57b7d2SSøren Schmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 269a57b7d2SSøren Schmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 279a57b7d2SSøren Schmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 289a57b7d2SSøren Schmidt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 299a57b7d2SSøren Schmidt */ 309a57b7d2SSøren Schmidt 31e67f5b9fSMatthew Dillon #include <sys/cdefs.h> 32e67f5b9fSMatthew Dillon __FBSDID("$FreeBSD$"); 33e67f5b9fSMatthew Dillon 349a57b7d2SSøren Schmidt #include <stdio.h> 359a57b7d2SSøren Schmidt #include <sys/types.h> 369a57b7d2SSøren Schmidt #include <sys/ioctl.h> 379a57b7d2SSøren Schmidt #include <sys/signal.h> 3800d25f51SPoul-Henning Kamp #include <sys/consio.h> 3900d25f51SPoul-Henning Kamp #include <sys/fbio.h> 409a57b7d2SSøren Schmidt #include "vgl.h" 419a57b7d2SSøren Schmidt 42c0ce6f7dSBruce Evans static void VGLMouseAction(int dummy); 43c0ce6f7dSBruce Evans 44a93ca07aSBruce Evans #define BORDER 0xff /* default border -- light white in rgb 3:3:2 */ 45a93ca07aSBruce Evans #define INTERIOR 0xa0 /* default interior -- red in rgb 3:3:2 */ 46*34f210d8SBruce Evans #define LARGE_MOUSE_IMG_XSIZE 19 47*34f210d8SBruce Evans #define LARGE_MOUSE_IMG_YSIZE 32 48*34f210d8SBruce Evans #define SMALL_MOUSE_IMG_XSIZE 10 49*34f210d8SBruce Evans #define SMALL_MOUSE_IMG_YSIZE 16 50a93ca07aSBruce Evans #define X 0xff /* any nonzero in And mask means part of cursor */ 51a93ca07aSBruce Evans #define B BORDER 52a93ca07aSBruce Evans #define I INTERIOR 53*34f210d8SBruce Evans static byte LargeAndMask[] = { 54*34f210d8SBruce Evans X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 55*34f210d8SBruce Evans X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 56*34f210d8SBruce Evans X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 57*34f210d8SBruce Evans X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 58*34f210d8SBruce Evans X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, 59*34f210d8SBruce Evans X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, 60*34f210d8SBruce Evans X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, 61*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, 62*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 63*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0, 64*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, 65*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0, 66*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0, 67*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0, 68*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0, 69*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0, 70*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0, 71*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, 72*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, 73*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, 74*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, 75*34f210d8SBruce Evans X,X,X,X,X,X,0,X,X,X,X,X,X,0,0,0,0,0,0, 76*34f210d8SBruce Evans X,X,X,X,X,0,0,X,X,X,X,X,X,0,0,0,0,0,0, 77*34f210d8SBruce Evans X,X,X,X,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0, 78*34f210d8SBruce Evans X,X,X,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0, 79*34f210d8SBruce Evans X,X,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0, 80*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0, 81*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0, 82*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0, 83*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0, 84*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0, 85*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,0,0,0, 869a57b7d2SSøren Schmidt }; 87*34f210d8SBruce Evans static byte LargeOrMask[] = { 88*34f210d8SBruce Evans B,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 89*34f210d8SBruce Evans B,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 90*34f210d8SBruce Evans B,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 91*34f210d8SBruce Evans B,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 92*34f210d8SBruce Evans B,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0, 93*34f210d8SBruce Evans B,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0, 94*34f210d8SBruce Evans B,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0, 95*34f210d8SBruce Evans B,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0, 96*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0, 97*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0, 98*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0, 99*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0, 100*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0, 101*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0, 102*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0, 103*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0, 104*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0, 105*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B, 106*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,B,B,B,B,B,B,B,B, 107*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0, 108*34f210d8SBruce Evans B,I,I,I,I,I,B,I,I,I,I,B,0,0,0,0,0,0,0, 109*34f210d8SBruce Evans B,I,I,I,I,B,0,B,I,I,I,I,B,0,0,0,0,0,0, 110*34f210d8SBruce Evans B,I,I,I,B,0,0,B,I,I,I,I,B,0,0,0,0,0,0, 111*34f210d8SBruce Evans B,I,I,B,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0, 112*34f210d8SBruce Evans B,I,B,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0, 113*34f210d8SBruce Evans B,B,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0, 114*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0, 115*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0, 116*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0, 117*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0, 118*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0, 119*34f210d8SBruce Evans 0,0,0,0,0,0,0,0,0,0,0,0,B,B,B,B,0,0,0, 120*34f210d8SBruce Evans }; 121*34f210d8SBruce Evans static byte SmallAndMask[] = { 122*34f210d8SBruce Evans X,X,0,0,0,0,0,0,0,0, 123*34f210d8SBruce Evans X,X,X,0,0,0,0,0,0,0, 124*34f210d8SBruce Evans X,X,X,X,0,0,0,0,0,0, 125*34f210d8SBruce Evans X,X,X,X,X,0,0,0,0,0, 126*34f210d8SBruce Evans X,X,X,X,X,X,0,0,0,0, 127*34f210d8SBruce Evans X,X,X,X,X,X,X,0,0,0, 128*34f210d8SBruce Evans X,X,X,X,X,X,X,X,0,0, 129*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,0, 130*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X, 131*34f210d8SBruce Evans X,X,X,X,X,X,X,X,X,X, 132*34f210d8SBruce Evans X,X,X,X,X,X,X,0,0,0, 133*34f210d8SBruce Evans X,X,X,0,X,X,X,X,0,0, 134*34f210d8SBruce Evans X,X,0,0,X,X,X,X,0,0, 135*34f210d8SBruce Evans 0,0,0,0,0,X,X,X,X,0, 136*34f210d8SBruce Evans 0,0,0,0,0,X,X,X,X,0, 137*34f210d8SBruce Evans 0,0,0,0,0,0,X,X,0,0, 138*34f210d8SBruce Evans }; 139*34f210d8SBruce Evans static byte SmallOrMask[] = { 140*34f210d8SBruce Evans B,B,0,0,0,0,0,0,0,0, 141*34f210d8SBruce Evans B,I,B,0,0,0,0,0,0,0, 142*34f210d8SBruce Evans B,I,I,B,0,0,0,0,0,0, 143*34f210d8SBruce Evans B,I,I,I,B,0,0,0,0,0, 144*34f210d8SBruce Evans B,I,I,I,I,B,0,0,0,0, 145*34f210d8SBruce Evans B,I,I,I,I,I,B,0,0,0, 146*34f210d8SBruce Evans B,I,I,I,I,I,I,B,0,0, 147*34f210d8SBruce Evans B,I,I,I,I,I,I,I,B,0, 148*34f210d8SBruce Evans B,I,I,I,I,I,I,I,I,B, 149*34f210d8SBruce Evans B,I,I,I,I,I,B,B,B,B, 150*34f210d8SBruce Evans B,I,I,B,I,I,B,0,0,0, 151*34f210d8SBruce Evans B,I,B,0,B,I,I,B,0,0, 152*34f210d8SBruce Evans B,B,0,0,B,I,I,B,0,0, 153*34f210d8SBruce Evans 0,0,0,0,0,B,I,I,B,0, 154*34f210d8SBruce Evans 0,0,0,0,0,B,I,I,B,0, 155*34f210d8SBruce Evans 0,0,0,0,0,0,B,B,0,0, 1569a57b7d2SSøren Schmidt }; 1579a57b7d2SSøren Schmidt #undef X 158a93ca07aSBruce Evans #undef B 159a93ca07aSBruce Evans #undef I 160*34f210d8SBruce Evans static VGLBitmap VGLMouseLargeAndMask = 161*34f210d8SBruce Evans VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE, 162*34f210d8SBruce Evans LargeAndMask); 163*34f210d8SBruce Evans static VGLBitmap VGLMouseLargeOrMask = 164*34f210d8SBruce Evans VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE, 165*34f210d8SBruce Evans LargeOrMask); 166*34f210d8SBruce Evans static VGLBitmap VGLMouseSmallAndMask = 167*34f210d8SBruce Evans VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE, 168*34f210d8SBruce Evans SmallAndMask); 169*34f210d8SBruce Evans static VGLBitmap VGLMouseSmallOrMask = 170*34f210d8SBruce Evans VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE, 171*34f210d8SBruce Evans SmallOrMask); 1729a57b7d2SSøren Schmidt static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask; 173c7432537SBruce Evans static int VGLMouseShown = VGL_MOUSEHIDE; 1749a57b7d2SSøren Schmidt static int VGLMouseXpos = 0; 1759a57b7d2SSøren Schmidt static int VGLMouseYpos = 0; 1769a57b7d2SSøren Schmidt static int VGLMouseButtons = 0; 1770410dc5fSBruce Evans static volatile sig_atomic_t VGLMintpending; 1780410dc5fSBruce Evans static volatile sig_atomic_t VGLMsuppressint; 1790410dc5fSBruce Evans 1800410dc5fSBruce Evans #define INTOFF() (VGLMsuppressint++) 1810410dc5fSBruce Evans #define INTON() do { \ 1820410dc5fSBruce Evans if (--VGLMsuppressint == 0 && VGLMintpending) \ 1830410dc5fSBruce Evans VGLMouseAction(0); \ 1840410dc5fSBruce Evans } while (0) 1859a57b7d2SSøren Schmidt 186c0ce6f7dSBruce Evans int 187c0ce6f7dSBruce Evans __VGLMouseMode(int mode) 1889a57b7d2SSøren Schmidt { 189c0ce6f7dSBruce Evans int oldmode; 1909a57b7d2SSøren Schmidt 1910410dc5fSBruce Evans INTOFF(); 192c0ce6f7dSBruce Evans oldmode = VGLMouseShown; 193c0ce6f7dSBruce Evans if (mode == VGL_MOUSESHOW) { 194c0ce6f7dSBruce Evans if (VGLMouseShown == VGL_MOUSEHIDE) { 195c0ce6f7dSBruce Evans VGLMouseShown = VGL_MOUSESHOW; 196*34f210d8SBruce Evans __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, 197*34f210d8SBruce Evans VGLDisplay, VGLMouseXpos, VGLMouseYpos, 198*34f210d8SBruce Evans VGLMouseAndMask->VXsize, -VGLMouseAndMask->VYsize); 1999a57b7d2SSøren Schmidt } 2009a57b7d2SSøren Schmidt } 201c0ce6f7dSBruce Evans else { 202c0ce6f7dSBruce Evans if (VGLMouseShown == VGL_MOUSESHOW) { 203c0ce6f7dSBruce Evans VGLMouseShown = VGL_MOUSEHIDE; 204*34f210d8SBruce Evans __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, 205*34f210d8SBruce Evans VGLDisplay, VGLMouseXpos, VGLMouseYpos, 206*34f210d8SBruce Evans VGLMouseAndMask->VXsize, VGLMouseAndMask->VYsize); 207c0ce6f7dSBruce Evans } 208c0ce6f7dSBruce Evans } 209c0ce6f7dSBruce Evans INTON(); 210c0ce6f7dSBruce Evans return oldmode; 211c0ce6f7dSBruce Evans } 2129a57b7d2SSøren Schmidt 2139a57b7d2SSøren Schmidt void 2149a57b7d2SSøren Schmidt VGLMouseMode(int mode) 2159a57b7d2SSøren Schmidt { 216c0ce6f7dSBruce Evans __VGLMouseMode(mode); 2179a57b7d2SSøren Schmidt } 2189a57b7d2SSøren Schmidt 219c0ce6f7dSBruce Evans static void 2209a57b7d2SSøren Schmidt VGLMouseAction(int dummy) 2219a57b7d2SSøren Schmidt { 2229a57b7d2SSøren Schmidt struct mouse_info mouseinfo; 223c0ce6f7dSBruce Evans int mousemode; 2249a57b7d2SSøren Schmidt 2250410dc5fSBruce Evans if (VGLMsuppressint) { 2260410dc5fSBruce Evans VGLMintpending = 1; 2279a57b7d2SSøren Schmidt return; 2289a57b7d2SSøren Schmidt } 2290410dc5fSBruce Evans again: 2300410dc5fSBruce Evans INTOFF(); 2310410dc5fSBruce Evans VGLMintpending = 0; 2329a57b7d2SSøren Schmidt mouseinfo.operation = MOUSE_GETINFO; 2339a57b7d2SSøren Schmidt ioctl(0, CONS_MOUSECTL, &mouseinfo); 234c0ce6f7dSBruce Evans if (VGLMouseXpos != mouseinfo.u.data.x || 235c0ce6f7dSBruce Evans VGLMouseYpos != mouseinfo.u.data.y) { 236c0ce6f7dSBruce Evans mousemode = __VGLMouseMode(VGL_MOUSEHIDE); 2379a57b7d2SSøren Schmidt VGLMouseXpos = mouseinfo.u.data.x; 2389a57b7d2SSøren Schmidt VGLMouseYpos = mouseinfo.u.data.y; 239c0ce6f7dSBruce Evans __VGLMouseMode(mousemode); 240c0ce6f7dSBruce Evans } 2419a57b7d2SSøren Schmidt VGLMouseButtons = mouseinfo.u.data.buttons; 2420410dc5fSBruce Evans 2430410dc5fSBruce Evans /* 2440410dc5fSBruce Evans * Loop to handle any new (suppressed) signals. This is INTON() without 2450410dc5fSBruce Evans * recursion. !SA_RESTART prevents recursion in signal handling. So the 2460410dc5fSBruce Evans * maximum recursion is 2 levels. 2470410dc5fSBruce Evans */ 2480410dc5fSBruce Evans VGLMsuppressint = 0; 2490410dc5fSBruce Evans if (VGLMintpending) 2500410dc5fSBruce Evans goto again; 2519a57b7d2SSøren Schmidt } 2529a57b7d2SSøren Schmidt 2539a57b7d2SSøren Schmidt void 2549a57b7d2SSøren Schmidt VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask) 2559a57b7d2SSøren Schmidt { 256c0ce6f7dSBruce Evans int mousemode; 257c0ce6f7dSBruce Evans 258c0ce6f7dSBruce Evans mousemode = __VGLMouseMode(VGL_MOUSEHIDE); 259a93ca07aSBruce Evans 2609a57b7d2SSøren Schmidt VGLMouseAndMask = AndMask; 261a93ca07aSBruce Evans 262a93ca07aSBruce Evans if (VGLMouseOrMask != NULL) { 263a93ca07aSBruce Evans free(VGLMouseOrMask->Bitmap); 264a93ca07aSBruce Evans free(VGLMouseOrMask); 265a93ca07aSBruce Evans } 266a93ca07aSBruce Evans VGLMouseOrMask = VGLBitmapCreate(MEMBUF, OrMask->VXsize, OrMask->VYsize, 0); 267a93ca07aSBruce Evans VGLBitmapAllocateBits(VGLMouseOrMask); 268a93ca07aSBruce Evans VGLBitmapCvt(OrMask, VGLMouseOrMask); 269a93ca07aSBruce Evans 270c0ce6f7dSBruce Evans __VGLMouseMode(mousemode); 2719a57b7d2SSøren Schmidt } 2729a57b7d2SSøren Schmidt 2739a57b7d2SSøren Schmidt void 2749a57b7d2SSøren Schmidt VGLMouseSetStdImage() 2759a57b7d2SSøren Schmidt { 276*34f210d8SBruce Evans if (VGLDisplay->VXsize > 800) 277*34f210d8SBruce Evans VGLMouseSetImage(&VGLMouseLargeAndMask, &VGLMouseLargeOrMask); 278*34f210d8SBruce Evans else 279*34f210d8SBruce Evans VGLMouseSetImage(&VGLMouseSmallAndMask, &VGLMouseSmallOrMask); 2809a57b7d2SSøren Schmidt } 2819a57b7d2SSøren Schmidt 2829a57b7d2SSøren Schmidt int 2839a57b7d2SSøren Schmidt VGLMouseInit(int mode) 2849a57b7d2SSøren Schmidt { 2859a57b7d2SSøren Schmidt struct mouse_info mouseinfo; 286*34f210d8SBruce Evans VGLBitmap *ormask; 287a93ca07aSBruce Evans int andmask, border, error, i, interior; 2889a57b7d2SSøren Schmidt 289aa1ce985SBruce Evans switch (VGLModeInfo.vi_mem_model) { 290aa1ce985SBruce Evans case V_INFO_MM_PACKED: 291aa1ce985SBruce Evans case V_INFO_MM_PLANAR: 292a93ca07aSBruce Evans andmask = 0x0f; 293a93ca07aSBruce Evans border = 0x0f; 294a93ca07aSBruce Evans interior = 0x04; 295aa1ce985SBruce Evans break; 296aa1ce985SBruce Evans case V_INFO_MM_VGAX: 297a93ca07aSBruce Evans andmask = 0x3f; 298a93ca07aSBruce Evans border = 0x3f; 299a93ca07aSBruce Evans interior = 0x24; 300aa1ce985SBruce Evans break; 301aa1ce985SBruce Evans default: 302a93ca07aSBruce Evans andmask = 0xff; 303a93ca07aSBruce Evans border = BORDER; 304a93ca07aSBruce Evans interior = INTERIOR; 305aa1ce985SBruce Evans break; 306aa1ce985SBruce Evans } 307a93ca07aSBruce Evans if (VGLModeInfo.vi_mode == M_BG640x480) 308a93ca07aSBruce Evans border = 0; /* XXX (palette makes 0x04 look like 0x0f) */ 309a93ca07aSBruce Evans if (getenv("VGLMOUSEBORDERCOLOR") != NULL) 310a93ca07aSBruce Evans border = strtoul(getenv("VGLMOUSEBORDERCOLOR"), NULL, 0); 311a93ca07aSBruce Evans if (getenv("VGLMOUSEINTERIORCOLOR") != NULL) 312a93ca07aSBruce Evans interior = strtoul(getenv("VGLMOUSEINTERIORCOLOR"), NULL, 0); 313*34f210d8SBruce Evans ormask = &VGLMouseLargeOrMask; 314*34f210d8SBruce Evans for (i = 0; i < ormask->VXsize * ormask->VYsize; i++) 315*34f210d8SBruce Evans ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ? border : 316*34f210d8SBruce Evans ormask->Bitmap[i] == INTERIOR ? interior : 0; 317*34f210d8SBruce Evans ormask = &VGLMouseSmallOrMask; 318*34f210d8SBruce Evans for (i = 0; i < ormask->VXsize * ormask->VYsize; i++) 319*34f210d8SBruce Evans ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ? border : 320*34f210d8SBruce Evans ormask->Bitmap[i] == INTERIOR ? interior : 0; 3219a57b7d2SSøren Schmidt VGLMouseSetStdImage(); 3229a57b7d2SSøren Schmidt mouseinfo.operation = MOUSE_MODE; 3239a57b7d2SSøren Schmidt mouseinfo.u.mode.signal = SIGUSR2; 3249a57b7d2SSøren Schmidt if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo))) 3259a57b7d2SSøren Schmidt return error; 3269a57b7d2SSøren Schmidt signal(SIGUSR2, VGLMouseAction); 3279a57b7d2SSøren Schmidt mouseinfo.operation = MOUSE_GETINFO; 3289a57b7d2SSøren Schmidt ioctl(0, CONS_MOUSECTL, &mouseinfo); 3299a57b7d2SSøren Schmidt VGLMouseXpos = mouseinfo.u.data.x; 3309a57b7d2SSøren Schmidt VGLMouseYpos = mouseinfo.u.data.y; 3319a57b7d2SSøren Schmidt VGLMouseButtons = mouseinfo.u.data.buttons; 3329a57b7d2SSøren Schmidt VGLMouseMode(mode); 3339a57b7d2SSøren Schmidt return 0; 3349a57b7d2SSøren Schmidt } 3359a57b7d2SSøren Schmidt 336e848f3d1SBruce Evans void 337e848f3d1SBruce Evans VGLMouseRestore(void) 338e848f3d1SBruce Evans { 339e848f3d1SBruce Evans struct mouse_info mouseinfo; 340e848f3d1SBruce Evans 341e848f3d1SBruce Evans INTOFF(); 342e848f3d1SBruce Evans mouseinfo.operation = MOUSE_GETINFO; 343e848f3d1SBruce Evans if (ioctl(0, CONS_MOUSECTL, &mouseinfo) == 0) { 344e848f3d1SBruce Evans mouseinfo.operation = MOUSE_MOVEABS; 345e848f3d1SBruce Evans mouseinfo.u.data.x = VGLMouseXpos; 346e848f3d1SBruce Evans mouseinfo.u.data.y = VGLMouseYpos; 347e848f3d1SBruce Evans ioctl(0, CONS_MOUSECTL, &mouseinfo); 348e848f3d1SBruce Evans } 349e848f3d1SBruce Evans INTON(); 350e848f3d1SBruce Evans } 351e848f3d1SBruce Evans 3529a57b7d2SSøren Schmidt int 3539a57b7d2SSøren Schmidt VGLMouseStatus(int *x, int *y, char *buttons) 3549a57b7d2SSøren Schmidt { 3550410dc5fSBruce Evans INTOFF(); 3569a57b7d2SSøren Schmidt *x = VGLMouseXpos; 3579a57b7d2SSøren Schmidt *y = VGLMouseYpos; 3589a57b7d2SSøren Schmidt *buttons = VGLMouseButtons; 3590410dc5fSBruce Evans INTON(); 3609a57b7d2SSøren Schmidt return VGLMouseShown; 3619a57b7d2SSøren Schmidt } 3629a57b7d2SSøren Schmidt 363c7432537SBruce Evans void 364c7432537SBruce Evans VGLMouseFreeze(void) 3659a57b7d2SSøren Schmidt { 3660410dc5fSBruce Evans INTOFF(); 367c7432537SBruce Evans } 368c7432537SBruce Evans 369c7432537SBruce Evans int 370c7432537SBruce Evans VGLMouseFreezeXY(int x, int y) 371c7432537SBruce Evans { 372c7432537SBruce Evans INTOFF(); 373c7432537SBruce Evans if (VGLMouseShown != VGL_MOUSESHOW) 374c7432537SBruce Evans return 0; 375*34f210d8SBruce Evans if (x >= VGLMouseXpos && x < VGLMouseXpos + VGLMouseAndMask->VXsize && 376*34f210d8SBruce Evans y >= VGLMouseYpos && y < VGLMouseYpos + VGLMouseAndMask->VYsize && 377*34f210d8SBruce Evans VGLMouseAndMask->Bitmap[(y-VGLMouseYpos)*VGLMouseAndMask->VXsize+ 378*34f210d8SBruce Evans (x-VGLMouseXpos)]) 379c7432537SBruce Evans return 1; 380c7432537SBruce Evans return 0; 381c7432537SBruce Evans } 382c7432537SBruce Evans 383c7432537SBruce Evans int 384c7432537SBruce Evans VGLMouseOverlap(int x, int y, int width, int hight) 385c7432537SBruce Evans { 3869a57b7d2SSøren Schmidt int overlap; 3879a57b7d2SSøren Schmidt 388c7432537SBruce Evans if (VGLMouseShown != VGL_MOUSESHOW) 389c7432537SBruce Evans return 0; 3909a57b7d2SSøren Schmidt if (x > VGLMouseXpos) 391*34f210d8SBruce Evans overlap = (VGLMouseXpos + VGLMouseAndMask->VXsize) - x; 3929a57b7d2SSøren Schmidt else 3939a57b7d2SSøren Schmidt overlap = (x + width) - VGLMouseXpos; 394c7432537SBruce Evans if (overlap <= 0) 395c7432537SBruce Evans return 0; 3969a57b7d2SSøren Schmidt if (y > VGLMouseYpos) 397*34f210d8SBruce Evans overlap = (VGLMouseYpos + VGLMouseAndMask->VYsize) - y; 3989a57b7d2SSøren Schmidt else 3999a57b7d2SSøren Schmidt overlap = (y + hight) - VGLMouseYpos; 400c7432537SBruce Evans return overlap > 0; 4019a57b7d2SSøren Schmidt } 4029a57b7d2SSøren Schmidt 4039a57b7d2SSøren Schmidt void 404a07067eaSBruce Evans VGLMouseMerge(int x, int y, int width, byte *line) 405a07067eaSBruce Evans { 406a07067eaSBruce Evans int pos, x1, xend, xstart; 407a07067eaSBruce Evans 408a07067eaSBruce Evans xstart = x; 409a07067eaSBruce Evans if (xstart < VGLMouseXpos) 410a07067eaSBruce Evans xstart = VGLMouseXpos; 411a07067eaSBruce Evans xend = x + width; 412*34f210d8SBruce Evans if (xend > VGLMouseXpos + VGLMouseAndMask->VXsize) 413*34f210d8SBruce Evans xend = VGLMouseXpos + VGLMouseAndMask->VXsize; 414a07067eaSBruce Evans for (x1 = xstart; x1 < xend; x1++) { 415*34f210d8SBruce Evans pos = (y - VGLMouseYpos) * VGLMouseAndMask->VXsize + x1 - VGLMouseXpos; 416a07067eaSBruce Evans if (VGLMouseAndMask->Bitmap[pos]) 417a07067eaSBruce Evans bcopy(&VGLMouseOrMask->Bitmap[pos * VGLDisplay->PixelBytes], 418a07067eaSBruce Evans &line[(x1 - x) * VGLDisplay->PixelBytes], VGLDisplay->PixelBytes); 419a07067eaSBruce Evans } 420a07067eaSBruce Evans } 421a07067eaSBruce Evans 422a07067eaSBruce Evans void 4239a57b7d2SSøren Schmidt VGLMouseUnFreeze() 4249a57b7d2SSøren Schmidt { 4250410dc5fSBruce Evans INTON(); 4269a57b7d2SSøren Schmidt } 427