Initial import from FreeBSD RELENG_4:
[dragonfly.git] / lib / libvgl / mouse.c
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  * $FreeBSD: src/lib/libvgl/mouse.c,v 1.3 1999/11/08 11:37:39 yokota 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 #define X 0xff
39 static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
40         X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
41         X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
42         X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
43         X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
44         X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
45         X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
46         X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
47         X,X,X,X,X,X,X,X,X,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         0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0,
50         0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0,
51         0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
52         0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
53         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
54         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
55         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
56 };
57 static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
58         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
59         0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
60         0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
61         0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
62         0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
63         0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
64         0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
65         0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0,
66         0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
67         0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
68         0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
69         0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
70         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
71         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72         0,0,0,0,0,0,0,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 };
75 #undef X
76 static VGLBitmap VGLMouseStdAndMask = 
77     VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask);
78 static VGLBitmap VGLMouseStdOrMask = 
79     VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask);
80 static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
81 static byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
82 static VGLBitmap VGLMouseSave = 
83     VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map);
84 static int VGLMouseVisible = 0;
85 static int VGLMouseFrozen = 0;
86 static int VGLMouseShown = 0;
87 static int VGLMouseXpos = 0;
88 static int VGLMouseYpos = 0;
89 static int VGLMouseButtons = 0;
90
91 void
92 VGLMousePointerShow()
93 {
94   byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
95   VGLBitmap buffer =
96     VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf);
97   byte crtcidx, crtcval, gdcidx, gdcval;
98   int pos;
99
100   if (!VGLMouseVisible) {
101     VGLMouseVisible = 1;
102     crtcidx = inb(0x3c4);
103     crtcval = inb(0x3c5);
104     gdcidx = inb(0x3ce);
105     gdcval = inb(0x3cf);
106     __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos, 
107                   &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
108     bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE);
109     for (pos = 0; pos <  MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++)
110       buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) |
111                            VGLMouseOrMask->Bitmap[pos];
112     __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay, 
113                   VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
114     outb(0x3c4, crtcidx);
115     outb(0x3c5, crtcval);
116     outb(0x3ce, gdcidx);
117     outb(0x3cf, gdcval);
118   }
119 }
120
121 void
122 VGLMousePointerHide()
123 {
124   byte crtcidx, crtcval, gdcidx, gdcval;
125
126   if (VGLMouseVisible) {
127     VGLMouseVisible = 0;
128     crtcidx = inb(0x3c4);
129     crtcval = inb(0x3c5);
130     gdcidx = inb(0x3ce);
131     gdcval = inb(0x3cf);
132     __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay, 
133                   VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
134     outb(0x3c4, crtcidx);
135     outb(0x3c5, crtcval);
136     outb(0x3ce, gdcidx);
137     outb(0x3cf, gdcval);
138   }
139 }
140
141 void
142 VGLMouseMode(int mode)
143 {
144   if (mode == VGL_MOUSESHOW) {
145     if (VGLMouseShown == VGL_MOUSEHIDE) {
146       VGLMousePointerShow();
147       VGLMouseShown = VGL_MOUSESHOW;
148     }
149   }
150   else {
151     if (VGLMouseShown == VGL_MOUSESHOW) {
152       VGLMousePointerHide();
153       VGLMouseShown = VGL_MOUSEHIDE;
154     }
155   }
156 }
157
158 void
159 VGLMouseAction(int dummy)       
160 {
161   struct mouse_info mouseinfo;
162
163   if (VGLMouseFrozen) {
164     VGLMouseFrozen++;
165     return;
166   }
167   mouseinfo.operation = MOUSE_GETINFO;
168   ioctl(0, CONS_MOUSECTL, &mouseinfo);
169   if (VGLMouseShown == VGL_MOUSESHOW)
170     VGLMousePointerHide();
171   VGLMouseXpos = mouseinfo.u.data.x;
172   VGLMouseYpos = mouseinfo.u.data.y;
173   VGLMouseButtons = mouseinfo.u.data.buttons;
174   if (VGLMouseShown == VGL_MOUSESHOW)
175     VGLMousePointerShow();
176 }
177
178 void
179 VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
180 {
181   if (VGLMouseShown == VGL_MOUSESHOW)
182     VGLMousePointerHide();
183   VGLMouseAndMask = AndMask;
184   VGLMouseOrMask = OrMask;
185   if (VGLMouseShown == VGL_MOUSESHOW)
186     VGLMousePointerShow();
187 }
188
189 void
190 VGLMouseSetStdImage()
191 {
192   if (VGLMouseShown == VGL_MOUSESHOW)
193     VGLMousePointerHide();
194   VGLMouseAndMask = &VGLMouseStdAndMask;
195   VGLMouseOrMask = &VGLMouseStdOrMask;
196   if (VGLMouseShown == VGL_MOUSESHOW)
197     VGLMousePointerShow();
198 }
199
200 int
201 VGLMouseInit(int mode)
202 {
203   struct mouse_info mouseinfo;
204   int error;
205
206   VGLMouseSetStdImage();
207   mouseinfo.operation = MOUSE_MODE;
208   mouseinfo.u.mode.signal = SIGUSR2;
209   if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
210     return error;
211   signal(SIGUSR2, VGLMouseAction);
212   mouseinfo.operation = MOUSE_GETINFO;
213   ioctl(0, CONS_MOUSECTL, &mouseinfo);
214   VGLMouseXpos = mouseinfo.u.data.x;
215   VGLMouseYpos = mouseinfo.u.data.y;
216   VGLMouseButtons = mouseinfo.u.data.buttons;
217   VGLMouseMode(mode);
218   return 0;
219 }
220
221 int
222 VGLMouseStatus(int *x, int *y, char *buttons)
223 {
224   signal(SIGUSR2, SIG_IGN);
225   *x =  VGLMouseXpos;
226   *y =  VGLMouseYpos;
227   *buttons =  VGLMouseButtons;
228   signal(SIGUSR2, VGLMouseAction);
229   return VGLMouseShown;
230 }
231
232 int
233 VGLMouseFreeze(int x, int y, int width, int hight, byte color)
234 {
235   if (!VGLMouseFrozen) {
236     VGLMouseFrozen = 1;
237     if (width > 1 || hight > 1) {               /* bitmap */
238       if (VGLMouseShown == 1) {
239         int overlap;
240
241         if (x > VGLMouseXpos)
242           overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x;
243         else
244           overlap = (x + width) - VGLMouseXpos;
245         if (overlap > 0) {
246           if (y > VGLMouseYpos)
247             overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y;
248           else
249             overlap = (y + hight) - VGLMouseYpos;
250           if (overlap > 0)
251             VGLMousePointerHide();
252         } 
253       }
254     }
255     else {                              /* bit */
256       if (VGLMouseShown &&
257           x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE &&
258           y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) {
259         VGLMouseSave.Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)] =
260           (color);
261         if (VGLMouseAndMask->Bitmap 
262           [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) {
263           return 1;
264         }   
265       }       
266     }
267   }
268   return 0;
269 }
270
271 void
272 VGLMouseUnFreeze()
273 {
274   if (VGLMouseFrozen > 1) {
275     VGLMouseFrozen = 0;
276     VGLMouseAction(0);
277   }
278   else {
279     VGLMouseFrozen = 0;
280     if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible)
281       VGLMousePointerShow();
282   }
283 }