xref: /freebsd/lib/libvgl/mouse.c (revision 1d386b48a555f61cb7325543adbbb5c3f3407a66)
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>
329a57b7d2SSøren Schmidt #include <stdio.h>
339a57b7d2SSøren Schmidt #include <sys/types.h>
349a57b7d2SSøren Schmidt #include <sys/ioctl.h>
359a57b7d2SSøren Schmidt #include <sys/signal.h>
3600d25f51SPoul-Henning Kamp #include <sys/consio.h>
3700d25f51SPoul-Henning Kamp #include <sys/fbio.h>
389a57b7d2SSøren Schmidt #include "vgl.h"
399a57b7d2SSøren Schmidt 
40c0ce6f7dSBruce Evans static void VGLMouseAction(int dummy);
41c0ce6f7dSBruce Evans 
42a93ca07aSBruce Evans #define BORDER	0xff	/* default border -- light white in rgb 3:3:2 */
43a93ca07aSBruce Evans #define INTERIOR 0xa0	/* default interior -- red in rgb 3:3:2 */
4434f210d8SBruce Evans #define LARGE_MOUSE_IMG_XSIZE	19
4534f210d8SBruce Evans #define LARGE_MOUSE_IMG_YSIZE	32
4634f210d8SBruce Evans #define SMALL_MOUSE_IMG_XSIZE	10
4734f210d8SBruce Evans #define SMALL_MOUSE_IMG_YSIZE	16
48a93ca07aSBruce Evans #define X	0xff	/* any nonzero in And mask means part of cursor */
49a93ca07aSBruce Evans #define B	BORDER
50a93ca07aSBruce Evans #define I	INTERIOR
5134f210d8SBruce Evans static byte LargeAndMask[] = {
5234f210d8SBruce Evans   X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5334f210d8SBruce Evans   X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5434f210d8SBruce Evans   X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5534f210d8SBruce Evans   X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5634f210d8SBruce Evans   X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
5734f210d8SBruce Evans   X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
5834f210d8SBruce Evans   X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
5934f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
6034f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
6134f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
6234f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
6334f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,
6434f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,
6534f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,
6634f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,
6734f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,0,
6834f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,0,
6934f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
7034f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
7134f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
7234f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
7334f210d8SBruce Evans   X,X,X,X,X,X,0,X,X,X,X,X,X,0,0,0,0,0,0,
7434f210d8SBruce Evans   X,X,X,X,X,0,0,X,X,X,X,X,X,0,0,0,0,0,0,
7534f210d8SBruce Evans   X,X,X,X,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0,
7634f210d8SBruce Evans   X,X,X,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,0,
7734f210d8SBruce Evans   X,X,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,
7834f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,0,
7934f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,
8034f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,0,
8134f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,
8234f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,X,X,0,0,
8334f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,0,X,X,X,X,0,0,0,
849a57b7d2SSøren Schmidt };
8534f210d8SBruce Evans static byte LargeOrMask[] = {
8634f210d8SBruce Evans   B,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8734f210d8SBruce Evans   B,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8834f210d8SBruce Evans   B,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
8934f210d8SBruce Evans   B,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
9034f210d8SBruce Evans   B,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0,
9134f210d8SBruce Evans   B,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0,
9234f210d8SBruce Evans   B,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0,
9334f210d8SBruce Evans   B,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0,
9434f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0,
9534f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0,
9634f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,
9734f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,
9834f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,
9934f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,
10034f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,0,
10134f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,0,
10234f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,0,
10334f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,B,
10434f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,B,B,B,B,B,B,B,B,
10534f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0,
10634f210d8SBruce Evans   B,I,I,I,I,I,B,I,I,I,I,B,0,0,0,0,0,0,0,
10734f210d8SBruce Evans   B,I,I,I,I,B,0,B,I,I,I,I,B,0,0,0,0,0,0,
10834f210d8SBruce Evans   B,I,I,I,B,0,0,B,I,I,I,I,B,0,0,0,0,0,0,
10934f210d8SBruce Evans   B,I,I,B,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0,
11034f210d8SBruce Evans   B,I,B,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,0,
11134f210d8SBruce Evans   B,B,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,
11234f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,0,
11334f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,
11434f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,0,
11534f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,
11634f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,B,I,I,I,I,B,0,0,
11734f210d8SBruce Evans   0,0,0,0,0,0,0,0,0,0,0,0,B,B,B,B,0,0,0,
11834f210d8SBruce Evans };
11934f210d8SBruce Evans static byte SmallAndMask[] = {
12034f210d8SBruce Evans   X,X,0,0,0,0,0,0,0,0,
12134f210d8SBruce Evans   X,X,X,0,0,0,0,0,0,0,
12234f210d8SBruce Evans   X,X,X,X,0,0,0,0,0,0,
12334f210d8SBruce Evans   X,X,X,X,X,0,0,0,0,0,
12434f210d8SBruce Evans   X,X,X,X,X,X,0,0,0,0,
12534f210d8SBruce Evans   X,X,X,X,X,X,X,0,0,0,
12634f210d8SBruce Evans   X,X,X,X,X,X,X,X,0,0,
12734f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,0,
12834f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,
12934f210d8SBruce Evans   X,X,X,X,X,X,X,X,X,X,
13034f210d8SBruce Evans   X,X,X,X,X,X,X,0,0,0,
13134f210d8SBruce Evans   X,X,X,0,X,X,X,X,0,0,
13234f210d8SBruce Evans   X,X,0,0,X,X,X,X,0,0,
13334f210d8SBruce Evans   0,0,0,0,0,X,X,X,X,0,
13434f210d8SBruce Evans   0,0,0,0,0,X,X,X,X,0,
13534f210d8SBruce Evans   0,0,0,0,0,0,X,X,0,0,
13634f210d8SBruce Evans };
13734f210d8SBruce Evans static byte SmallOrMask[] = {
13834f210d8SBruce Evans   B,B,0,0,0,0,0,0,0,0,
13934f210d8SBruce Evans   B,I,B,0,0,0,0,0,0,0,
14034f210d8SBruce Evans   B,I,I,B,0,0,0,0,0,0,
14134f210d8SBruce Evans   B,I,I,I,B,0,0,0,0,0,
14234f210d8SBruce Evans   B,I,I,I,I,B,0,0,0,0,
14334f210d8SBruce Evans   B,I,I,I,I,I,B,0,0,0,
14434f210d8SBruce Evans   B,I,I,I,I,I,I,B,0,0,
14534f210d8SBruce Evans   B,I,I,I,I,I,I,I,B,0,
14634f210d8SBruce Evans   B,I,I,I,I,I,I,I,I,B,
14734f210d8SBruce Evans   B,I,I,I,I,I,B,B,B,B,
14834f210d8SBruce Evans   B,I,I,B,I,I,B,0,0,0,
14934f210d8SBruce Evans   B,I,B,0,B,I,I,B,0,0,
15034f210d8SBruce Evans   B,B,0,0,B,I,I,B,0,0,
15134f210d8SBruce Evans   0,0,0,0,0,B,I,I,B,0,
15234f210d8SBruce Evans   0,0,0,0,0,B,I,I,B,0,
15334f210d8SBruce Evans   0,0,0,0,0,0,B,B,0,0,
1549a57b7d2SSøren Schmidt };
1559a57b7d2SSøren Schmidt #undef X
156a93ca07aSBruce Evans #undef B
157a93ca07aSBruce Evans #undef I
15834f210d8SBruce Evans static VGLBitmap VGLMouseLargeAndMask =
15934f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE,
16034f210d8SBruce Evans                         LargeAndMask);
16134f210d8SBruce Evans static VGLBitmap VGLMouseLargeOrMask =
16234f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, LARGE_MOUSE_IMG_XSIZE, LARGE_MOUSE_IMG_YSIZE,
16334f210d8SBruce Evans                         LargeOrMask);
16434f210d8SBruce Evans static VGLBitmap VGLMouseSmallAndMask =
16534f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE,
16634f210d8SBruce Evans                         SmallAndMask);
16734f210d8SBruce Evans static VGLBitmap VGLMouseSmallOrMask =
16834f210d8SBruce Evans   VGLBITMAP_INITIALIZER(MEMBUF, SMALL_MOUSE_IMG_XSIZE, SMALL_MOUSE_IMG_YSIZE,
16934f210d8SBruce Evans                         SmallOrMask);
1709a57b7d2SSøren Schmidt static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
171c7432537SBruce Evans static int VGLMouseShown = VGL_MOUSEHIDE;
1729a57b7d2SSøren Schmidt static int VGLMouseXpos = 0;
1739a57b7d2SSøren Schmidt static int VGLMouseYpos = 0;
1749a57b7d2SSøren Schmidt static int VGLMouseButtons = 0;
1750410dc5fSBruce Evans static volatile sig_atomic_t VGLMintpending;
1760410dc5fSBruce Evans static volatile sig_atomic_t VGLMsuppressint;
1770410dc5fSBruce Evans 
1780410dc5fSBruce Evans #define	INTOFF()	(VGLMsuppressint++)
1790410dc5fSBruce Evans #define	INTON()		do { 						\
1800410dc5fSBruce Evans 				if (--VGLMsuppressint == 0 && VGLMintpending) \
1810410dc5fSBruce Evans 					VGLMouseAction(0);		\
1820410dc5fSBruce Evans 			} while (0)
1839a57b7d2SSøren Schmidt 
184c0ce6f7dSBruce Evans int
__VGLMouseMode(int mode)185c0ce6f7dSBruce Evans __VGLMouseMode(int mode)
1869a57b7d2SSøren Schmidt {
187c0ce6f7dSBruce Evans   int oldmode;
1889a57b7d2SSøren Schmidt 
1890410dc5fSBruce Evans   INTOFF();
190c0ce6f7dSBruce Evans   oldmode = VGLMouseShown;
191c0ce6f7dSBruce Evans   if (mode == VGL_MOUSESHOW) {
192c0ce6f7dSBruce Evans     if (VGLMouseShown == VGL_MOUSEHIDE) {
193c0ce6f7dSBruce Evans       VGLMouseShown = VGL_MOUSESHOW;
19434f210d8SBruce Evans       __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos,
19534f210d8SBruce Evans                       VGLDisplay, VGLMouseXpos, VGLMouseYpos,
19634f210d8SBruce Evans                       VGLMouseAndMask->VXsize, -VGLMouseAndMask->VYsize);
1979a57b7d2SSøren Schmidt     }
1989a57b7d2SSøren Schmidt   }
199c0ce6f7dSBruce Evans   else {
200c0ce6f7dSBruce Evans     if (VGLMouseShown == VGL_MOUSESHOW) {
201c0ce6f7dSBruce Evans       VGLMouseShown = VGL_MOUSEHIDE;
20234f210d8SBruce Evans       __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos,
20334f210d8SBruce Evans                       VGLDisplay, VGLMouseXpos, VGLMouseYpos,
20434f210d8SBruce Evans                       VGLMouseAndMask->VXsize, VGLMouseAndMask->VYsize);
205c0ce6f7dSBruce Evans     }
206c0ce6f7dSBruce Evans   }
207c0ce6f7dSBruce Evans   INTON();
208c0ce6f7dSBruce Evans   return oldmode;
209c0ce6f7dSBruce Evans }
2109a57b7d2SSøren Schmidt 
2119a57b7d2SSøren Schmidt void
VGLMouseMode(int mode)2129a57b7d2SSøren Schmidt VGLMouseMode(int mode)
2139a57b7d2SSøren Schmidt {
214c0ce6f7dSBruce Evans   __VGLMouseMode(mode);
2159a57b7d2SSøren Schmidt }
2169a57b7d2SSøren Schmidt 
217c0ce6f7dSBruce Evans static void
VGLMouseAction(int dummy)2189a57b7d2SSøren Schmidt VGLMouseAction(int dummy)
2199a57b7d2SSøren Schmidt {
2209a57b7d2SSøren Schmidt   struct mouse_info mouseinfo;
221c0ce6f7dSBruce Evans   int mousemode;
2229a57b7d2SSøren Schmidt 
2230410dc5fSBruce Evans   if (VGLMsuppressint) {
2240410dc5fSBruce Evans     VGLMintpending = 1;
2259a57b7d2SSøren Schmidt     return;
2269a57b7d2SSøren Schmidt   }
2270410dc5fSBruce Evans again:
2280410dc5fSBruce Evans   INTOFF();
2290410dc5fSBruce Evans   VGLMintpending = 0;
2309a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_GETINFO;
2319a57b7d2SSøren Schmidt   ioctl(0, CONS_MOUSECTL, &mouseinfo);
232c0ce6f7dSBruce Evans   if (VGLMouseXpos != mouseinfo.u.data.x ||
233c0ce6f7dSBruce Evans       VGLMouseYpos != mouseinfo.u.data.y) {
234c0ce6f7dSBruce Evans     mousemode = __VGLMouseMode(VGL_MOUSEHIDE);
2359a57b7d2SSøren Schmidt     VGLMouseXpos = mouseinfo.u.data.x;
2369a57b7d2SSøren Schmidt     VGLMouseYpos = mouseinfo.u.data.y;
237c0ce6f7dSBruce Evans     __VGLMouseMode(mousemode);
238c0ce6f7dSBruce Evans   }
2399a57b7d2SSøren Schmidt   VGLMouseButtons = mouseinfo.u.data.buttons;
2400410dc5fSBruce Evans 
2410410dc5fSBruce Evans   /*
2420410dc5fSBruce Evans    * Loop to handle any new (suppressed) signals.  This is INTON() without
2430410dc5fSBruce Evans    * recursion.  !SA_RESTART prevents recursion in signal handling.  So the
2440410dc5fSBruce Evans    * maximum recursion is 2 levels.
2450410dc5fSBruce Evans    */
2460410dc5fSBruce Evans   VGLMsuppressint = 0;
2470410dc5fSBruce Evans   if (VGLMintpending)
2480410dc5fSBruce Evans     goto again;
2499a57b7d2SSøren Schmidt }
2509a57b7d2SSøren Schmidt 
2519a57b7d2SSøren Schmidt void
VGLMouseSetImage(VGLBitmap * AndMask,VGLBitmap * OrMask)2529a57b7d2SSøren Schmidt VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
2539a57b7d2SSøren Schmidt {
254c0ce6f7dSBruce Evans   int mousemode;
255c0ce6f7dSBruce Evans 
256c0ce6f7dSBruce Evans   mousemode = __VGLMouseMode(VGL_MOUSEHIDE);
257a93ca07aSBruce Evans 
2589a57b7d2SSøren Schmidt   VGLMouseAndMask = AndMask;
259a93ca07aSBruce Evans 
260a93ca07aSBruce Evans   if (VGLMouseOrMask != NULL) {
261a93ca07aSBruce Evans     free(VGLMouseOrMask->Bitmap);
262a93ca07aSBruce Evans     free(VGLMouseOrMask);
263a93ca07aSBruce Evans   }
264a93ca07aSBruce Evans   VGLMouseOrMask = VGLBitmapCreate(MEMBUF, OrMask->VXsize, OrMask->VYsize, 0);
265a93ca07aSBruce Evans   VGLBitmapAllocateBits(VGLMouseOrMask);
266a93ca07aSBruce Evans   VGLBitmapCvt(OrMask, VGLMouseOrMask);
267a93ca07aSBruce Evans 
268c0ce6f7dSBruce Evans   __VGLMouseMode(mousemode);
2699a57b7d2SSøren Schmidt }
2709a57b7d2SSøren Schmidt 
2719a57b7d2SSøren Schmidt void
VGLMouseSetStdImage()2729a57b7d2SSøren Schmidt VGLMouseSetStdImage()
2739a57b7d2SSøren Schmidt {
27434f210d8SBruce Evans   if (VGLDisplay->VXsize > 800)
27534f210d8SBruce Evans     VGLMouseSetImage(&VGLMouseLargeAndMask, &VGLMouseLargeOrMask);
27634f210d8SBruce Evans   else
27734f210d8SBruce Evans     VGLMouseSetImage(&VGLMouseSmallAndMask, &VGLMouseSmallOrMask);
2789a57b7d2SSøren Schmidt }
2799a57b7d2SSøren Schmidt 
2809a57b7d2SSøren Schmidt int
VGLMouseInit(int mode)2819a57b7d2SSøren Schmidt VGLMouseInit(int mode)
2829a57b7d2SSøren Schmidt {
2839a57b7d2SSøren Schmidt   struct mouse_info mouseinfo;
28434f210d8SBruce Evans   VGLBitmap *ormask;
285*035dd78dSJohn Baldwin   int border, error, i, interior;
2869a57b7d2SSøren Schmidt 
287aa1ce985SBruce Evans   switch (VGLModeInfo.vi_mem_model) {
288aa1ce985SBruce Evans   case V_INFO_MM_PACKED:
289aa1ce985SBruce Evans   case V_INFO_MM_PLANAR:
290a93ca07aSBruce Evans     border = 0x0f;
291a93ca07aSBruce Evans     interior = 0x04;
292aa1ce985SBruce Evans     break;
293aa1ce985SBruce Evans   case V_INFO_MM_VGAX:
294a93ca07aSBruce Evans     border = 0x3f;
295a93ca07aSBruce Evans     interior = 0x24;
296aa1ce985SBruce Evans     break;
297aa1ce985SBruce Evans   default:
298a93ca07aSBruce Evans     border = BORDER;
299a93ca07aSBruce Evans     interior = INTERIOR;
300aa1ce985SBruce Evans     break;
301aa1ce985SBruce Evans   }
302a93ca07aSBruce Evans   if (VGLModeInfo.vi_mode == M_BG640x480)
303a93ca07aSBruce Evans     border = 0;		/* XXX (palette makes 0x04 look like 0x0f) */
304a93ca07aSBruce Evans   if (getenv("VGLMOUSEBORDERCOLOR") != NULL)
305a93ca07aSBruce Evans     border = strtoul(getenv("VGLMOUSEBORDERCOLOR"), NULL, 0);
306a93ca07aSBruce Evans   if (getenv("VGLMOUSEINTERIORCOLOR") != NULL)
307a93ca07aSBruce Evans     interior = strtoul(getenv("VGLMOUSEINTERIORCOLOR"), NULL, 0);
30834f210d8SBruce Evans   ormask = &VGLMouseLargeOrMask;
30934f210d8SBruce Evans   for (i = 0; i < ormask->VXsize * ormask->VYsize; i++)
31034f210d8SBruce Evans     ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ?  border :
31134f210d8SBruce Evans                         ormask->Bitmap[i] == INTERIOR ? interior : 0;
31234f210d8SBruce Evans   ormask = &VGLMouseSmallOrMask;
31334f210d8SBruce Evans   for (i = 0; i < ormask->VXsize * ormask->VYsize; i++)
31434f210d8SBruce Evans     ormask->Bitmap[i] = ormask->Bitmap[i] == BORDER ?  border :
31534f210d8SBruce Evans                         ormask->Bitmap[i] == INTERIOR ? interior : 0;
3169a57b7d2SSøren Schmidt   VGLMouseSetStdImage();
3179a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_MODE;
3189a57b7d2SSøren Schmidt   mouseinfo.u.mode.signal = SIGUSR2;
3199a57b7d2SSøren Schmidt   if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
3209a57b7d2SSøren Schmidt     return error;
3219a57b7d2SSøren Schmidt   signal(SIGUSR2, VGLMouseAction);
3229a57b7d2SSøren Schmidt   mouseinfo.operation = MOUSE_GETINFO;
3239a57b7d2SSøren Schmidt   ioctl(0, CONS_MOUSECTL, &mouseinfo);
3249a57b7d2SSøren Schmidt   VGLMouseXpos = mouseinfo.u.data.x;
3259a57b7d2SSøren Schmidt   VGLMouseYpos = mouseinfo.u.data.y;
3269a57b7d2SSøren Schmidt   VGLMouseButtons = mouseinfo.u.data.buttons;
3279a57b7d2SSøren Schmidt   VGLMouseMode(mode);
3289a57b7d2SSøren Schmidt   return 0;
3299a57b7d2SSøren Schmidt }
3309a57b7d2SSøren Schmidt 
331e848f3d1SBruce Evans void
VGLMouseRestore(void)332e848f3d1SBruce Evans VGLMouseRestore(void)
333e848f3d1SBruce Evans {
334e848f3d1SBruce Evans   struct mouse_info mouseinfo;
335e848f3d1SBruce Evans 
336e848f3d1SBruce Evans   INTOFF();
337e848f3d1SBruce Evans   mouseinfo.operation = MOUSE_GETINFO;
338e848f3d1SBruce Evans   if (ioctl(0, CONS_MOUSECTL, &mouseinfo) == 0) {
339e848f3d1SBruce Evans     mouseinfo.operation = MOUSE_MOVEABS;
340e848f3d1SBruce Evans     mouseinfo.u.data.x = VGLMouseXpos;
341e848f3d1SBruce Evans     mouseinfo.u.data.y = VGLMouseYpos;
342e848f3d1SBruce Evans     ioctl(0, CONS_MOUSECTL, &mouseinfo);
343e848f3d1SBruce Evans   }
344e848f3d1SBruce Evans   INTON();
345e848f3d1SBruce Evans }
346e848f3d1SBruce Evans 
3479a57b7d2SSøren Schmidt int
VGLMouseStatus(int * x,int * y,char * buttons)3489a57b7d2SSøren Schmidt VGLMouseStatus(int *x, int *y, char *buttons)
3499a57b7d2SSøren Schmidt {
3500410dc5fSBruce Evans   INTOFF();
3519a57b7d2SSøren Schmidt   *x =  VGLMouseXpos;
3529a57b7d2SSøren Schmidt   *y =  VGLMouseYpos;
3539a57b7d2SSøren Schmidt   *buttons =  VGLMouseButtons;
3540410dc5fSBruce Evans   INTON();
3559a57b7d2SSøren Schmidt   return VGLMouseShown;
3569a57b7d2SSøren Schmidt }
3579a57b7d2SSøren Schmidt 
358c7432537SBruce Evans void
VGLMouseFreeze(void)359c7432537SBruce Evans VGLMouseFreeze(void)
3609a57b7d2SSøren Schmidt {
3610410dc5fSBruce Evans   INTOFF();
362c7432537SBruce Evans }
363c7432537SBruce Evans 
364c7432537SBruce Evans int
VGLMouseFreezeXY(int x,int y)365c7432537SBruce Evans VGLMouseFreezeXY(int x, int y)
366c7432537SBruce Evans {
367c7432537SBruce Evans   INTOFF();
368c7432537SBruce Evans   if (VGLMouseShown != VGL_MOUSESHOW)
369c7432537SBruce Evans     return 0;
37034f210d8SBruce Evans   if (x >= VGLMouseXpos && x < VGLMouseXpos + VGLMouseAndMask->VXsize &&
37134f210d8SBruce Evans       y >= VGLMouseYpos && y < VGLMouseYpos + VGLMouseAndMask->VYsize &&
37234f210d8SBruce Evans       VGLMouseAndMask->Bitmap[(y-VGLMouseYpos)*VGLMouseAndMask->VXsize+
37334f210d8SBruce Evans                               (x-VGLMouseXpos)])
374c7432537SBruce Evans     return 1;
375c7432537SBruce Evans   return 0;
376c7432537SBruce Evans }
377c7432537SBruce Evans 
378c7432537SBruce Evans int
VGLMouseOverlap(int x,int y,int width,int hight)379c7432537SBruce Evans VGLMouseOverlap(int x, int y, int width, int hight)
380c7432537SBruce Evans {
3819a57b7d2SSøren Schmidt   int overlap;
3829a57b7d2SSøren Schmidt 
383c7432537SBruce Evans   if (VGLMouseShown != VGL_MOUSESHOW)
384c7432537SBruce Evans     return 0;
3859a57b7d2SSøren Schmidt   if (x > VGLMouseXpos)
38634f210d8SBruce Evans     overlap = (VGLMouseXpos + VGLMouseAndMask->VXsize) - x;
3879a57b7d2SSøren Schmidt   else
3889a57b7d2SSøren Schmidt     overlap = (x + width) - VGLMouseXpos;
389c7432537SBruce Evans   if (overlap <= 0)
390c7432537SBruce Evans     return 0;
3919a57b7d2SSøren Schmidt   if (y > VGLMouseYpos)
39234f210d8SBruce Evans     overlap = (VGLMouseYpos + VGLMouseAndMask->VYsize) - y;
3939a57b7d2SSøren Schmidt   else
3949a57b7d2SSøren Schmidt     overlap = (y + hight) - VGLMouseYpos;
395c7432537SBruce Evans   return overlap > 0;
3969a57b7d2SSøren Schmidt }
3979a57b7d2SSøren Schmidt 
3989a57b7d2SSøren Schmidt void
VGLMouseMerge(int x,int y,int width,byte * line)399a07067eaSBruce Evans VGLMouseMerge(int x, int y, int width, byte *line)
400a07067eaSBruce Evans {
401a07067eaSBruce Evans   int pos, x1, xend, xstart;
402a07067eaSBruce Evans 
403a07067eaSBruce Evans   xstart = x;
404a07067eaSBruce Evans   if (xstart < VGLMouseXpos)
405a07067eaSBruce Evans     xstart = VGLMouseXpos;
406a07067eaSBruce Evans   xend = x + width;
40734f210d8SBruce Evans   if (xend > VGLMouseXpos + VGLMouseAndMask->VXsize)
40834f210d8SBruce Evans     xend = VGLMouseXpos + VGLMouseAndMask->VXsize;
409a07067eaSBruce Evans   for (x1 = xstart; x1 < xend; x1++) {
41034f210d8SBruce Evans     pos = (y - VGLMouseYpos) * VGLMouseAndMask->VXsize + x1 - VGLMouseXpos;
411a07067eaSBruce Evans     if (VGLMouseAndMask->Bitmap[pos])
412a07067eaSBruce Evans       bcopy(&VGLMouseOrMask->Bitmap[pos * VGLDisplay->PixelBytes],
413a07067eaSBruce Evans             &line[(x1 - x) * VGLDisplay->PixelBytes], VGLDisplay->PixelBytes);
414a07067eaSBruce Evans   }
415a07067eaSBruce Evans }
416a07067eaSBruce Evans 
417a07067eaSBruce Evans void
VGLMouseUnFreeze()4189a57b7d2SSøren Schmidt VGLMouseUnFreeze()
4199a57b7d2SSøren Schmidt {
4200410dc5fSBruce Evans   INTON();
4219a57b7d2SSøren Schmidt }
422