mouse.c revision 53013
128328Ssos/*-
228328Ssos * Copyright (c) 1991-1997 S�ren Schmidt
328328Ssos * All rights reserved.
428328Ssos *
528328Ssos * Redistribution and use in source and binary forms, with or without
628328Ssos * modification, are permitted provided that the following conditions
728328Ssos * are met:
828328Ssos * 1. Redistributions of source code must retain the above copyright
928328Ssos *    notice, this list of conditions and the following disclaimer
1028328Ssos *    in this position and unchanged.
1128328Ssos * 2. Redistributions in binary form must reproduce the above copyright
1228328Ssos *    notice, this list of conditions and the following disclaimer in the
1328328Ssos *    documentation and/or other materials provided with the distribution.
1428328Ssos * 3. The name of the author may not be used to endorse or promote products
1528328Ssos *    derived from this software withough specific prior written permission
1628328Ssos *
1728328Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1828328Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1928328Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2028328Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2128328Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2228328Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2328328Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2428328Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2528328Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2628328Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2728328Ssos *
2850476Speter * $FreeBSD: head/lib/libvgl/mouse.c 53013 1999-11-08 11:37:46Z yokota $
2928328Ssos */
3028328Ssos
3128328Ssos#include <stdio.h>
3228328Ssos#include <sys/types.h>
3328328Ssos#include <sys/ioctl.h>
3428328Ssos#include <sys/signal.h>
3528328Ssos#include <machine/console.h>
3628328Ssos#include "vgl.h"
3728328Ssos
3828328Ssos#define X 0xff
3928328Ssosstatic byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
4028328Ssos	X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4128328Ssos	X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
4228328Ssos	X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
4328328Ssos	X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
4428328Ssos	X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
4528328Ssos	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
4628328Ssos	X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
4728328Ssos	X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
4828328Ssos	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
4928328Ssos	0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0,
5028328Ssos	0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0,
5128328Ssos	0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
5228328Ssos	0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
5328328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5428328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5528328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5628328Ssos};
5728328Ssosstatic byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
5828328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5928328Ssos	0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
6028328Ssos	0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
6128328Ssos	0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
6228328Ssos	0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
6328328Ssos	0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
6428328Ssos	0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
6528328Ssos	0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0,
6628328Ssos	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
6728328Ssos	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
6828328Ssos	0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
6928328Ssos	0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
7028328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7128328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7228328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7328328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7428328Ssos};
7528328Ssos#undef X
7628328Ssosstatic VGLBitmap VGLMouseStdAndMask =
7753013Syokota    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask);
7828328Ssosstatic VGLBitmap VGLMouseStdOrMask =
7953013Syokota    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask);
8028328Ssosstatic VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
8128328Ssosstatic byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
8253013Syokotastatic VGLBitmap VGLMouseSave =
8353013Syokota    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map);
8428328Ssosstatic int VGLMouseVisible = 0;
8528328Ssosstatic int VGLMouseFrozen = 0;
8628328Ssosstatic int VGLMouseShown = 0;
8728328Ssosstatic int VGLMouseXpos = 0;
8828328Ssosstatic int VGLMouseYpos = 0;
8928328Ssosstatic int VGLMouseButtons = 0;
9028328Ssos
9128328Ssosvoid
9228328SsosVGLMousePointerShow()
9328328Ssos{
9428328Ssos  byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
9553013Syokota  VGLBitmap buffer =
9653013Syokota    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf);
9728328Ssos  byte crtcidx, crtcval, gdcidx, gdcval;
9828328Ssos  int pos;
9928328Ssos
10028328Ssos  if (!VGLMouseVisible) {
10128328Ssos    VGLMouseVisible = 1;
10228328Ssos    crtcidx = inb(0x3c4);
10328328Ssos    crtcval = inb(0x3c5);
10428328Ssos    gdcidx = inb(0x3ce);
10528328Ssos    gdcval = inb(0x3cf);
10628328Ssos    __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos,
10728328Ssos		  &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
10828328Ssos    bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE);
10928328Ssos    for (pos = 0; pos <  MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++)
11028328Ssos      buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) |
11128328Ssos			   VGLMouseOrMask->Bitmap[pos];
11228328Ssos    __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay,
11328328Ssos		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
11428328Ssos    outb(0x3c4, crtcidx);
11528328Ssos    outb(0x3c5, crtcval);
11628328Ssos    outb(0x3ce, gdcidx);
11728328Ssos    outb(0x3cf, gdcval);
11828328Ssos  }
11928328Ssos}
12028328Ssos
12128328Ssosvoid
12228328SsosVGLMousePointerHide()
12328328Ssos{
12428328Ssos  byte crtcidx, crtcval, gdcidx, gdcval;
12528328Ssos
12628328Ssos  if (VGLMouseVisible) {
12728328Ssos    VGLMouseVisible = 0;
12828328Ssos    crtcidx = inb(0x3c4);
12928328Ssos    crtcval = inb(0x3c5);
13028328Ssos    gdcidx = inb(0x3ce);
13128328Ssos    gdcval = inb(0x3cf);
13228328Ssos    __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay,
13328328Ssos		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
13428328Ssos    outb(0x3c4, crtcidx);
13528328Ssos    outb(0x3c5, crtcval);
13628328Ssos    outb(0x3ce, gdcidx);
13728328Ssos    outb(0x3cf, gdcval);
13828328Ssos  }
13928328Ssos}
14028328Ssos
14128328Ssosvoid
14228328SsosVGLMouseMode(int mode)
14328328Ssos{
14428328Ssos  if (mode == VGL_MOUSESHOW) {
14528328Ssos    if (VGLMouseShown == VGL_MOUSEHIDE) {
14628328Ssos      VGLMousePointerShow();
14728328Ssos      VGLMouseShown = VGL_MOUSESHOW;
14828328Ssos    }
14928328Ssos  }
15028328Ssos  else {
15128328Ssos    if (VGLMouseShown == VGL_MOUSESHOW) {
15228328Ssos      VGLMousePointerHide();
15328328Ssos      VGLMouseShown = VGL_MOUSEHIDE;
15428328Ssos    }
15528328Ssos  }
15628328Ssos}
15728328Ssos
15828328Ssosvoid
15928328SsosVGLMouseAction(int dummy)
16028328Ssos{
16128328Ssos  struct mouse_info mouseinfo;
16228328Ssos
16328328Ssos  if (VGLMouseFrozen) {
16428328Ssos    VGLMouseFrozen++;
16528328Ssos    return;
16628328Ssos  }
16728328Ssos  mouseinfo.operation = MOUSE_GETINFO;
16828328Ssos  ioctl(0, CONS_MOUSECTL, &mouseinfo);
16928328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
17028328Ssos    VGLMousePointerHide();
17128328Ssos  VGLMouseXpos = mouseinfo.u.data.x;
17228328Ssos  VGLMouseYpos = mouseinfo.u.data.y;
17328328Ssos  VGLMouseButtons = mouseinfo.u.data.buttons;
17428328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
17528328Ssos    VGLMousePointerShow();
17628328Ssos}
17728328Ssos
17828328Ssosvoid
17928328SsosVGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
18028328Ssos{
18128328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
18228328Ssos    VGLMousePointerHide();
18328328Ssos  VGLMouseAndMask = AndMask;
18428328Ssos  VGLMouseOrMask = OrMask;
18528328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
18628328Ssos    VGLMousePointerShow();
18728328Ssos}
18828328Ssos
18928328Ssosvoid
19028328SsosVGLMouseSetStdImage()
19128328Ssos{
19228328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
19328328Ssos    VGLMousePointerHide();
19428328Ssos  VGLMouseAndMask = &VGLMouseStdAndMask;
19528328Ssos  VGLMouseOrMask = &VGLMouseStdOrMask;
19628328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
19728328Ssos    VGLMousePointerShow();
19828328Ssos}
19928328Ssos
20028328Ssosint
20128328SsosVGLMouseInit(int mode)
20228328Ssos{
20328328Ssos  struct mouse_info mouseinfo;
20428328Ssos  int error;
20528328Ssos
20628328Ssos  VGLMouseSetStdImage();
20728328Ssos  mouseinfo.operation = MOUSE_MODE;
20828328Ssos  mouseinfo.u.mode.signal = SIGUSR2;
20928328Ssos  if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
21028328Ssos    return error;
21128328Ssos  signal(SIGUSR2, VGLMouseAction);
21228328Ssos  mouseinfo.operation = MOUSE_GETINFO;
21328328Ssos  ioctl(0, CONS_MOUSECTL, &mouseinfo);
21428328Ssos  VGLMouseXpos = mouseinfo.u.data.x;
21528328Ssos  VGLMouseYpos = mouseinfo.u.data.y;
21628328Ssos  VGLMouseButtons = mouseinfo.u.data.buttons;
21728328Ssos  VGLMouseMode(mode);
21828328Ssos  return 0;
21928328Ssos}
22028328Ssos
22128328Ssosint
22228328SsosVGLMouseStatus(int *x, int *y, char *buttons)
22328328Ssos{
22428328Ssos  signal(SIGUSR2, SIG_IGN);
22528328Ssos  *x =  VGLMouseXpos;
22628328Ssos  *y =  VGLMouseYpos;
22728328Ssos  *buttons =  VGLMouseButtons;
22828328Ssos  signal(SIGUSR2, VGLMouseAction);
22928328Ssos  return VGLMouseShown;
23028328Ssos}
23128328Ssos
23228328Ssosint
23328328SsosVGLMouseFreeze(int x, int y, int width, int hight, byte color)
23428328Ssos{
23528328Ssos  if (!VGLMouseFrozen) {
23628328Ssos    VGLMouseFrozen = 1;
23728328Ssos    if (width > 1 || hight > 1) {		/* bitmap */
23828328Ssos      if (VGLMouseShown == 1) {
23928328Ssos        int overlap;
24028328Ssos
24128328Ssos        if (x > VGLMouseXpos)
24228328Ssos          overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x;
24328328Ssos        else
24428328Ssos          overlap = (x + width) - VGLMouseXpos;
24528328Ssos        if (overlap > 0) {
24628328Ssos          if (y > VGLMouseYpos)
24728328Ssos            overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y;
24828328Ssos          else
24928328Ssos            overlap = (y + hight) - VGLMouseYpos;
25028328Ssos          if (overlap > 0)
25128328Ssos            VGLMousePointerHide();
25228328Ssos        }
25328328Ssos      }
25428328Ssos    }
25528328Ssos    else {				/* bit */
25628328Ssos      if (VGLMouseShown &&
25728328Ssos          x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE &&
25828328Ssos          y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) {
25928328Ssos        VGLMouseSave.Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)] =
26028328Ssos          (color);
26128328Ssos        if (VGLMouseAndMask->Bitmap
26228328Ssos          [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) {
26328328Ssos          return 1;
26428328Ssos        }
26528328Ssos      }
26628328Ssos    }
26728328Ssos  }
26828328Ssos  return 0;
26928328Ssos}
27028328Ssos
27128328Ssosvoid
27228328SsosVGLMouseUnFreeze()
27328328Ssos{
27428328Ssos  if (VGLMouseFrozen > 1) {
27528328Ssos    VGLMouseFrozen = 0;
27628328Ssos    VGLMouseAction(0);
27728328Ssos  }
27828328Ssos  else {
27928328Ssos    VGLMouseFrozen = 0;
28028328Ssos    if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible)
28128328Ssos      VGLMousePointerShow();
28228328Ssos  }
28328328Ssos}
284