xref: /freebsd/lib/libvgl/mouse.c (revision 380a989b3223d455375b4fae70fd0b9bdd43bafb)
1 /*-
2  * Copyright (c) 1991-1997 S�ren Schmidt
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software withough specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  *  $Id: mouse.c,v 1.10 1997/08/15 12:32:59 sos Exp $
29  */
30 
31 #include <stdio.h>
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
34 #include <sys/signal.h>
35 #include <machine/console.h>
36 #include "vgl.h"
37 
38 /* prototype for internal function */
39 int __VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy, VGLBitmap *dst, int dstx, int dsty, int width, int hight);
40 
41 #define X 0xff
42 static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
43 	X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
44 	X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
45 	X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
46 	X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
47 	X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
48 	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
49 	X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
50 	X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
51 	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
52 	0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0,
53 	0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0,
54 	0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
55 	0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
56 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
57 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
58 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
59 };
60 static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
61 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62 	0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
63 	0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
64 	0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
65 	0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
66 	0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
67 	0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
68 	0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0,
69 	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
70 	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
71 	0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
72 	0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
73 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
74 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
75 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
76 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
77 };
78 #undef X
79 static VGLBitmap VGLMouseStdAndMask =
80 	{ MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask };
81 static VGLBitmap VGLMouseStdOrMask =
82 	{ MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask };
83 static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
84 static byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
85 static VGLBitmap VGLMouseSave = { MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map};
86 static int VGLMouseVisible = 0;
87 static int VGLMouseFrozen = 0;
88 static int VGLMouseShown = 0;
89 static int VGLMouseXpos = 0;
90 static int VGLMouseYpos = 0;
91 static int VGLMouseButtons = 0;
92 
93 void
94 VGLMousePointerShow()
95 {
96   byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
97   VGLBitmap buffer = { MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf };
98   byte crtcidx, crtcval, gdcidx, gdcval;
99   int pos;
100 
101   if (!VGLMouseVisible) {
102     VGLMouseVisible = 1;
103     crtcidx = inb(0x3c4);
104     crtcval = inb(0x3c5);
105     gdcidx = inb(0x3ce);
106     gdcval = inb(0x3cf);
107     __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos,
108 		  &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
109     bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE);
110     for (pos = 0; pos <  MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++)
111       buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) |
112 			   VGLMouseOrMask->Bitmap[pos];
113     __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay,
114 		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
115     outb(0x3c4, crtcidx);
116     outb(0x3c5, crtcval);
117     outb(0x3ce, gdcidx);
118     outb(0x3cf, gdcval);
119   }
120 }
121 
122 void
123 VGLMousePointerHide()
124 {
125   byte crtcidx, crtcval, gdcidx, gdcval;
126 
127   if (VGLMouseVisible) {
128     VGLMouseVisible = 0;
129     crtcidx = inb(0x3c4);
130     crtcval = inb(0x3c5);
131     gdcidx = inb(0x3ce);
132     gdcval = inb(0x3cf);
133     __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay,
134 		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
135     outb(0x3c4, crtcidx);
136     outb(0x3c5, crtcval);
137     outb(0x3ce, gdcidx);
138     outb(0x3cf, gdcval);
139   }
140 }
141 
142 void
143 VGLMouseMode(int mode)
144 {
145   if (mode == VGL_MOUSESHOW) {
146     if (VGLMouseShown == VGL_MOUSEHIDE) {
147       VGLMousePointerShow();
148       VGLMouseShown = VGL_MOUSESHOW;
149     }
150   }
151   else {
152     if (VGLMouseShown == VGL_MOUSESHOW) {
153       VGLMousePointerHide();
154       VGLMouseShown = VGL_MOUSEHIDE;
155     }
156   }
157 }
158 
159 void
160 VGLMouseAction(int dummy)
161 {
162   struct mouse_info mouseinfo;
163 
164   if (VGLMouseFrozen) {
165     VGLMouseFrozen++;
166     return;
167   }
168   mouseinfo.operation = MOUSE_GETINFO;
169   ioctl(0, CONS_MOUSECTL, &mouseinfo);
170   if (VGLMouseShown == VGL_MOUSESHOW)
171     VGLMousePointerHide();
172   VGLMouseXpos = mouseinfo.u.data.x;
173   VGLMouseYpos = mouseinfo.u.data.y;
174   VGLMouseButtons = mouseinfo.u.data.buttons;
175   if (VGLMouseShown == VGL_MOUSESHOW)
176     VGLMousePointerShow();
177 }
178 
179 void
180 VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
181 {
182   if (VGLMouseShown == VGL_MOUSESHOW)
183     VGLMousePointerHide();
184   VGLMouseAndMask = AndMask;
185   VGLMouseOrMask = OrMask;
186   if (VGLMouseShown == VGL_MOUSESHOW)
187     VGLMousePointerShow();
188 }
189 
190 void
191 VGLMouseSetStdImage()
192 {
193   if (VGLMouseShown == VGL_MOUSESHOW)
194     VGLMousePointerHide();
195   VGLMouseAndMask = &VGLMouseStdAndMask;
196   VGLMouseOrMask = &VGLMouseStdOrMask;
197   if (VGLMouseShown == VGL_MOUSESHOW)
198     VGLMousePointerShow();
199 }
200 
201 int
202 VGLMouseInit(int mode)
203 {
204   struct mouse_info mouseinfo;
205   int error;
206 
207   VGLMouseSetStdImage();
208   mouseinfo.operation = MOUSE_MODE;
209   mouseinfo.u.mode.signal = SIGUSR2;
210   if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
211     return error;
212   signal(SIGUSR2, VGLMouseAction);
213   mouseinfo.operation = MOUSE_GETINFO;
214   ioctl(0, CONS_MOUSECTL, &mouseinfo);
215   VGLMouseXpos = mouseinfo.u.data.x;
216   VGLMouseYpos = mouseinfo.u.data.y;
217   VGLMouseButtons = mouseinfo.u.data.buttons;
218   VGLMouseMode(mode);
219   return 0;
220 }
221 
222 int
223 VGLMouseStatus(int *x, int *y, char *buttons)
224 {
225   signal(SIGUSR2, SIG_IGN);
226   *x =  VGLMouseXpos;
227   *y =  VGLMouseYpos;
228   *buttons =  VGLMouseButtons;
229   signal(SIGUSR2, VGLMouseAction);
230   return VGLMouseShown;
231 }
232 
233 int
234 VGLMouseFreeze(int x, int y, int width, int hight, byte color)
235 {
236   if (!VGLMouseFrozen) {
237     VGLMouseFrozen = 1;
238     if (width > 1 || hight > 1) {		/* bitmap */
239       if (VGLMouseShown == 1) {
240         int overlap;
241 
242         if (x > VGLMouseXpos)
243           overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x;
244         else
245           overlap = (x + width) - VGLMouseXpos;
246         if (overlap > 0) {
247           if (y > VGLMouseYpos)
248             overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y;
249           else
250             overlap = (y + hight) - VGLMouseYpos;
251           if (overlap > 0)
252             VGLMousePointerHide();
253         }
254       }
255     }
256     else {				/* bit */
257       if (VGLMouseShown &&
258           x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE &&
259           y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) {
260         VGLMouseSave.Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)] =
261           (color);
262         if (VGLMouseAndMask->Bitmap
263           [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) {
264           return 1;
265         }
266       }
267     }
268   }
269   return 0;
270 }
271 
272 void
273 VGLMouseUnFreeze()
274 {
275   if (VGLMouseFrozen > 1) {
276     VGLMouseFrozen = 0;
277     VGLMouseAction(0);
278   }
279   else {
280     VGLMouseFrozen = 0;
281     if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible)
282       VGLMousePointerShow();
283   }
284 }
285