xref: /freebsd/lib/libvgl/mouse.c (revision 34f210d8610b126bb3d5e37a408d9d5d2caf4136)
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 
42c0ce6f7dSBruce Evans static void VGLMouseAction(int dummy);
43c0ce6f7dSBruce Evans 
44a93ca07aSBruce Evans #define BORDER	0xff	/* default border -- light white in rgb 3:3:2 */
45a93ca07aSBruce Evans #define INTERIOR 0xa0	/* default interior -- red in rgb 3:3:2 */
46*34f210d8SBruce Evans #define LARGE_MOUSE_IMG_XSIZE	19
47*34f210d8SBruce Evans #define LARGE_MOUSE_IMG_YSIZE	32
48*34f210d8SBruce Evans #define SMALL_MOUSE_IMG_XSIZE	10
49*34f210d8SBruce Evans #define SMALL_MOUSE_IMG_YSIZE	16
50a93ca07aSBruce Evans #define X	0xff	/* any nonzero in And mask means part of cursor */
51a93ca07aSBruce Evans #define B	BORDER
52a93ca07aSBruce Evans #define I	INTERIOR
53*34f210d8SBruce Evans static byte LargeAndMask[] = {
54*34f210d8SBruce Evans   X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
55*34f210d8SBruce Evans   X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
56*34f210d8SBruce Evans   X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
57*34f210d8SBruce Evans   X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
58*34f210d8SBruce Evans   X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
59*34f210d8SBruce Evans   X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
60*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
61*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
62*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
63*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
64*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
65*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,
66*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,
67*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,
68*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,
69*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,
70*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,
71*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
72*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
73*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
74*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
75*34f210d8SBruce Evans   X,X,X,X,X,X,0,X,X,X,X,X,X,0,0,0,0,0,0,
76*34f210d8SBruce Evans   X,X,X,X,X,0,0,X,X,X,X,X,X,0,0,0,0,0,0,
77*34f210d8SBruce Evans   X,X,X,X,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0,
78*34f210d8SBruce Evans   X,X,X,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0,
79*34f210d8SBruce Evans   X,X,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,
80*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,
81*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,
82*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,
83*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,
84*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,
85*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,0,0,0,
869a57b7d2SSøren Schmidt };
87*34f210d8SBruce Evans static byte LargeOrMask[] = {
88*34f210d8SBruce Evans   B,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
89*34f210d8SBruce Evans   B,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
90*34f210d8SBruce Evans   B,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
91*34f210d8SBruce Evans   B,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
92*34f210d8SBruce Evans   B,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,
93*34f210d8SBruce Evans   B,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,
94*34f210d8SBruce Evans   B,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,
95*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,
96*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,
97*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,
98*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,
99*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,
100*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,
101*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,
102*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,
103*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,
104*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,
105*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,
106*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,B,B,B,B,B,B,B,B,
107*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,
108*34f210d8SBruce Evans   B,I,I,I,I,I,B,I,I,I,I,B,0,0,0,0,0,0,0,
109*34f210d8SBruce Evans   B,I,I,I,I,B,0,B,I,I,I,I,B,0,0,0,0,0,0,
110*34f210d8SBruce Evans   B,I,I,I,B,0,0,B,I,I,I,I,B,0,0,0,0,0,0,
111*34f210d8SBruce Evans   B,I,I,B,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0,
112*34f210d8SBruce Evans   B,I,B,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0,
113*34f210d8SBruce Evans   B,B,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,
114*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,
115*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,
116*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,
117*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,
118*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,
119*34f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,0,B,B,B,B,0,0,0,
120*34f210d8SBruce Evans };
121*34f210d8SBruce Evans static byte SmallAndMask[] = {
122*34f210d8SBruce Evans   X,X,0,0,0,0,0,0,0,0,
123*34f210d8SBruce Evans   X,X,X,0,0,0,0,0,0,0,
124*34f210d8SBruce Evans   X,X,X,X,0,0,0,0,0,0,
125*34f210d8SBruce Evans   X,X,X,X,X,0,0,0,0,0,
126*34f210d8SBruce Evans   X,X,X,X,X,X,0,0,0,0,
127*34f210d8SBruce Evans   X,X,X,X,X,X,X,0,0,0,
128*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,0,0,
129*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,0,
130*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,
131*34f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,
132*34f210d8SBruce Evans   X,X,X,X,X,X,X,0,0,0,
133*34f210d8SBruce Evans   X,X,X,0,X,X,X,X,0,0,
134*34f210d8SBruce Evans   X,X,0,0,X,X,X,X,0,0,
135*34f210d8SBruce Evans   0,0,0,0,0,X,X,X,X,0,
136*34f210d8SBruce Evans   0,0,0,0,0,X,X,X,X,0,
137*34f210d8SBruce Evans   0,0,0,0,0,0,X,X,0,0,
138*34f210d8SBruce Evans };
139*34f210d8SBruce Evans static byte SmallOrMask[] = {
140*34f210d8SBruce Evans   B,B,0,0,0,0,0,0,0,0,
141*34f210d8SBruce Evans   B,I,B,0,0,0,0,0,0,0,
142*34f210d8SBruce Evans   B,I,I,B,0,0,0,0,0,0,
143*34f210d8SBruce Evans   B,I,I,I,B,0,0,0,0,0,
144*34f210d8SBruce Evans   B,I,I,I,I,B,0,0,0,0,
145*34f210d8SBruce Evans   B,I,I,I,I,I,B,0,0,0,
146*34f210d8SBruce Evans   B,I,I,I,I,I,I,B,0,0,
147*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,B,0,
148*34f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,B,
149*34f210d8SBruce Evans   B,I,I,I,I,I,B,B,B,B,
150*34f210d8SBruce Evans   B,I,I,B,I,I,B,0,0,0,
151*34f210d8SBruce Evans   B,I,B,0,B,I,I,B,0,0,
152*34f210d8SBruce Evans   B,B,0,0,B,I,I,B,0,0,
153*34f210d8SBruce Evans   0,0,0,0,0,B,I,I,B,0,
154*34f210d8SBruce Evans   0,0,0,0,0,B,I,I,B,0,
155*34f210d8SBruce Evans   0,0,0,0,0,0,B,B,0,0,
1569a57b7d2SSøren Schmidt };
1579a57b7d2SSøren Schmidt #undef X
158a93ca07aSBruce Evans #undef B
159a93ca07aSBruce Evans #undef I
160*34f210d8SBruce Evans static VGLBitmap VGLMouseLargeAndMask =
161*34f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE,
162*34f210d8SBruce Evans                         LargeAndMask);
163*34f210d8SBruce Evans static VGLBitmap VGLMouseLargeOrMask =
164*34f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE,
165*34f210d8SBruce Evans                         LargeOrMask);
166*34f210d8SBruce Evans static VGLBitmap VGLMouseSmallAndMask =
167*34f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE,
168*34f210d8SBruce Evans                         SmallAndMask);
169*34f210d8SBruce Evans static VGLBitmap VGLMouseSmallOrMask =
170*34f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE,
171*34f210d8SBruce Evans                         SmallOrMask);
1729a57b7d2SSøren Schmidt static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
173c7432537SBruce Evans static int VGLMouseShown = VGL_MOUSEHIDE;
1749a57b7d2SSøren Schmidt static int VGLMouseXpos = 0;
1759a57b7d2SSøren Schmidt static int VGLMouseYpos = 0;
1769a57b7d2SSøren Schmidt static int VGLMouseButtons = 0;
1770410dc5fSBruce Evans static volatile sig_atomic_t VGLMintpending;
1780410dc5fSBruce Evans static volatile sig_atomic_t VGLMsuppressint;
1790410dc5fSBruce Evans 
1800410dc5fSBruce Evans #define	INTOFF()	(VGLMsuppressint++)
1810410dc5fSBruce Evans #define	INTON()		do { 						\
1820410dc5fSBruce Evans 				if (--VGLMsuppressint == 0 && VGLMintpending) \
1830410dc5fSBruce Evans 					VGLMouseAction(0);		\
1840410dc5fSBruce Evans 			} while (0)
1859a57b7d2SSøren Schmidt 
186c0ce6f7dSBruce Evans int
187c0ce6f7dSBruce Evans __VGLMouseMode(int mode)
1889a57b7d2SSøren Schmidt {
189c0ce6f7dSBruce Evans   int oldmode;
1909a57b7d2SSøren Schmidt 
1910410dc5fSBruce Evans   INTOFF();
192c0ce6f7dSBruce Evans   oldmode = VGLMouseShown;
193c0ce6f7dSBruce Evans   if (mode == VGL_MOUSESHOW) {
194c0ce6f7dSBruce Evans     if (VGLMouseShown == VGL_MOUSEHIDE) {
195c0ce6f7dSBruce Evans       VGLMouseShown = VGL_MOUSESHOW;
196*34f210d8SBruce Evans       __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos,
197*34f210d8SBruce Evans                       VGLDisplay, VGLMouseXpos, VGLMouseYpos,
198*34f210d8SBruce Evans                       VGLMouseAndMask->VXsize, -VGLMouseAndMask->VYsize);
1999a57b7d2SSøren Schmidt     }
2009a57b7d2SSøren Schmidt   }
201c0ce6f7dSBruce Evans   else {
202c0ce6f7dSBruce Evans     if (VGLMouseShown == VGL_MOUSESHOW) {
203c0ce6f7dSBruce Evans       VGLMouseShown = VGL_MOUSEHIDE;
204*34f210d8SBruce Evans       __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos,
205*34f210d8SBruce Evans                       VGLDisplay, VGLMouseXpos, VGLMouseYpos,
206*34f210d8SBruce Evans                       VGLMouseAndMask->VXsize, VGLMouseAndMask->VYsize);
207c0ce6f7dSBruce Evans     }
208c0ce6f7dSBruce Evans   }
209c0ce6f7dSBruce Evans   INTON();
210c0ce6f7dSBruce Evans   return oldmode;
211c0ce6f7dSBruce Evans }
2129a57b7d2SSøren Schmidt 
2139a57b7d2SSøren Schmidt void
2149a57b7d2SSøren Schmidt VGLMouseMode(int mode)
2159a57b7d2SSøren Schmidt {
216c0ce6f7dSBruce Evans   __VGLMouseMode(mode);
2179a57b7d2SSøren Schmidt }
2189a57b7d2SSøren Schmidt 
219c0ce6f7dSBruce Evans static void
2209a57b7d2SSøren Schmidt VGLMouseAction(int dummy)
2219a57b7d2SSøren Schmidt {
2229a57b7d2SSøren Schmidt   struct mouse_info mouseinfo;
223c0ce6f7dSBruce Evans   int mousemode;
2249a57b7d2SSøren Schmidt 
2250410dc5fSBruce Evans   if (VGLMsuppressint) {
2260410dc5fSBruce Evans     VGLMintpending = 1;
2279a57b7d2SSøren Schmidt     return;
2289a57b7d2SSøren Schmidt   }
2290410dc5fSBruce Evans again:
2300410dc5fSBruce Evans   INTOFF();
2310410dc5fSBruce Evans   VGLMintpending = 0;
2329a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_GETINFO;
2339a57b7d2SSøren Schmidt   ioctl(0, CONS_MOUSECTL, &mouseinfo);
234c0ce6f7dSBruce Evans   if (VGLMouseXpos != mouseinfo.u.data.x ||
235c0ce6f7dSBruce Evans       VGLMouseYpos != mouseinfo.u.data.y) {
236c0ce6f7dSBruce Evans     mousemode = __VGLMouseMode(VGL_MOUSEHIDE);
2379a57b7d2SSøren Schmidt     VGLMouseXpos = mouseinfo.u.data.x;
2389a57b7d2SSøren Schmidt     VGLMouseYpos = mouseinfo.u.data.y;
239c0ce6f7dSBruce Evans     __VGLMouseMode(mousemode);
240c0ce6f7dSBruce Evans   }
2419a57b7d2SSøren Schmidt   VGLMouseButtons = mouseinfo.u.data.buttons;
2420410dc5fSBruce Evans 
2430410dc5fSBruce Evans   /*
2440410dc5fSBruce Evans    * Loop to handle any new (suppressed) signals.  This is INTON() without
2450410dc5fSBruce Evans    * recursion.  !SA_RESTART prevents recursion in signal handling.  So the
2460410dc5fSBruce Evans    * maximum recursion is 2 levels.
2470410dc5fSBruce Evans    */
2480410dc5fSBruce Evans   VGLMsuppressint = 0;
2490410dc5fSBruce Evans   if (VGLMintpending)
2500410dc5fSBruce Evans     goto again;
2519a57b7d2SSøren Schmidt }
2529a57b7d2SSøren Schmidt 
2539a57b7d2SSøren Schmidt void
2549a57b7d2SSøren Schmidt VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
2559a57b7d2SSøren Schmidt {
256c0ce6f7dSBruce Evans   int mousemode;
257c0ce6f7dSBruce Evans 
258c0ce6f7dSBruce Evans   mousemode = __VGLMouseMode(VGL_MOUSEHIDE);
259a93ca07aSBruce Evans 
2609a57b7d2SSøren Schmidt   VGLMouseAndMask = AndMask;
261a93ca07aSBruce Evans 
262a93ca07aSBruce Evans   if (VGLMouseOrMask != NULL) {
263a93ca07aSBruce Evans     free(VGLMouseOrMask->Bitmap);
264a93ca07aSBruce Evans     free(VGLMouseOrMask);
265a93ca07aSBruce Evans   }
266a93ca07aSBruce Evans   VGLMouseOrMask = VGLBitmapCreate(MEMBUF, OrMask->VXsize, OrMask->VYsize, 0);
267a93ca07aSBruce Evans   VGLBitmapAllocateBits(VGLMouseOrMask);
268a93ca07aSBruce Evans   VGLBitmapCvt(OrMask, VGLMouseOrMask);
269a93ca07aSBruce Evans 
270c0ce6f7dSBruce Evans   __VGLMouseMode(mousemode);
2719a57b7d2SSøren Schmidt }
2729a57b7d2SSøren Schmidt 
2739a57b7d2SSøren Schmidt void
2749a57b7d2SSøren Schmidt VGLMouseSetStdImage()
2759a57b7d2SSøren Schmidt {
276*34f210d8SBruce Evans   if (VGLDisplay->VXsize > 800)
277*34f210d8SBruce Evans     VGLMouseSetImage(&VGLMouseLargeAndMask, &VGLMouseLargeOrMask);
278*34f210d8SBruce Evans   else
279*34f210d8SBruce Evans     VGLMouseSetImage(&VGLMouseSmallAndMask, &VGLMouseSmallOrMask);
2809a57b7d2SSøren Schmidt }
2819a57b7d2SSøren Schmidt 
2829a57b7d2SSøren Schmidt int
2839a57b7d2SSøren Schmidt VGLMouseInit(int mode)
2849a57b7d2SSøren Schmidt {
2859a57b7d2SSøren Schmidt   struct mouse_info mouseinfo;
286*34f210d8SBruce Evans   VGLBitmap *ormask;
287a93ca07aSBruce Evans   int andmask, border, error, i, interior;
2889a57b7d2SSøren Schmidt 
289aa1ce985SBruce Evans   switch (VGLModeInfo.vi_mem_model) {
290aa1ce985SBruce Evans   case V_INFO_MM_PACKED:
291aa1ce985SBruce Evans   case V_INFO_MM_PLANAR:
292a93ca07aSBruce Evans     andmask = 0x0f;
293a93ca07aSBruce Evans     border = 0x0f;
294a93ca07aSBruce Evans     interior = 0x04;
295aa1ce985SBruce Evans     break;
296aa1ce985SBruce Evans   case V_INFO_MM_VGAX:
297a93ca07aSBruce Evans     andmask = 0x3f;
298a93ca07aSBruce Evans     border = 0x3f;
299a93ca07aSBruce Evans     interior = 0x24;
300aa1ce985SBruce Evans     break;
301aa1ce985SBruce Evans   default:
302a93ca07aSBruce Evans     andmask = 0xff;
303a93ca07aSBruce Evans     border = BORDER;
304a93ca07aSBruce Evans     interior = INTERIOR;
305aa1ce985SBruce Evans     break;
306aa1ce985SBruce Evans   }
307a93ca07aSBruce Evans   if (VGLModeInfo.vi_mode == M_BG640x480)
308a93ca07aSBruce Evans     border = 0;		/* XXX (palette makes 0x04 look like 0x0f) */
309a93ca07aSBruce Evans   if (getenv("VGLMOUSEBORDERCOLOR") != NULL)
310a93ca07aSBruce Evans     border = strtoul(getenv("VGLMOUSEBORDERCOLOR"), NULL, 0);
311a93ca07aSBruce Evans   if (getenv("VGLMOUSEINTERIORCOLOR") != NULL)
312a93ca07aSBruce Evans     interior = strtoul(getenv("VGLMOUSEINTERIORCOLOR"), NULL, 0);
313*34f210d8SBruce Evans   ormask = &VGLMouseLargeOrMask;
314*34f210d8SBruce Evans   for (i = 0; i < ormask->VXsize * ormask->VYsize; i++)
315*34f210d8SBruce Evans     ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ?  border :
316*34f210d8SBruce Evans                         ormask->Bitmap[i] == INTERIOR ? interior : 0;
317*34f210d8SBruce Evans   ormask = &VGLMouseSmallOrMask;
318*34f210d8SBruce Evans   for (i = 0; i < ormask->VXsize * ormask->VYsize; i++)
319*34f210d8SBruce Evans     ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ?  border :
320*34f210d8SBruce Evans                         ormask->Bitmap[i] == INTERIOR ? interior : 0;
3219a57b7d2SSøren Schmidt   VGLMouseSetStdImage();
3229a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_MODE;
3239a57b7d2SSøren Schmidt   mouseinfo.u.mode.signal = SIGUSR2;
3249a57b7d2SSøren Schmidt   if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
3259a57b7d2SSøren Schmidt     return error;
3269a57b7d2SSøren Schmidt   signal(SIGUSR2, VGLMouseAction);
3279a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_GETINFO;
3289a57b7d2SSøren Schmidt   ioctl(0, CONS_MOUSECTL, &mouseinfo);
3299a57b7d2SSøren Schmidt   VGLMouseXpos = mouseinfo.u.data.x;
3309a57b7d2SSøren Schmidt   VGLMouseYpos = mouseinfo.u.data.y;
3319a57b7d2SSøren Schmidt   VGLMouseButtons = mouseinfo.u.data.buttons;
3329a57b7d2SSøren Schmidt   VGLMouseMode(mode);
3339a57b7d2SSøren Schmidt   return 0;
3349a57b7d2SSøren Schmidt }
3359a57b7d2SSøren Schmidt 
336e848f3d1SBruce Evans void
337e848f3d1SBruce Evans VGLMouseRestore(void)
338e848f3d1SBruce Evans {
339e848f3d1SBruce Evans   struct mouse_info mouseinfo;
340e848f3d1SBruce Evans 
341e848f3d1SBruce Evans   INTOFF();
342e848f3d1SBruce Evans   mouseinfo.operation = MOUSE_GETINFO;
343e848f3d1SBruce Evans   if (ioctl(0, CONS_MOUSECTL, &mouseinfo) == 0) {
344e848f3d1SBruce Evans     mouseinfo.operation = MOUSE_MOVEABS;
345e848f3d1SBruce Evans     mouseinfo.u.data.x = VGLMouseXpos;
346e848f3d1SBruce Evans     mouseinfo.u.data.y = VGLMouseYpos;
347e848f3d1SBruce Evans     ioctl(0, CONS_MOUSECTL, &mouseinfo);
348e848f3d1SBruce Evans   }
349e848f3d1SBruce Evans   INTON();
350e848f3d1SBruce Evans }
351e848f3d1SBruce Evans 
3529a57b7d2SSøren Schmidt int
3539a57b7d2SSøren Schmidt VGLMouseStatus(int *x, int *y, char *buttons)
3549a57b7d2SSøren Schmidt {
3550410dc5fSBruce Evans   INTOFF();
3569a57b7d2SSøren Schmidt   *x =  VGLMouseXpos;
3579a57b7d2SSøren Schmidt   *y =  VGLMouseYpos;
3589a57b7d2SSøren Schmidt   *buttons =  VGLMouseButtons;
3590410dc5fSBruce Evans   INTON();
3609a57b7d2SSøren Schmidt   return VGLMouseShown;
3619a57b7d2SSøren Schmidt }
3629a57b7d2SSøren Schmidt 
363c7432537SBruce Evans void
364c7432537SBruce Evans VGLMouseFreeze(void)
3659a57b7d2SSøren Schmidt {
3660410dc5fSBruce Evans   INTOFF();
367c7432537SBruce Evans }
368c7432537SBruce Evans 
369c7432537SBruce Evans int
370c7432537SBruce Evans VGLMouseFreezeXY(int x, int y)
371c7432537SBruce Evans {
372c7432537SBruce Evans   INTOFF();
373c7432537SBruce Evans   if (VGLMouseShown != VGL_MOUSESHOW)
374c7432537SBruce Evans     return 0;
375*34f210d8SBruce Evans   if (x >= VGLMouseXpos && x < VGLMouseXpos + VGLMouseAndMask->VXsize &&
376*34f210d8SBruce Evans       y >= VGLMouseYpos && y < VGLMouseYpos + VGLMouseAndMask->VYsize &&
377*34f210d8SBruce Evans       VGLMouseAndMask->Bitmap[(y-VGLMouseYpos)*VGLMouseAndMask->VXsize+
378*34f210d8SBruce Evans                               (x-VGLMouseXpos)])
379c7432537SBruce Evans     return 1;
380c7432537SBruce Evans   return 0;
381c7432537SBruce Evans }
382c7432537SBruce Evans 
383c7432537SBruce Evans int
384c7432537SBruce Evans VGLMouseOverlap(int x, int y, int width, int hight)
385c7432537SBruce Evans {
3869a57b7d2SSøren Schmidt   int overlap;
3879a57b7d2SSøren Schmidt 
388c7432537SBruce Evans   if (VGLMouseShown != VGL_MOUSESHOW)
389c7432537SBruce Evans     return 0;
3909a57b7d2SSøren Schmidt   if (x > VGLMouseXpos)
391*34f210d8SBruce Evans     overlap = (VGLMouseXpos + VGLMouseAndMask->VXsize) - x;
3929a57b7d2SSøren Schmidt   else
3939a57b7d2SSøren Schmidt     overlap = (x + width) - VGLMouseXpos;
394c7432537SBruce Evans   if (overlap <= 0)
395c7432537SBruce Evans     return 0;
3969a57b7d2SSøren Schmidt   if (y > VGLMouseYpos)
397*34f210d8SBruce Evans     overlap = (VGLMouseYpos + VGLMouseAndMask->VYsize) - y;
3989a57b7d2SSøren Schmidt   else
3999a57b7d2SSøren Schmidt     overlap = (y + hight) - VGLMouseYpos;
400c7432537SBruce Evans   return overlap > 0;
4019a57b7d2SSøren Schmidt }
4029a57b7d2SSøren Schmidt 
4039a57b7d2SSøren Schmidt void
404a07067eaSBruce Evans VGLMouseMerge(int x, int y, int width, byte *line)
405a07067eaSBruce Evans {
406a07067eaSBruce Evans   int pos, x1, xend, xstart;
407a07067eaSBruce Evans 
408a07067eaSBruce Evans   xstart = x;
409a07067eaSBruce Evans   if (xstart < VGLMouseXpos)
410a07067eaSBruce Evans     xstart = VGLMouseXpos;
411a07067eaSBruce Evans   xend = x + width;
412*34f210d8SBruce Evans   if (xend > VGLMouseXpos + VGLMouseAndMask->VXsize)
413*34f210d8SBruce Evans     xend = VGLMouseXpos + VGLMouseAndMask->VXsize;
414a07067eaSBruce Evans   for (x1 = xstart; x1 < xend; x1++) {
415*34f210d8SBruce Evans     pos = (y - VGLMouseYpos) * VGLMouseAndMask->VXsize + x1 - VGLMouseXpos;
416a07067eaSBruce Evans     if (VGLMouseAndMask->Bitmap[pos])
417a07067eaSBruce Evans       bcopy(&VGLMouseOrMask->Bitmap[pos * VGLDisplay->PixelBytes],
418a07067eaSBruce Evans             &line[(x1 - x) * VGLDisplay->PixelBytes], VGLDisplay->PixelBytes);
419a07067eaSBruce Evans   }
420a07067eaSBruce Evans }
421a07067eaSBruce Evans 
422a07067eaSBruce Evans void
4239a57b7d2SSøren Schmidt VGLMouseUnFreeze()
4249a57b7d2SSøren Schmidt {
4250410dc5fSBruce Evans   INTON();
4269a57b7d2SSøren Schmidt }
427