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