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 withough 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 * $FreeBSD$ 29 */ 30 31 #include <stdio.h> 32 #include <sys/types.h> 33 #include <sys/ioctl.h> 34 #include <sys/signal.h> 35 #include <machine/console.h> 36 #include "vgl.h" 37 38 #define X 0xff 39 static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { 40 X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 41 X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, 42 X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, 43 X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, 44 X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, 45 X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 46 X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0, 47 X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, 48 X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 49 0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0, 50 0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0, 51 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0, 52 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0, 53 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 54 0,0,0,0,0,0,0,0,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 }; 57 static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { 58 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 59 0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 60 0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, 61 0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, 62 0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, 63 0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, 64 0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 65 0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0, 66 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, 67 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, 68 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, 69 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, 70 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 71 0,0,0,0,0,0,0,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 }; 75 #undef X 76 static VGLBitmap VGLMouseStdAndMask = 77 VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask); 78 static VGLBitmap VGLMouseStdOrMask = 79 VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask); 80 static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask; 81 static byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE]; 82 static VGLBitmap VGLMouseSave = 83 VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map); 84 static int VGLMouseVisible = 0; 85 static int VGLMouseFrozen = 0; 86 static int VGLMouseShown = 0; 87 static int VGLMouseXpos = 0; 88 static int VGLMouseYpos = 0; 89 static int VGLMouseButtons = 0; 90 91 void 92 VGLMousePointerShow() 93 { 94 byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE]; 95 VGLBitmap buffer = 96 VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf); 97 byte crtcidx, crtcval, gdcidx, gdcval; 98 int pos; 99 100 if (!VGLMouseVisible) { 101 VGLMouseVisible = 1; 102 crtcidx = inb(0x3c4); 103 crtcval = inb(0x3c5); 104 gdcidx = inb(0x3ce); 105 gdcval = inb(0x3cf); 106 __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos, 107 &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 108 bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE); 109 for (pos = 0; pos < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++) 110 buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) | 111 VGLMouseOrMask->Bitmap[pos]; 112 __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay, 113 VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 114 outb(0x3c4, crtcidx); 115 outb(0x3c5, crtcval); 116 outb(0x3ce, gdcidx); 117 outb(0x3cf, gdcval); 118 } 119 } 120 121 void 122 VGLMousePointerHide() 123 { 124 byte crtcidx, crtcval, gdcidx, gdcval; 125 126 if (VGLMouseVisible) { 127 VGLMouseVisible = 0; 128 crtcidx = inb(0x3c4); 129 crtcval = inb(0x3c5); 130 gdcidx = inb(0x3ce); 131 gdcval = inb(0x3cf); 132 __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay, 133 VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 134 outb(0x3c4, crtcidx); 135 outb(0x3c5, crtcval); 136 outb(0x3ce, gdcidx); 137 outb(0x3cf, gdcval); 138 } 139 } 140 141 void 142 VGLMouseMode(int mode) 143 { 144 if (mode == VGL_MOUSESHOW) { 145 if (VGLMouseShown == VGL_MOUSEHIDE) { 146 VGLMousePointerShow(); 147 VGLMouseShown = VGL_MOUSESHOW; 148 } 149 } 150 else { 151 if (VGLMouseShown == VGL_MOUSESHOW) { 152 VGLMousePointerHide(); 153 VGLMouseShown = VGL_MOUSEHIDE; 154 } 155 } 156 } 157 158 void 159 VGLMouseAction(int dummy) 160 { 161 struct mouse_info mouseinfo; 162 163 if (VGLMouseFrozen) { 164 VGLMouseFrozen++; 165 return; 166 } 167 mouseinfo.operation = MOUSE_GETINFO; 168 ioctl(0, CONS_MOUSECTL, &mouseinfo); 169 if (VGLMouseShown == VGL_MOUSESHOW) 170 VGLMousePointerHide(); 171 VGLMouseXpos = mouseinfo.u.data.x; 172 VGLMouseYpos = mouseinfo.u.data.y; 173 VGLMouseButtons = mouseinfo.u.data.buttons; 174 if (VGLMouseShown == VGL_MOUSESHOW) 175 VGLMousePointerShow(); 176 } 177 178 void 179 VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask) 180 { 181 if (VGLMouseShown == VGL_MOUSESHOW) 182 VGLMousePointerHide(); 183 VGLMouseAndMask = AndMask; 184 VGLMouseOrMask = OrMask; 185 if (VGLMouseShown == VGL_MOUSESHOW) 186 VGLMousePointerShow(); 187 } 188 189 void 190 VGLMouseSetStdImage() 191 { 192 if (VGLMouseShown == VGL_MOUSESHOW) 193 VGLMousePointerHide(); 194 VGLMouseAndMask = &VGLMouseStdAndMask; 195 VGLMouseOrMask = &VGLMouseStdOrMask; 196 if (VGLMouseShown == VGL_MOUSESHOW) 197 VGLMousePointerShow(); 198 } 199 200 int 201 VGLMouseInit(int mode) 202 { 203 struct mouse_info mouseinfo; 204 int error; 205 206 VGLMouseSetStdImage(); 207 mouseinfo.operation = MOUSE_MODE; 208 mouseinfo.u.mode.signal = SIGUSR2; 209 if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo))) 210 return error; 211 signal(SIGUSR2, VGLMouseAction); 212 mouseinfo.operation = MOUSE_GETINFO; 213 ioctl(0, CONS_MOUSECTL, &mouseinfo); 214 VGLMouseXpos = mouseinfo.u.data.x; 215 VGLMouseYpos = mouseinfo.u.data.y; 216 VGLMouseButtons = mouseinfo.u.data.buttons; 217 VGLMouseMode(mode); 218 return 0; 219 } 220 221 int 222 VGLMouseStatus(int *x, int *y, char *buttons) 223 { 224 signal(SIGUSR2, SIG_IGN); 225 *x = VGLMouseXpos; 226 *y = VGLMouseYpos; 227 *buttons = VGLMouseButtons; 228 signal(SIGUSR2, VGLMouseAction); 229 return VGLMouseShown; 230 } 231 232 int 233 VGLMouseFreeze(int x, int y, int width, int hight, byte color) 234 { 235 if (!VGLMouseFrozen) { 236 VGLMouseFrozen = 1; 237 if (width > 1 || hight > 1) { /* bitmap */ 238 if (VGLMouseShown == 1) { 239 int overlap; 240 241 if (x > VGLMouseXpos) 242 overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x; 243 else 244 overlap = (x + width) - VGLMouseXpos; 245 if (overlap > 0) { 246 if (y > VGLMouseYpos) 247 overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y; 248 else 249 overlap = (y + hight) - VGLMouseYpos; 250 if (overlap > 0) 251 VGLMousePointerHide(); 252 } 253 } 254 } 255 else { /* bit */ 256 if (VGLMouseShown && 257 x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE && 258 y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) { 259 VGLMouseSave.Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)] = 260 (color); 261 if (VGLMouseAndMask->Bitmap 262 [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) { 263 return 1; 264 } 265 } 266 } 267 } 268 return 0; 269 } 270 271 void 272 VGLMouseUnFreeze() 273 { 274 if (VGLMouseFrozen > 1) { 275 VGLMouseFrozen = 0; 276 VGLMouseAction(0); 277 } 278 else { 279 VGLMouseFrozen = 0; 280 if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible) 281 VGLMousePointerShow(); 282 } 283 } 284