xref: /freebsd/lib/libvgl/mouse.c (revision e848f3d19c724083c0ccf4ac1e353e0a10e884b7)
19a57b7d2SSøren Schmidt /*-
25e53a4f9SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
35e53a4f9SPedro F. Giffuni  *
4bf3f9db6SUlrich Spörlein  * Copyright (c) 1991-1997 Søren Schmidt
59a57b7d2SSøren Schmidt  * All rights reserved.
69a57b7d2SSøren Schmidt  *
79a57b7d2SSøren Schmidt  * Redistribution and use in source and binary forms, with or without
89a57b7d2SSøren Schmidt  * modification, are permitted provided that the following conditions
99a57b7d2SSøren Schmidt  * are met:
109a57b7d2SSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
119a57b7d2SSøren Schmidt  *    notice, this list of conditions and the following disclaimer
129a57b7d2SSøren Schmidt  *    in this position and unchanged.
139a57b7d2SSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
149a57b7d2SSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
159a57b7d2SSøren Schmidt  *    documentation and/or other materials provided with the distribution.
169a57b7d2SSøren Schmidt  * 3. The name of the author may not be used to endorse or promote products
1721dc7d4fSJens Schweikhardt  *    derived from this software without specific prior written permission
189a57b7d2SSøren Schmidt  *
199a57b7d2SSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
209a57b7d2SSøren Schmidt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
219a57b7d2SSøren Schmidt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
229a57b7d2SSøren Schmidt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
239a57b7d2SSøren Schmidt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
249a57b7d2SSøren Schmidt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
259a57b7d2SSøren Schmidt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
269a57b7d2SSøren Schmidt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
279a57b7d2SSøren Schmidt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
289a57b7d2SSøren Schmidt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
299a57b7d2SSøren Schmidt  */
309a57b7d2SSøren Schmidt 
31e67f5b9fSMatthew Dillon #include <sys/cdefs.h>
32e67f5b9fSMatthew Dillon __FBSDID("$FreeBSD$");
33e67f5b9fSMatthew Dillon 
349a57b7d2SSøren Schmidt #include <stdio.h>
359a57b7d2SSøren Schmidt #include <sys/types.h>
369a57b7d2SSøren Schmidt #include <sys/ioctl.h>
379a57b7d2SSøren Schmidt #include <sys/signal.h>
3800d25f51SPoul-Henning Kamp #include <sys/consio.h>
3900d25f51SPoul-Henning Kamp #include <sys/fbio.h>
409a57b7d2SSøren Schmidt #include "vgl.h"
419a57b7d2SSøren Schmidt 
429a57b7d2SSøren Schmidt #define X 0xff
439a57b7d2SSøren Schmidt static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
449a57b7d2SSøren Schmidt 	X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
459a57b7d2SSøren Schmidt 	X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
469a57b7d2SSøren Schmidt 	X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
479a57b7d2SSøren Schmidt 	X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
489a57b7d2SSøren Schmidt 	X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
499a57b7d2SSøren Schmidt 	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
509a57b7d2SSøren Schmidt 	X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
519a57b7d2SSøren Schmidt 	X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
529a57b7d2SSøren Schmidt 	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
539a57b7d2SSøren Schmidt 	0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0,
549a57b7d2SSøren Schmidt 	0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0,
559a57b7d2SSøren Schmidt 	0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
569a57b7d2SSøren Schmidt 	0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
579a57b7d2SSøren Schmidt 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
589a57b7d2SSøren Schmidt 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
599a57b7d2SSøren Schmidt 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
609a57b7d2SSøren Schmidt };
619a57b7d2SSøren Schmidt static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
629a57b7d2SSøren Schmidt 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
639a57b7d2SSøren Schmidt 	0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
649a57b7d2SSøren Schmidt 	0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
659a57b7d2SSøren Schmidt 	0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
669a57b7d2SSøren Schmidt 	0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
679a57b7d2SSøren Schmidt 	0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
689a57b7d2SSøren Schmidt 	0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
699a57b7d2SSøren Schmidt 	0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0,
709a57b7d2SSøren Schmidt 	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
719a57b7d2SSøren Schmidt 	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
729a57b7d2SSøren Schmidt 	0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
739a57b7d2SSøren Schmidt 	0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
749a57b7d2SSøren Schmidt 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
759a57b7d2SSøren Schmidt 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
769a57b7d2SSøren Schmidt 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
779a57b7d2SSøren Schmidt 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
789a57b7d2SSøren Schmidt };
799a57b7d2SSøren Schmidt #undef X
809a57b7d2SSøren Schmidt static VGLBitmap VGLMouseStdAndMask =
815acf51eaSKazutaka YOKOTA     VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask);
829a57b7d2SSøren Schmidt static VGLBitmap VGLMouseStdOrMask =
835acf51eaSKazutaka YOKOTA     VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask);
849a57b7d2SSøren Schmidt static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
85fbc6daa1SBruce Evans static byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE*4];
865acf51eaSKazutaka YOKOTA static VGLBitmap VGLMouseSave =
875acf51eaSKazutaka YOKOTA     VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map);
889a57b7d2SSøren Schmidt static int VGLMouseVisible = 0;
899a57b7d2SSøren Schmidt static int VGLMouseShown = 0;
909a57b7d2SSøren Schmidt static int VGLMouseXpos = 0;
919a57b7d2SSøren Schmidt static int VGLMouseYpos = 0;
929a57b7d2SSøren Schmidt static int VGLMouseButtons = 0;
930410dc5fSBruce Evans static volatile sig_atomic_t VGLMintpending;
940410dc5fSBruce Evans static volatile sig_atomic_t VGLMsuppressint;
950410dc5fSBruce Evans 
960410dc5fSBruce Evans #define	INTOFF()	(VGLMsuppressint++)
970410dc5fSBruce Evans #define	INTON()		do { 						\
980410dc5fSBruce Evans 				if (--VGLMsuppressint == 0 && VGLMintpending) \
990410dc5fSBruce Evans 					VGLMouseAction(0);		\
1000410dc5fSBruce Evans 			} while (0)
1019a57b7d2SSøren Schmidt 
1029a57b7d2SSøren Schmidt void
1039a57b7d2SSøren Schmidt VGLMousePointerShow()
1049a57b7d2SSøren Schmidt {
105fbc6daa1SBruce Evans   byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE*4];
1065acf51eaSKazutaka YOKOTA   VGLBitmap buffer =
1075acf51eaSKazutaka YOKOTA     VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf);
1089a57b7d2SSøren Schmidt   byte crtcidx, crtcval, gdcidx, gdcval;
109aa1ce985SBruce Evans   int i, pos, pos1;
1109a57b7d2SSøren Schmidt 
1119a57b7d2SSøren Schmidt   if (!VGLMouseVisible) {
1120410dc5fSBruce Evans     INTOFF();
1139a57b7d2SSøren Schmidt     VGLMouseVisible = 1;
11480b4b86eSBruce Evans     if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT) {
1159a57b7d2SSøren Schmidt       crtcidx = inb(0x3c4);
1169a57b7d2SSøren Schmidt       crtcval = inb(0x3c5);
1179a57b7d2SSøren Schmidt       gdcidx = inb(0x3ce);
1189a57b7d2SSøren Schmidt       gdcval = inb(0x3cf);
11980b4b86eSBruce Evans     }
1209a57b7d2SSøren Schmidt     __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos,
1219a57b7d2SSøren Schmidt 		  &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
122aa1ce985SBruce Evans     bcopy(VGLMouseSave.Bitmap, buffer.Bitmap,
123aa1ce985SBruce Evans           MOUSE_IMG_SIZE*MOUSE_IMG_SIZE*VGLDisplay->PixelBytes);
1249a57b7d2SSøren Schmidt     for (pos = 0; pos <  MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++)
125aa1ce985SBruce Evans       for (i = 0; i < VGLDisplay->PixelBytes; i++) {
126aa1ce985SBruce Evans         pos1 = pos * VGLDisplay->PixelBytes + i;
127aa1ce985SBruce Evans         buffer.Bitmap[pos1] = (buffer.Bitmap[pos1] &
128aa1ce985SBruce Evans                                ~VGLMouseAndMask->Bitmap[pos]) |
1299a57b7d2SSøren Schmidt                               VGLMouseOrMask->Bitmap[pos];
130aa1ce985SBruce Evans       }
1319a57b7d2SSøren Schmidt     __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay,
1329a57b7d2SSøren Schmidt 		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
13380b4b86eSBruce Evans     if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT) {
1349a57b7d2SSøren Schmidt       outb(0x3c4, crtcidx);
1359a57b7d2SSøren Schmidt       outb(0x3c5, crtcval);
1369a57b7d2SSøren Schmidt       outb(0x3ce, gdcidx);
1379a57b7d2SSøren Schmidt       outb(0x3cf, gdcval);
13880b4b86eSBruce Evans     }
1390410dc5fSBruce Evans     INTON();
1409a57b7d2SSøren Schmidt   }
1419a57b7d2SSøren Schmidt }
1429a57b7d2SSøren Schmidt 
1439a57b7d2SSøren Schmidt void
1449a57b7d2SSøren Schmidt VGLMousePointerHide()
1459a57b7d2SSøren Schmidt {
1469a57b7d2SSøren Schmidt   byte crtcidx, crtcval, gdcidx, gdcval;
1479a57b7d2SSøren Schmidt 
1489a57b7d2SSøren Schmidt   if (VGLMouseVisible) {
1490410dc5fSBruce Evans     INTOFF();
1509a57b7d2SSøren Schmidt     VGLMouseVisible = 0;
15180b4b86eSBruce Evans     if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT) {
1529a57b7d2SSøren Schmidt       crtcidx = inb(0x3c4);
1539a57b7d2SSøren Schmidt       crtcval = inb(0x3c5);
1549a57b7d2SSøren Schmidt       gdcidx = inb(0x3ce);
1559a57b7d2SSøren Schmidt       gdcval = inb(0x3cf);
15680b4b86eSBruce Evans     }
1579a57b7d2SSøren Schmidt     __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay,
1589a57b7d2SSøren Schmidt 		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
15980b4b86eSBruce Evans     if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT) {
1609a57b7d2SSøren Schmidt       outb(0x3c4, crtcidx);
1619a57b7d2SSøren Schmidt       outb(0x3c5, crtcval);
1629a57b7d2SSøren Schmidt       outb(0x3ce, gdcidx);
1639a57b7d2SSøren Schmidt       outb(0x3cf, gdcval);
16480b4b86eSBruce Evans     }
1650410dc5fSBruce Evans     INTON();
1669a57b7d2SSøren Schmidt   }
1679a57b7d2SSøren Schmidt }
1689a57b7d2SSøren Schmidt 
1699a57b7d2SSøren Schmidt void
1709a57b7d2SSøren Schmidt VGLMouseMode(int mode)
1719a57b7d2SSøren Schmidt {
1729a57b7d2SSøren Schmidt   if (mode == VGL_MOUSESHOW) {
1739a57b7d2SSøren Schmidt     if (VGLMouseShown == VGL_MOUSEHIDE) {
1749a57b7d2SSøren Schmidt       VGLMousePointerShow();
1759a57b7d2SSøren Schmidt       VGLMouseShown = VGL_MOUSESHOW;
1769a57b7d2SSøren Schmidt     }
1779a57b7d2SSøren Schmidt   }
1789a57b7d2SSøren Schmidt   else {
1799a57b7d2SSøren Schmidt     if (VGLMouseShown == VGL_MOUSESHOW) {
1809a57b7d2SSøren Schmidt       VGLMousePointerHide();
1819a57b7d2SSøren Schmidt       VGLMouseShown = VGL_MOUSEHIDE;
1829a57b7d2SSøren Schmidt     }
1839a57b7d2SSøren Schmidt   }
1849a57b7d2SSøren Schmidt }
1859a57b7d2SSøren Schmidt 
1869a57b7d2SSøren Schmidt void
1879a57b7d2SSøren Schmidt VGLMouseAction(int dummy)
1889a57b7d2SSøren Schmidt {
1899a57b7d2SSøren Schmidt   struct mouse_info mouseinfo;
1909a57b7d2SSøren Schmidt 
1910410dc5fSBruce Evans   if (VGLMsuppressint) {
1920410dc5fSBruce Evans     VGLMintpending = 1;
1939a57b7d2SSøren Schmidt     return;
1949a57b7d2SSøren Schmidt   }
1950410dc5fSBruce Evans again:
1960410dc5fSBruce Evans   INTOFF();
1970410dc5fSBruce Evans   VGLMintpending = 0;
1989a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_GETINFO;
1999a57b7d2SSøren Schmidt   ioctl(0, CONS_MOUSECTL, &mouseinfo);
2009a57b7d2SSøren Schmidt   if (VGLMouseShown == VGL_MOUSESHOW)
2019a57b7d2SSøren Schmidt     VGLMousePointerHide();
2029a57b7d2SSøren Schmidt   VGLMouseXpos = mouseinfo.u.data.x;
2039a57b7d2SSøren Schmidt   VGLMouseYpos = mouseinfo.u.data.y;
2049a57b7d2SSøren Schmidt   VGLMouseButtons = mouseinfo.u.data.buttons;
2059a57b7d2SSøren Schmidt   if (VGLMouseShown == VGL_MOUSESHOW)
2069a57b7d2SSøren Schmidt     VGLMousePointerShow();
2070410dc5fSBruce Evans 
2080410dc5fSBruce Evans   /*
2090410dc5fSBruce Evans    * Loop to handle any new (suppressed) signals.  This is INTON() without
2100410dc5fSBruce Evans    * recursion.  !SA_RESTART prevents recursion in signal handling.  So the
2110410dc5fSBruce Evans    * maximum recursion is 2 levels.
2120410dc5fSBruce Evans    */
2130410dc5fSBruce Evans   VGLMsuppressint = 0;
2140410dc5fSBruce Evans   if (VGLMintpending)
2150410dc5fSBruce Evans     goto again;
2169a57b7d2SSøren Schmidt }
2179a57b7d2SSøren Schmidt 
2189a57b7d2SSøren Schmidt void
2199a57b7d2SSøren Schmidt VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
2209a57b7d2SSøren Schmidt {
2219a57b7d2SSøren Schmidt   if (VGLMouseShown == VGL_MOUSESHOW)
2229a57b7d2SSøren Schmidt     VGLMousePointerHide();
2239a57b7d2SSøren Schmidt   VGLMouseAndMask = AndMask;
2249a57b7d2SSøren Schmidt   VGLMouseOrMask = OrMask;
2259a57b7d2SSøren Schmidt   if (VGLMouseShown == VGL_MOUSESHOW)
2269a57b7d2SSøren Schmidt     VGLMousePointerShow();
2279a57b7d2SSøren Schmidt }
2289a57b7d2SSøren Schmidt 
2299a57b7d2SSøren Schmidt void
2309a57b7d2SSøren Schmidt VGLMouseSetStdImage()
2319a57b7d2SSøren Schmidt {
2329a57b7d2SSøren Schmidt   if (VGLMouseShown == VGL_MOUSESHOW)
2339a57b7d2SSøren Schmidt     VGLMousePointerHide();
2349a57b7d2SSøren Schmidt   VGLMouseAndMask = &VGLMouseStdAndMask;
2359a57b7d2SSøren Schmidt   VGLMouseOrMask = &VGLMouseStdOrMask;
2369a57b7d2SSøren Schmidt   if (VGLMouseShown == VGL_MOUSESHOW)
2379a57b7d2SSøren Schmidt     VGLMousePointerShow();
2389a57b7d2SSøren Schmidt }
2399a57b7d2SSøren Schmidt 
2409a57b7d2SSøren Schmidt int
2419a57b7d2SSøren Schmidt VGLMouseInit(int mode)
2429a57b7d2SSøren Schmidt {
2439a57b7d2SSøren Schmidt   struct mouse_info mouseinfo;
244aa1ce985SBruce Evans   int error, i, mask;
2459a57b7d2SSøren Schmidt 
246aa1ce985SBruce Evans   switch (VGLModeInfo.vi_mem_model) {
247aa1ce985SBruce Evans   case V_INFO_MM_PACKED:
248aa1ce985SBruce Evans   case V_INFO_MM_PLANAR:
249aa1ce985SBruce Evans     mask = 0x0f;
250aa1ce985SBruce Evans     break;
251aa1ce985SBruce Evans   case V_INFO_MM_VGAX:
252aa1ce985SBruce Evans     mask = 0x3f;
253aa1ce985SBruce Evans     break;
254aa1ce985SBruce Evans   default:
255aa1ce985SBruce Evans     mask = 0xff;
256aa1ce985SBruce Evans     break;
257aa1ce985SBruce Evans   }
258aa1ce985SBruce Evans   for (i = 0; i < 256; i++)
259aa1ce985SBruce Evans     VGLMouseStdOrMask.Bitmap[i] &= mask;
2609a57b7d2SSøren Schmidt   VGLMouseSetStdImage();
2619a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_MODE;
2629a57b7d2SSøren Schmidt   mouseinfo.u.mode.signal = SIGUSR2;
2639a57b7d2SSøren Schmidt   if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
2649a57b7d2SSøren Schmidt     return error;
2659a57b7d2SSøren Schmidt   signal(SIGUSR2, VGLMouseAction);
2669a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_GETINFO;
2679a57b7d2SSøren Schmidt   ioctl(0, CONS_MOUSECTL, &mouseinfo);
2689a57b7d2SSøren Schmidt   VGLMouseXpos = mouseinfo.u.data.x;
2699a57b7d2SSøren Schmidt   VGLMouseYpos = mouseinfo.u.data.y;
2709a57b7d2SSøren Schmidt   VGLMouseButtons = mouseinfo.u.data.buttons;
2719a57b7d2SSøren Schmidt   VGLMouseMode(mode);
2729a57b7d2SSøren Schmidt   return 0;
2739a57b7d2SSøren Schmidt }
2749a57b7d2SSøren Schmidt 
275*e848f3d1SBruce Evans void
276*e848f3d1SBruce Evans VGLMouseRestore(void)
277*e848f3d1SBruce Evans {
278*e848f3d1SBruce Evans   struct mouse_info mouseinfo;
279*e848f3d1SBruce Evans 
280*e848f3d1SBruce Evans   INTOFF();
281*e848f3d1SBruce Evans   mouseinfo.operation = MOUSE_GETINFO;
282*e848f3d1SBruce Evans   if (ioctl(0, CONS_MOUSECTL, &mouseinfo) == 0) {
283*e848f3d1SBruce Evans     mouseinfo.operation = MOUSE_MOVEABS;
284*e848f3d1SBruce Evans     mouseinfo.u.data.x = VGLMouseXpos;
285*e848f3d1SBruce Evans     mouseinfo.u.data.y = VGLMouseYpos;
286*e848f3d1SBruce Evans     ioctl(0, CONS_MOUSECTL, &mouseinfo);
287*e848f3d1SBruce Evans   }
288*e848f3d1SBruce Evans   INTON();
289*e848f3d1SBruce Evans }
290*e848f3d1SBruce Evans 
2919a57b7d2SSøren Schmidt int
2929a57b7d2SSøren Schmidt VGLMouseStatus(int *x, int *y, char *buttons)
2939a57b7d2SSøren Schmidt {
2940410dc5fSBruce Evans   INTOFF();
2959a57b7d2SSøren Schmidt   *x =  VGLMouseXpos;
2969a57b7d2SSøren Schmidt   *y =  VGLMouseYpos;
2979a57b7d2SSøren Schmidt   *buttons =  VGLMouseButtons;
2980410dc5fSBruce Evans   INTON();
2999a57b7d2SSøren Schmidt   return VGLMouseShown;
3009a57b7d2SSøren Schmidt }
3019a57b7d2SSøren Schmidt 
3029a57b7d2SSøren Schmidt int
303dd31deb8SBruce Evans VGLMouseFreeze(int x, int y, int width, int hight, u_long color)
3049a57b7d2SSøren Schmidt {
305aa1ce985SBruce Evans   int i, xstride, ystride;
306aa1ce985SBruce Evans 
3070410dc5fSBruce Evans     INTOFF();
308014ddcbcSBruce Evans     if (width > 1 || hight > 1 || (color & 0xc0000000) == 0) { /* bitmap */
3099a57b7d2SSøren Schmidt       if (VGLMouseShown == 1) {
3109a57b7d2SSøren Schmidt         int overlap;
3119a57b7d2SSøren Schmidt 
3129a57b7d2SSøren Schmidt         if (x > VGLMouseXpos)
3139a57b7d2SSøren Schmidt           overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x;
3149a57b7d2SSøren Schmidt         else
3159a57b7d2SSøren Schmidt           overlap = (x + width) - VGLMouseXpos;
3169a57b7d2SSøren Schmidt         if (overlap > 0) {
3179a57b7d2SSøren Schmidt           if (y > VGLMouseYpos)
3189a57b7d2SSøren Schmidt             overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y;
3199a57b7d2SSøren Schmidt           else
3209a57b7d2SSøren Schmidt             overlap = (y + hight) - VGLMouseYpos;
3219a57b7d2SSøren Schmidt           if (overlap > 0)
3229a57b7d2SSøren Schmidt             VGLMousePointerHide();
3239a57b7d2SSøren Schmidt         }
3249a57b7d2SSøren Schmidt       }
3259a57b7d2SSøren Schmidt     }
3269a57b7d2SSøren Schmidt     else {				/* bit */
3279a57b7d2SSøren Schmidt       if (VGLMouseShown &&
3289a57b7d2SSøren Schmidt           x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE &&
3299a57b7d2SSøren Schmidt           y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) {
330aa1ce985SBruce Evans         xstride = VGLDisplay->PixelBytes;
331aa1ce985SBruce Evans         ystride = MOUSE_IMG_SIZE * xstride;
332014ddcbcSBruce Evans         if (color & 0x40000000) {	/* Get */
333014ddcbcSBruce Evans           color = 0;
334014ddcbcSBruce Evans           for (i = xstride - 1; i >= 0; i--)
335014ddcbcSBruce Evans             color = (color << 8) |
336014ddcbcSBruce Evans                     VGLMouseSave.Bitmap[(y-VGLMouseYpos)*ystride+
337014ddcbcSBruce Evans                                         (x-VGLMouseXpos)*xstride+i];
338014ddcbcSBruce Evans           return 0x40000000 | (color & 0xffffff);
339014ddcbcSBruce Evans         } else {			/* Set */
340014ddcbcSBruce Evans           color &= 0xffffff;		/* discard flag and other garbage */
341aa1ce985SBruce Evans           for (i = 0; i < xstride; i++, color >>= 8)
342aa1ce985SBruce Evans             VGLMouseSave.Bitmap[(y-VGLMouseYpos)*ystride+
343aa1ce985SBruce Evans                                 (x-VGLMouseXpos)*xstride+i] = color;
3449a57b7d2SSøren Schmidt           if (VGLMouseAndMask->Bitmap
3459a57b7d2SSøren Schmidt             [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) {
3469a57b7d2SSøren Schmidt             return 1;
3479a57b7d2SSøren Schmidt           }
3489a57b7d2SSøren Schmidt         }
3499a57b7d2SSøren Schmidt       }
3509a57b7d2SSøren Schmidt     }
3519a57b7d2SSøren Schmidt   return 0;
3529a57b7d2SSøren Schmidt }
3539a57b7d2SSøren Schmidt 
3549a57b7d2SSøren Schmidt void
3559a57b7d2SSøren Schmidt VGLMouseUnFreeze()
3569a57b7d2SSøren Schmidt {
3570410dc5fSBruce Evans   if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible && !VGLMintpending)
3589a57b7d2SSøren Schmidt     VGLMousePointerShow();
3590410dc5fSBruce Evans   while (VGLMsuppressint)
3600410dc5fSBruce Evans     INTON();
3619a57b7d2SSøren Schmidt }
362