mouse.c revision 53013
155714Skris/*- 2194206Ssimon * Copyright (c) 1991-1997 S�ren Schmidt 355714Skris * All rights reserved. 455714Skris * 555714Skris * Redistribution and use in source and binary forms, with or without 655714Skris * modification, are permitted provided that the following conditions 755714Skris * are met: 855714Skris * 1. Redistributions of source code must retain the above copyright 955714Skris * notice, this list of conditions and the following disclaimer 1055714Skris * in this position and unchanged. 1155714Skris * 2. Redistributions in binary form must reproduce the above copyright 1255714Skris * notice, this list of conditions and the following disclaimer in the 1355714Skris * documentation and/or other materials provided with the distribution. 1455714Skris * 3. The name of the author may not be used to endorse or promote products 1555714Skris * derived from this software withough specific prior written permission 1655714Skris * 1755714Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1855714Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1955714Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2055714Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2155714Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2255714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2355714Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2455714Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2555714Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2655714Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2755714Skris * 2855714Skris * $FreeBSD: head/lib/libvgl/mouse.c 53013 1999-11-08 11:37:46Z yokota $ 2955714Skris */ 3055714Skris 3155714Skris#include <stdio.h> 3255714Skris#include <sys/types.h> 3355714Skris#include <sys/ioctl.h> 3455714Skris#include <sys/signal.h> 3555714Skris#include <machine/console.h> 3655714Skris#include "vgl.h" 3755714Skris 3855714Skris#define X 0xff 3955714Skrisstatic byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { 4055714Skris X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 4155714Skris X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, 4255714Skris X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, 4355714Skris X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, 4455714Skris X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, 4555714Skris X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 4655714Skris X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0, 4755714Skris X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, 4855714Skris X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 4955714Skris 0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0, 5055714Skris 0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0, 5155714Skris 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0, 5255714Skris 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0, 5355714Skris 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5455714Skris 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5555714Skris 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5655714Skris}; 5755714Skrisstatic byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { 5855714Skris 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 5955714Skris 0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 6055714Skris 0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, 61109998Smarkm 0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, 6255714Skris 0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, 6355714Skris 0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, 6455714Skris 0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, 6555714Skris 0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0, 6655714Skris 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, 67109998Smarkm 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, 68109998Smarkm 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, 69109998Smarkm 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, 70109998Smarkm 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 7155714Skris 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 72109998Smarkm 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 7355714Skris 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 7455714Skris}; 75238405Sjkim#undef X 76238405Sjkimstatic VGLBitmap VGLMouseStdAndMask = 77238405Sjkim VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask); 78238405Sjkimstatic VGLBitmap VGLMouseStdOrMask = 79238405Sjkim VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask); 80160814Ssimonstatic VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask; 81238405Sjkimstatic byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE]; 82238405Sjkimstatic VGLBitmap VGLMouseSave = 8355714Skris VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map); 84238405Sjkimstatic int VGLMouseVisible = 0; 85238405Sjkimstatic int VGLMouseFrozen = 0; 86238405Sjkimstatic int VGLMouseShown = 0; 87238405Sjkimstatic int VGLMouseXpos = 0; 88160814Ssimonstatic int VGLMouseYpos = 0; 89238405Sjkimstatic int VGLMouseButtons = 0; 90238405Sjkim 91238405Sjkimvoid 92238405SjkimVGLMousePointerShow() 93238405Sjkim{ 94238405Sjkim byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE]; 95160814Ssimon VGLBitmap buffer = 96238405Sjkim VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf); 97238405Sjkim byte crtcidx, crtcval, gdcidx, gdcval; 98238405Sjkim int pos; 99238405Sjkim 100238405Sjkim if (!VGLMouseVisible) { 101238405Sjkim VGLMouseVisible = 1; 102160814Ssimon crtcidx = inb(0x3c4); 103238405Sjkim crtcval = inb(0x3c5); 104238405Sjkim gdcidx = inb(0x3ce); 105238405Sjkim gdcval = inb(0x3cf); 106238405Sjkim __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos, 107238405Sjkim &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 108160814Ssimon bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE); 10955714Skris for (pos = 0; pos < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++) 110238405Sjkim buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) | 111238405Sjkim VGLMouseOrMask->Bitmap[pos]; 112238405Sjkim __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay, 113160814Ssimon VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 114238405Sjkim outb(0x3c4, crtcidx); 11555714Skris outb(0x3c5, crtcval); 116238405Sjkim outb(0x3ce, gdcidx); 117160814Ssimon outb(0x3cf, gdcval); 118238405Sjkim } 119238405Sjkim} 120238405Sjkim 121238405Sjkimvoid 122238405SjkimVGLMousePointerHide() 123238405Sjkim{ 124238405Sjkim byte crtcidx, crtcval, gdcidx, gdcval; 125238405Sjkim 126238405Sjkim if (VGLMouseVisible) { 127238405Sjkim VGLMouseVisible = 0; 12855714Skris crtcidx = inb(0x3c4); 12955714Skris crtcval = inb(0x3c5); 130238405Sjkim gdcidx = inb(0x3ce); 131238405Sjkim gdcval = inb(0x3cf); 132238405Sjkim __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay, 133238405Sjkim VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); 134238405Sjkim outb(0x3c4, crtcidx); 135238405Sjkim outb(0x3c5, crtcval); 136238405Sjkim outb(0x3ce, gdcidx); 137238405Sjkim outb(0x3cf, gdcval); 138238405Sjkim } 139238405Sjkim} 140238405Sjkim 141238405Sjkimvoid 142238405SjkimVGLMouseMode(int mode) 143238405Sjkim{ 144238405Sjkim if (mode == VGL_MOUSESHOW) { 145238405Sjkim if (VGLMouseShown == VGL_MOUSEHIDE) { 146238405Sjkim VGLMousePointerShow(); 147160814Ssimon VGLMouseShown = VGL_MOUSESHOW; 148238405Sjkim } 149 } 150 else { 151 if (VGLMouseShown == VGL_MOUSESHOW) { 152 VGLMousePointerHide(); 153 VGLMouseShown = VGL_MOUSEHIDE; 154 } 155 } 156} 157 158void 159VGLMouseAction(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 178void 179VGLMouseSetImage(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 189void 190VGLMouseSetStdImage() 191{ 192 if (VGLMouseShown == VGL_MOUSESHOW) 193 VGLMousePointerHide(); 194 VGLMouseAndMask = &VGLMouseStdAndMask; 195 VGLMouseOrMask = &VGLMouseStdOrMask; 196 if (VGLMouseShown == VGL_MOUSESHOW) 197 VGLMousePointerShow(); 198} 199 200int 201VGLMouseInit(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 221int 222VGLMouseStatus(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 232int 233VGLMouseFreeze(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 271void 272VGLMouseUnFreeze() 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