1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1991-1997 Søren Schmidt 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer 12 * in this position and unchanged. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <stdio.h> 35 #include <sys/types.h> 36 #include <sys/ioctl.h> 37 #include <sys/signal.h> 38 #include <sys/consio.h> 39 #include <sys/fbio.h> 40 #include "vgl.h" 41 42 #define X 0xff 43 static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { 44 X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 45 X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, 46 X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, 47 X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, 48 X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, 49 X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 50 X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0, 51 X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, 52 X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 53 0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0, 54 0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0, 55 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0, 56 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0, 57 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 58 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 59 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 60 }; 61 static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { 62 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 63 0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 64 0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, 65 0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, 66 0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, 67 0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, 68 0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 69 0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0, 70 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, 71 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, 72 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, 73 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, 74 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 75 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 76 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 77 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 78 }; 79 #undef X 80 static VGLBitmap VGLMouseStdAndMask = 81 VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask); 82 static VGLBitmap VGLMouseStdOrMask = 83 VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask); 84 static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask; 85 static byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE]; 86 static VGLBitmap VGLMouseSave = 87 VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map); 88 static int VGLMouseVisible = 0; 89 static int VGLMouseFrozen = 0; 90 static int VGLMouseShown = 0; 91 static int VGLMouseXpos = 0; 92 static int VGLMouseYpos = 0; 93 static int VGLMouseButtons = 0; 94 95 void 96 VGLMousePointerShow() 97 { 98 byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE]; 99 VGLBitmap buffer = 100 VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf); 101 byte crtcidx, crtcval, gdcidx, gdcval; 102 int pos; 103 104 if (!VGLMouseVisible) { 105 VGLMouseVisible = 1; 106 crtcidx = inb(0x3c4); 107 crtcval = inb(0x3c5); 108 gdcidx = inb(0x3ce); 109 gdcval = inb(0x3cf); 110 __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos, 111 &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 112 bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE); 113 for (pos = 0; pos < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++) 114 buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) | 115 VGLMouseOrMask->Bitmap[pos]; 116 __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay, 117 VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 118 outb(0x3c4, crtcidx); 119 outb(0x3c5, crtcval); 120 outb(0x3ce, gdcidx); 121 outb(0x3cf, gdcval); 122 } 123 } 124 125 void 126 VGLMousePointerHide() 127 { 128 byte crtcidx, crtcval, gdcidx, gdcval; 129 130 if (VGLMouseVisible) { 131 VGLMouseVisible = 0; 132 crtcidx = inb(0x3c4); 133 crtcval = inb(0x3c5); 134 gdcidx = inb(0x3ce); 135 gdcval = inb(0x3cf); 136 __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay, 137 VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 138 outb(0x3c4, crtcidx); 139 outb(0x3c5, crtcval); 140 outb(0x3ce, gdcidx); 141 outb(0x3cf, gdcval); 142 } 143 } 144 145 void 146 VGLMouseMode(int mode) 147 { 148 if (mode == VGL_MOUSESHOW) { 149 if (VGLMouseShown == VGL_MOUSEHIDE) { 150 VGLMousePointerShow(); 151 VGLMouseShown = VGL_MOUSESHOW; 152 } 153 } 154 else { 155 if (VGLMouseShown == VGL_MOUSESHOW) { 156 VGLMousePointerHide(); 157 VGLMouseShown = VGL_MOUSEHIDE; 158 } 159 } 160 } 161 162 void 163 VGLMouseAction(int dummy) 164 { 165 struct mouse_info mouseinfo; 166 167 if (VGLMouseFrozen) { 168 VGLMouseFrozen++; 169 return; 170 } 171 mouseinfo.operation = MOUSE_GETINFO; 172 ioctl(0, CONS_MOUSECTL, &mouseinfo); 173 if (VGLMouseShown == VGL_MOUSESHOW) 174 VGLMousePointerHide(); 175 VGLMouseXpos = mouseinfo.u.data.x; 176 VGLMouseYpos = mouseinfo.u.data.y; 177 VGLMouseButtons = mouseinfo.u.data.buttons; 178 if (VGLMouseShown == VGL_MOUSESHOW) 179 VGLMousePointerShow(); 180 } 181 182 void 183 VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask) 184 { 185 if (VGLMouseShown == VGL_MOUSESHOW) 186 VGLMousePointerHide(); 187 VGLMouseAndMask = AndMask; 188 VGLMouseOrMask = OrMask; 189 if (VGLMouseShown == VGL_MOUSESHOW) 190 VGLMousePointerShow(); 191 } 192 193 void 194 VGLMouseSetStdImage() 195 { 196 if (VGLMouseShown == VGL_MOUSESHOW) 197 VGLMousePointerHide(); 198 VGLMouseAndMask = &VGLMouseStdAndMask; 199 VGLMouseOrMask = &VGLMouseStdOrMask; 200 if (VGLMouseShown == VGL_MOUSESHOW) 201 VGLMousePointerShow(); 202 } 203 204 int 205 VGLMouseInit(int mode) 206 { 207 struct mouse_info mouseinfo; 208 int error; 209 210 VGLMouseSetStdImage(); 211 mouseinfo.operation = MOUSE_MODE; 212 mouseinfo.u.mode.signal = SIGUSR2; 213 if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo))) 214 return error; 215 signal(SIGUSR2, VGLMouseAction); 216 mouseinfo.operation = MOUSE_GETINFO; 217 ioctl(0, CONS_MOUSECTL, &mouseinfo); 218 VGLMouseXpos = mouseinfo.u.data.x; 219 VGLMouseYpos = mouseinfo.u.data.y; 220 VGLMouseButtons = mouseinfo.u.data.buttons; 221 VGLMouseMode(mode); 222 return 0; 223 } 224 225 int 226 VGLMouseStatus(int *x, int *y, char *buttons) 227 { 228 signal(SIGUSR2, SIG_IGN); 229 *x = VGLMouseXpos; 230 *y = VGLMouseYpos; 231 *buttons = VGLMouseButtons; 232 signal(SIGUSR2, VGLMouseAction); 233 return VGLMouseShown; 234 } 235 236 int 237 VGLMouseFreeze(int x, int y, int width, int hight, byte color) 238 { 239 if (!VGLMouseFrozen) { 240 VGLMouseFrozen = 1; 241 if (width > 1 || hight > 1) { /* bitmap */ 242 if (VGLMouseShown == 1) { 243 int overlap; 244 245 if (x > VGLMouseXpos) 246 overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x; 247 else 248 overlap = (x + width) - VGLMouseXpos; 249 if (overlap > 0) { 250 if (y > VGLMouseYpos) 251 overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y; 252 else 253 overlap = (y + hight) - VGLMouseYpos; 254 if (overlap > 0) 255 VGLMousePointerHide(); 256 } 257 } 258 } 259 else { /* bit */ 260 if (VGLMouseShown && 261 x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE && 262 y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) { 263 VGLMouseSave.Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)] = 264 (color); 265 if (VGLMouseAndMask->Bitmap 266 [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) { 267 return 1; 268 } 269 } 270 } 271 } 272 return 0; 273 } 274 275 void 276 VGLMouseUnFreeze() 277 { 278 if (VGLMouseFrozen > 1) { 279 VGLMouseFrozen = 0; 280 VGLMouseAction(0); 281 } 282 else { 283 VGLMouseFrozen = 0; 284 if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible) 285 VGLMousePointerShow(); 286 } 287 } 288