mouse.c revision 53013
155714Skris/*-
2194206Ssimon * Copyright (c) 1991-1997 S�ren Schmidt
355714Skris * All rights reserved.
455714Skris *
555714Skris * Redistribution and use in source and binary forms, with or without
655714Skris * modification, are permitted provided that the following conditions
755714Skris * are met:
855714Skris * 1. Redistributions of source code must retain the above copyright
955714Skris *    notice, this list of conditions and the following disclaimer
1055714Skris *    in this position and unchanged.
1155714Skris * 2. Redistributions in binary form must reproduce the above copyright
1255714Skris *    notice, this list of conditions and the following disclaimer in the
1355714Skris *    documentation and/or other materials provided with the distribution.
1455714Skris * 3. The name of the author may not be used to endorse or promote products
1555714Skris *    derived from this software withough specific prior written permission
1655714Skris *
1755714Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1855714Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1955714Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2055714Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2155714Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2255714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2355714Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2455714Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2555714Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2655714Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2755714Skris *
2855714Skris * $FreeBSD: head/lib/libvgl/mouse.c 53013 1999-11-08 11:37:46Z yokota $
2955714Skris */
3055714Skris
3155714Skris#include <stdio.h>
3255714Skris#include <sys/types.h>
3355714Skris#include <sys/ioctl.h>
3455714Skris#include <sys/signal.h>
3555714Skris#include <machine/console.h>
3655714Skris#include "vgl.h"
3755714Skris
3855714Skris#define X 0xff
3955714Skrisstatic byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
4055714Skris	X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4155714Skris	X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
4255714Skris	X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
4355714Skris	X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
4455714Skris	X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
4555714Skris	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
4655714Skris	X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
4755714Skris	X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
4855714Skris	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
4955714Skris	0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0,
5055714Skris	0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0,
5155714Skris	0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
5255714Skris	0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
5355714Skris	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5455714Skris	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5555714Skris	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5655714Skris};
5755714Skrisstatic byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
5855714Skris	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5955714Skris	0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
6055714Skris	0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
61109998Smarkm	0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
6255714Skris	0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
6355714Skris	0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
6455714Skris	0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
6555714Skris	0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0,
6655714Skris	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
67109998Smarkm	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
68109998Smarkm	0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
69109998Smarkm	0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
70109998Smarkm	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7155714Skris	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72109998Smarkm	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7355714Skris	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7455714Skris};
75238405Sjkim#undef X
76238405Sjkimstatic VGLBitmap VGLMouseStdAndMask =
77238405Sjkim    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask);
78238405Sjkimstatic VGLBitmap VGLMouseStdOrMask =
79238405Sjkim    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask);
80160814Ssimonstatic VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
81238405Sjkimstatic byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
82238405Sjkimstatic VGLBitmap VGLMouseSave =
8355714Skris    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map);
84238405Sjkimstatic int VGLMouseVisible = 0;
85238405Sjkimstatic int VGLMouseFrozen = 0;
86238405Sjkimstatic int VGLMouseShown = 0;
87238405Sjkimstatic int VGLMouseXpos = 0;
88160814Ssimonstatic int VGLMouseYpos = 0;
89238405Sjkimstatic int VGLMouseButtons = 0;
90238405Sjkim
91238405Sjkimvoid
92238405SjkimVGLMousePointerShow()
93238405Sjkim{
94238405Sjkim  byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
95160814Ssimon  VGLBitmap buffer =
96238405Sjkim    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf);
97238405Sjkim  byte crtcidx, crtcval, gdcidx, gdcval;
98238405Sjkim  int pos;
99238405Sjkim
100238405Sjkim  if (!VGLMouseVisible) {
101238405Sjkim    VGLMouseVisible = 1;
102160814Ssimon    crtcidx = inb(0x3c4);
103238405Sjkim    crtcval = inb(0x3c5);
104238405Sjkim    gdcidx = inb(0x3ce);
105238405Sjkim    gdcval = inb(0x3cf);
106238405Sjkim    __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos,
107238405Sjkim		  &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
108160814Ssimon    bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE);
10955714Skris    for (pos = 0; pos <  MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++)
110238405Sjkim      buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) |
111238405Sjkim			   VGLMouseOrMask->Bitmap[pos];
112238405Sjkim    __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay,
113160814Ssimon		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
114238405Sjkim    outb(0x3c4, crtcidx);
11555714Skris    outb(0x3c5, crtcval);
116238405Sjkim    outb(0x3ce, gdcidx);
117160814Ssimon    outb(0x3cf, gdcval);
118238405Sjkim  }
119238405Sjkim}
120238405Sjkim
121238405Sjkimvoid
122238405SjkimVGLMousePointerHide()
123238405Sjkim{
124238405Sjkim  byte crtcidx, crtcval, gdcidx, gdcval;
125238405Sjkim
126238405Sjkim  if (VGLMouseVisible) {
127238405Sjkim    VGLMouseVisible = 0;
12855714Skris    crtcidx = inb(0x3c4);
12955714Skris    crtcval = inb(0x3c5);
130238405Sjkim    gdcidx = inb(0x3ce);
131238405Sjkim    gdcval = inb(0x3cf);
132238405Sjkim    __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay,
133238405Sjkim		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
134238405Sjkim    outb(0x3c4, crtcidx);
135238405Sjkim    outb(0x3c5, crtcval);
136238405Sjkim    outb(0x3ce, gdcidx);
137238405Sjkim    outb(0x3cf, gdcval);
138238405Sjkim  }
139238405Sjkim}
140238405Sjkim
141238405Sjkimvoid
142238405SjkimVGLMouseMode(int mode)
143238405Sjkim{
144238405Sjkim  if (mode == VGL_MOUSESHOW) {
145238405Sjkim    if (VGLMouseShown == VGL_MOUSEHIDE) {
146238405Sjkim      VGLMousePointerShow();
147160814Ssimon      VGLMouseShown = VGL_MOUSESHOW;
148238405Sjkim    }
149  }
150  else {
151    if (VGLMouseShown == VGL_MOUSESHOW) {
152      VGLMousePointerHide();
153      VGLMouseShown = VGL_MOUSEHIDE;
154    }
155  }
156}
157
158void
159VGLMouseAction(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
178void
179VGLMouseSetImage(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
189void
190VGLMouseSetStdImage()
191{
192  if (VGLMouseShown == VGL_MOUSESHOW)
193    VGLMousePointerHide();
194  VGLMouseAndMask = &VGLMouseStdAndMask;
195  VGLMouseOrMask = &VGLMouseStdOrMask;
196  if (VGLMouseShown == VGL_MOUSESHOW)
197    VGLMousePointerShow();
198}
199
200int
201VGLMouseInit(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
221int
222VGLMouseStatus(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
232int
233VGLMouseFreeze(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
271void
272VGLMouseUnFreeze()
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}
284