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