xref: /freebsd/lib/libvgl/mouse.c (revision 035dd78d30ba28a3dc15c05ec85ad10127165677)
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 */
4634f210d8SBruce Evans #define LARGE_MOUSE_IMG_XSIZE	19
4734f210d8SBruce Evans #define LARGE_MOUSE_IMG_YSIZE	32
4834f210d8SBruce Evans #define SMALL_MOUSE_IMG_XSIZE	10
4934f210d8SBruce 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
5334f210d8SBruce Evans static byte LargeAndMask[] = {
5434f210d8SBruce Evans   X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5534f210d8SBruce Evans   X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5634f210d8SBruce Evans   X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5734f210d8SBruce Evans   X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5834f210d8SBruce Evans   X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
5934f210d8SBruce Evans   X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
6034f210d8SBruce Evans   X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
6134f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
6234f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
6334f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
6434f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
6534f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,
6634f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,
6734f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,
6834f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,
6934f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,
7034f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,
7134f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
7234f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
7334f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
7434f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
7534f210d8SBruce Evans   X,X,X,X,X,X,0,X,X,X,X,X,X,0,0,0,0,0,0,
7634f210d8SBruce Evans   X,X,X,X,X,0,0,X,X,X,X,X,X,0,0,0,0,0,0,
7734f210d8SBruce Evans   X,X,X,X,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0,
7834f210d8SBruce Evans   X,X,X,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0,
7934f210d8SBruce Evans   X,X,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,
8034f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,
8134f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,
8234f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,
8334f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,
8434f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,
8534f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,0,0,0,
869a57b7d2SSøren Schmidt };
8734f210d8SBruce Evans static byte LargeOrMask[] = {
8834f210d8SBruce Evans   B,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8934f210d8SBruce Evans   B,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9034f210d8SBruce Evans   B,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9134f210d8SBruce Evans   B,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9234f210d8SBruce Evans   B,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,
9334f210d8SBruce Evans   B,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,
9434f210d8SBruce Evans   B,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,
9534f210d8SBruce Evans   B,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,
9634f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,
9734f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,
9834f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,
9934f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,
10034f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,
10134f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,
10234f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,
10334f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,
10434f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,
10534f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,
10634f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,B,B,B,B,B,B,B,B,
10734f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,
10834f210d8SBruce Evans   B,I,I,I,I,I,B,I,I,I,I,B,0,0,0,0,0,0,0,
10934f210d8SBruce Evans   B,I,I,I,I,B,0,B,I,I,I,I,B,0,0,0,0,0,0,
11034f210d8SBruce Evans   B,I,I,I,B,0,0,B,I,I,I,I,B,0,0,0,0,0,0,
11134f210d8SBruce Evans   B,I,I,B,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0,
11234f210d8SBruce Evans   B,I,B,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0,
11334f210d8SBruce Evans   B,B,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,
11434f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,
11534f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,
11634f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,
11734f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,
11834f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,
11934f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,0,B,B,B,B,0,0,0,
12034f210d8SBruce Evans };
12134f210d8SBruce Evans static byte SmallAndMask[] = {
12234f210d8SBruce Evans   X,X,0,0,0,0,0,0,0,0,
12334f210d8SBruce Evans   X,X,X,0,0,0,0,0,0,0,
12434f210d8SBruce Evans   X,X,X,X,0,0,0,0,0,0,
12534f210d8SBruce Evans   X,X,X,X,X,0,0,0,0,0,
12634f210d8SBruce Evans   X,X,X,X,X,X,0,0,0,0,
12734f210d8SBruce Evans   X,X,X,X,X,X,X,0,0,0,
12834f210d8SBruce Evans   X,X,X,X,X,X,X,X,0,0,
12934f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,0,
13034f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,
13134f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,
13234f210d8SBruce Evans   X,X,X,X,X,X,X,0,0,0,
13334f210d8SBruce Evans   X,X,X,0,X,X,X,X,0,0,
13434f210d8SBruce Evans   X,X,0,0,X,X,X,X,0,0,
13534f210d8SBruce Evans   0,0,0,0,0,X,X,X,X,0,
13634f210d8SBruce Evans   0,0,0,0,0,X,X,X,X,0,
13734f210d8SBruce Evans   0,0,0,0,0,0,X,X,0,0,
13834f210d8SBruce Evans };
13934f210d8SBruce Evans static byte SmallOrMask[] = {
14034f210d8SBruce Evans   B,B,0,0,0,0,0,0,0,0,
14134f210d8SBruce Evans   B,I,B,0,0,0,0,0,0,0,
14234f210d8SBruce Evans   B,I,I,B,0,0,0,0,0,0,
14334f210d8SBruce Evans   B,I,I,I,B,0,0,0,0,0,
14434f210d8SBruce Evans   B,I,I,I,I,B,0,0,0,0,
14534f210d8SBruce Evans   B,I,I,I,I,I,B,0,0,0,
14634f210d8SBruce Evans   B,I,I,I,I,I,I,B,0,0,
14734f210d8SBruce Evans   B,I,I,I,I,I,I,I,B,0,
14834f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,B,
14934f210d8SBruce Evans   B,I,I,I,I,I,B,B,B,B,
15034f210d8SBruce Evans   B,I,I,B,I,I,B,0,0,0,
15134f210d8SBruce Evans   B,I,B,0,B,I,I,B,0,0,
15234f210d8SBruce Evans   B,B,0,0,B,I,I,B,0,0,
15334f210d8SBruce Evans   0,0,0,0,0,B,I,I,B,0,
15434f210d8SBruce Evans   0,0,0,0,0,B,I,I,B,0,
15534f210d8SBruce 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
16034f210d8SBruce Evans static VGLBitmap VGLMouseLargeAndMask =
16134f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE,
16234f210d8SBruce Evans                         LargeAndMask);
16334f210d8SBruce Evans static VGLBitmap VGLMouseLargeOrMask =
16434f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE,
16534f210d8SBruce Evans                         LargeOrMask);
16634f210d8SBruce Evans static VGLBitmap VGLMouseSmallAndMask =
16734f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE,
16834f210d8SBruce Evans                         SmallAndMask);
16934f210d8SBruce Evans static VGLBitmap VGLMouseSmallOrMask =
17034f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE,
17134f210d8SBruce 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;
19634f210d8SBruce Evans       __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos,
19734f210d8SBruce Evans                       VGLDisplay, VGLMouseXpos, VGLMouseYpos,
19834f210d8SBruce 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;
20434f210d8SBruce Evans       __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos,
20534f210d8SBruce Evans                       VGLDisplay, VGLMouseXpos, VGLMouseYpos,
20634f210d8SBruce 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 {
27634f210d8SBruce Evans   if (VGLDisplay->VXsize > 800)
27734f210d8SBruce Evans     VGLMouseSetImage(&VGLMouseLargeAndMask, &VGLMouseLargeOrMask);
27834f210d8SBruce Evans   else
27934f210d8SBruce 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;
28634f210d8SBruce Evans   VGLBitmap *ormask;
287*035dd78dSJohn Baldwin   int 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     border = 0x0f;
293a93ca07aSBruce Evans     interior = 0x04;
294aa1ce985SBruce Evans     break;
295aa1ce985SBruce Evans   case V_INFO_MM_VGAX:
296a93ca07aSBruce Evans     border = 0x3f;
297a93ca07aSBruce Evans     interior = 0x24;
298aa1ce985SBruce Evans     break;
299aa1ce985SBruce Evans   default:
300a93ca07aSBruce Evans     border = BORDER;
301a93ca07aSBruce Evans     interior = INTERIOR;
302aa1ce985SBruce Evans     break;
303aa1ce985SBruce Evans   }
304a93ca07aSBruce Evans   if (VGLModeInfo.vi_mode == M_BG640x480)
305a93ca07aSBruce Evans     border = 0;		/* XXX (palette makes 0x04 look like 0x0f) */
306a93ca07aSBruce Evans   if (getenv("VGLMOUSEBORDERCOLOR") != NULL)
307a93ca07aSBruce Evans     border = strtoul(getenv("VGLMOUSEBORDERCOLOR"), NULL, 0);
308a93ca07aSBruce Evans   if (getenv("VGLMOUSEINTERIORCOLOR") != NULL)
309a93ca07aSBruce Evans     interior = strtoul(getenv("VGLMOUSEINTERIORCOLOR"), NULL, 0);
31034f210d8SBruce Evans   ormask = &VGLMouseLargeOrMask;
31134f210d8SBruce Evans   for (i = 0; i < ormask->VXsize * ormask->VYsize; i++)
31234f210d8SBruce Evans     ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ?  border :
31334f210d8SBruce Evans                         ormask->Bitmap[i] == INTERIOR ? interior : 0;
31434f210d8SBruce Evans   ormask = &VGLMouseSmallOrMask;
31534f210d8SBruce Evans   for (i = 0; i < ormask->VXsize * ormask->VYsize; i++)
31634f210d8SBruce Evans     ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ?  border :
31734f210d8SBruce Evans                         ormask->Bitmap[i] == INTERIOR ? interior : 0;
3189a57b7d2SSøren Schmidt   VGLMouseSetStdImage();
3199a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_MODE;
3209a57b7d2SSøren Schmidt   mouseinfo.u.mode.signal = SIGUSR2;
3219a57b7d2SSøren Schmidt   if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
3229a57b7d2SSøren Schmidt     return error;
3239a57b7d2SSøren Schmidt   signal(SIGUSR2, VGLMouseAction);
3249a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_GETINFO;
3259a57b7d2SSøren Schmidt   ioctl(0, CONS_MOUSECTL, &mouseinfo);
3269a57b7d2SSøren Schmidt   VGLMouseXpos = mouseinfo.u.data.x;
3279a57b7d2SSøren Schmidt   VGLMouseYpos = mouseinfo.u.data.y;
3289a57b7d2SSøren Schmidt   VGLMouseButtons = mouseinfo.u.data.buttons;
3299a57b7d2SSøren Schmidt   VGLMouseMode(mode);
3309a57b7d2SSøren Schmidt   return 0;
3319a57b7d2SSøren Schmidt }
3329a57b7d2SSøren Schmidt 
333e848f3d1SBruce Evans void
334e848f3d1SBruce Evans VGLMouseRestore(void)
335e848f3d1SBruce Evans {
336e848f3d1SBruce Evans   struct mouse_info mouseinfo;
337e848f3d1SBruce Evans 
338e848f3d1SBruce Evans   INTOFF();
339e848f3d1SBruce Evans   mouseinfo.operation = MOUSE_GETINFO;
340e848f3d1SBruce Evans   if (ioctl(0, CONS_MOUSECTL, &mouseinfo) == 0) {
341e848f3d1SBruce Evans     mouseinfo.operation = MOUSE_MOVEABS;
342e848f3d1SBruce Evans     mouseinfo.u.data.x = VGLMouseXpos;
343e848f3d1SBruce Evans     mouseinfo.u.data.y = VGLMouseYpos;
344e848f3d1SBruce Evans     ioctl(0, CONS_MOUSECTL, &mouseinfo);
345e848f3d1SBruce Evans   }
346e848f3d1SBruce Evans   INTON();
347e848f3d1SBruce Evans }
348e848f3d1SBruce Evans 
3499a57b7d2SSøren Schmidt int
3509a57b7d2SSøren Schmidt VGLMouseStatus(int *x, int *y, char *buttons)
3519a57b7d2SSøren Schmidt {
3520410dc5fSBruce Evans   INTOFF();
3539a57b7d2SSøren Schmidt   *x =  VGLMouseXpos;
3549a57b7d2SSøren Schmidt   *y =  VGLMouseYpos;
3559a57b7d2SSøren Schmidt   *buttons =  VGLMouseButtons;
3560410dc5fSBruce Evans   INTON();
3579a57b7d2SSøren Schmidt   return VGLMouseShown;
3589a57b7d2SSøren Schmidt }
3599a57b7d2SSøren Schmidt 
360c7432537SBruce Evans void
361c7432537SBruce Evans VGLMouseFreeze(void)
3629a57b7d2SSøren Schmidt {
3630410dc5fSBruce Evans   INTOFF();
364c7432537SBruce Evans }
365c7432537SBruce Evans 
366c7432537SBruce Evans int
367c7432537SBruce Evans VGLMouseFreezeXY(int x, int y)
368c7432537SBruce Evans {
369c7432537SBruce Evans   INTOFF();
370c7432537SBruce Evans   if (VGLMouseShown != VGL_MOUSESHOW)
371c7432537SBruce Evans     return 0;
37234f210d8SBruce Evans   if (x >= VGLMouseXpos && x < VGLMouseXpos + VGLMouseAndMask->VXsize &&
37334f210d8SBruce Evans       y >= VGLMouseYpos && y < VGLMouseYpos + VGLMouseAndMask->VYsize &&
37434f210d8SBruce Evans       VGLMouseAndMask->Bitmap[(y-VGLMouseYpos)*VGLMouseAndMask->VXsize+
37534f210d8SBruce Evans                               (x-VGLMouseXpos)])
376c7432537SBruce Evans     return 1;
377c7432537SBruce Evans   return 0;
378c7432537SBruce Evans }
379c7432537SBruce Evans 
380c7432537SBruce Evans int
381c7432537SBruce Evans VGLMouseOverlap(int x, int y, int width, int hight)
382c7432537SBruce Evans {
3839a57b7d2SSøren Schmidt   int overlap;
3849a57b7d2SSøren Schmidt 
385c7432537SBruce Evans   if (VGLMouseShown != VGL_MOUSESHOW)
386c7432537SBruce Evans     return 0;
3879a57b7d2SSøren Schmidt   if (x > VGLMouseXpos)
38834f210d8SBruce Evans     overlap = (VGLMouseXpos + VGLMouseAndMask->VXsize) - x;
3899a57b7d2SSøren Schmidt   else
3909a57b7d2SSøren Schmidt     overlap = (x + width) - VGLMouseXpos;
391c7432537SBruce Evans   if (overlap <= 0)
392c7432537SBruce Evans     return 0;
3939a57b7d2SSøren Schmidt   if (y > VGLMouseYpos)
39434f210d8SBruce Evans     overlap = (VGLMouseYpos + VGLMouseAndMask->VYsize) - y;
3959a57b7d2SSøren Schmidt   else
3969a57b7d2SSøren Schmidt     overlap = (y + hight) - VGLMouseYpos;
397c7432537SBruce Evans   return overlap > 0;
3989a57b7d2SSøren Schmidt }
3999a57b7d2SSøren Schmidt 
4009a57b7d2SSøren Schmidt void
401a07067eaSBruce Evans VGLMouseMerge(int x, int y, int width, byte *line)
402a07067eaSBruce Evans {
403a07067eaSBruce Evans   int pos, x1, xend, xstart;
404a07067eaSBruce Evans 
405a07067eaSBruce Evans   xstart = x;
406a07067eaSBruce Evans   if (xstart < VGLMouseXpos)
407a07067eaSBruce Evans     xstart = VGLMouseXpos;
408a07067eaSBruce Evans   xend = x + width;
40934f210d8SBruce Evans   if (xend > VGLMouseXpos + VGLMouseAndMask->VXsize)
41034f210d8SBruce Evans     xend = VGLMouseXpos + VGLMouseAndMask->VXsize;
411a07067eaSBruce Evans   for (x1 = xstart; x1 < xend; x1++) {
41234f210d8SBruce Evans     pos = (y - VGLMouseYpos) * VGLMouseAndMask->VXsize + x1 - VGLMouseXpos;
413a07067eaSBruce Evans     if (VGLMouseAndMask->Bitmap[pos])
414a07067eaSBruce Evans       bcopy(&VGLMouseOrMask->Bitmap[pos * VGLDisplay->PixelBytes],
415a07067eaSBruce Evans             &line[(x1 - x) * VGLDisplay->PixelBytes], VGLDisplay->PixelBytes);
416a07067eaSBruce Evans   }
417a07067eaSBruce Evans }
418a07067eaSBruce Evans 
419a07067eaSBruce Evans void
4209a57b7d2SSøren Schmidt VGLMouseUnFreeze()
4219a57b7d2SSøren Schmidt {
4220410dc5fSBruce Evans   INTON();
4239a57b7d2SSøren Schmidt }
424