2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 1991-1997 Søren Schmidt
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
37 #include <sys/signal.h>
38 #include <sys/consio.h>
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,
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,
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 VGLMouseShown = 0;
90 static int VGLMouseXpos = 0;
91 static int VGLMouseYpos = 0;
92 static int VGLMouseButtons = 0;
93 static volatile sig_atomic_t VGLMintpending;
94 static volatile sig_atomic_t VGLMsuppressint;
96 #define INTOFF() (VGLMsuppressint++)
97 #define INTON() do { \
98 if (--VGLMsuppressint == 0 && VGLMintpending) \
103 VGLMousePointerShow()
105 byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE*4];
107 VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf);
108 byte crtcidx, crtcval, gdcidx, gdcval;
111 if (!VGLMouseVisible) {
114 crtcidx = inb(0x3c4);
115 crtcval = inb(0x3c5);
118 __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos,
119 &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
120 bcopy(VGLMouseSave.Bitmap, buffer.Bitmap,
121 MOUSE_IMG_SIZE*MOUSE_IMG_SIZE*VGLDisplay->PixelBytes);
122 for (pos = 0; pos < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++)
123 for (i = 0; i < VGLDisplay->PixelBytes; i++) {
124 pos1 = pos * VGLDisplay->PixelBytes + i;
125 buffer.Bitmap[pos1] = (buffer.Bitmap[pos1] &
126 ~VGLMouseAndMask->Bitmap[pos]) |
127 VGLMouseOrMask->Bitmap[pos];
129 __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay,
130 VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
131 outb(0x3c4, crtcidx);
132 outb(0x3c5, crtcval);
140 VGLMousePointerHide()
142 byte crtcidx, crtcval, gdcidx, gdcval;
144 if (VGLMouseVisible) {
147 crtcidx = inb(0x3c4);
148 crtcval = inb(0x3c5);
151 __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay,
152 VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
153 outb(0x3c4, crtcidx);
154 outb(0x3c5, crtcval);
162 VGLMouseMode(int mode)
164 if (mode == VGL_MOUSESHOW) {
165 if (VGLMouseShown == VGL_MOUSEHIDE) {
166 VGLMousePointerShow();
167 VGLMouseShown = VGL_MOUSESHOW;
171 if (VGLMouseShown == VGL_MOUSESHOW) {
172 VGLMousePointerHide();
173 VGLMouseShown = VGL_MOUSEHIDE;
179 VGLMouseAction(int dummy)
181 struct mouse_info mouseinfo;
183 if (VGLMsuppressint) {
190 mouseinfo.operation = MOUSE_GETINFO;
191 ioctl(0, CONS_MOUSECTL, &mouseinfo);
192 if (VGLMouseShown == VGL_MOUSESHOW)
193 VGLMousePointerHide();
194 VGLMouseXpos = mouseinfo.u.data.x;
195 VGLMouseYpos = mouseinfo.u.data.y;
196 VGLMouseButtons = mouseinfo.u.data.buttons;
197 if (VGLMouseShown == VGL_MOUSESHOW)
198 VGLMousePointerShow();
201 * Loop to handle any new (suppressed) signals. This is INTON() without
202 * recursion. !SA_RESTART prevents recursion in signal handling. So the
203 * maximum recursion is 2 levels.
211 VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
213 if (VGLMouseShown == VGL_MOUSESHOW)
214 VGLMousePointerHide();
215 VGLMouseAndMask = AndMask;
216 VGLMouseOrMask = OrMask;
217 if (VGLMouseShown == VGL_MOUSESHOW)
218 VGLMousePointerShow();
222 VGLMouseSetStdImage()
224 if (VGLMouseShown == VGL_MOUSESHOW)
225 VGLMousePointerHide();
226 VGLMouseAndMask = &VGLMouseStdAndMask;
227 VGLMouseOrMask = &VGLMouseStdOrMask;
228 if (VGLMouseShown == VGL_MOUSESHOW)
229 VGLMousePointerShow();
233 VGLMouseInit(int mode)
235 struct mouse_info mouseinfo;
238 switch (VGLModeInfo.vi_mem_model) {
239 case V_INFO_MM_PACKED:
240 case V_INFO_MM_PLANAR:
250 for (i = 0; i < 256; i++)
251 VGLMouseStdOrMask.Bitmap[i] &= mask;
252 VGLMouseSetStdImage();
253 mouseinfo.operation = MOUSE_MODE;
254 mouseinfo.u.mode.signal = SIGUSR2;
255 if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
257 signal(SIGUSR2, VGLMouseAction);
258 mouseinfo.operation = MOUSE_GETINFO;
259 ioctl(0, CONS_MOUSECTL, &mouseinfo);
260 VGLMouseXpos = mouseinfo.u.data.x;
261 VGLMouseYpos = mouseinfo.u.data.y;
262 VGLMouseButtons = mouseinfo.u.data.buttons;
268 VGLMouseStatus(int *x, int *y, char *buttons)
273 *buttons = VGLMouseButtons;
275 return VGLMouseShown;
279 VGLMouseFreeze(int x, int y, int width, int hight, u_long color)
281 int i, xstride, ystride;
284 if (width > 1 || hight > 1 || (color & 0xc0000000) == 0) { /* bitmap */
285 if (VGLMouseShown == 1) {
288 if (x > VGLMouseXpos)
289 overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x;
291 overlap = (x + width) - VGLMouseXpos;
293 if (y > VGLMouseYpos)
294 overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y;
296 overlap = (y + hight) - VGLMouseYpos;
298 VGLMousePointerHide();
304 x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE &&
305 y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) {
306 xstride = VGLDisplay->PixelBytes;
307 ystride = MOUSE_IMG_SIZE * xstride;
308 if (color & 0x40000000) { /* Get */
310 for (i = xstride - 1; i >= 0; i--)
311 color = (color << 8) |
312 VGLMouseSave.Bitmap[(y-VGLMouseYpos)*ystride+
313 (x-VGLMouseXpos)*xstride+i];
314 return 0x40000000 | (color & 0xffffff);
316 color &= 0xffffff; /* discard flag and other garbage */
317 for (i = 0; i < xstride; i++, color >>= 8)
318 VGLMouseSave.Bitmap[(y-VGLMouseYpos)*ystride+
319 (x-VGLMouseXpos)*xstride+i] = color;
320 if (VGLMouseAndMask->Bitmap
321 [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) {
333 if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible && !VGLMintpending)
334 VGLMousePointerShow();
335 while (VGLMsuppressint)