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