128328Ssos/*-
2229784Suqs * 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
1597748Sschweikh *    derived from this software without 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 */
2828328Ssos
2983551Sdillon#include <sys/cdefs.h>
3083551Sdillon__FBSDID("$FreeBSD$");
3183551Sdillon
3228328Ssos#include <stdio.h>
3328328Ssos#include <sys/types.h>
3428328Ssos#include <sys/ioctl.h>
3528328Ssos#include <sys/signal.h>
3666834Sphk#include <sys/consio.h>
3766834Sphk#include <sys/fbio.h>
3828328Ssos#include "vgl.h"
3928328Ssos
4028328Ssos#define X 0xff
4128328Ssosstatic byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
4228328Ssos	X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4328328Ssos	X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
4428328Ssos	X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
4528328Ssos	X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
4628328Ssos	X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
4728328Ssos	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
4828328Ssos	X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,
4928328Ssos	X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,
5028328Ssos	X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
5128328Ssos	0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0,
5228328Ssos	0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0,
5328328Ssos	0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,
5428328Ssos	0,0,0,0,X,X,X,X,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	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5728328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5828328Ssos};
5928328Ssosstatic byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
6028328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
6128328Ssos	0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
6228328Ssos	0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,
6328328Ssos	0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,
6428328Ssos	0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0,
6528328Ssos	0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0,
6628328Ssos	0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0,
6728328Ssos	0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0,
6828328Ssos	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
6928328Ssos	0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0,
7028328Ssos	0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,
7128328Ssos	0,0,0,0,0,X,X,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	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7528328Ssos	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7628328Ssos};
7728328Ssos#undef X
7828328Ssosstatic VGLBitmap VGLMouseStdAndMask =
7953013Syokota    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask);
8028328Ssosstatic VGLBitmap VGLMouseStdOrMask =
8153013Syokota    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask);
8228328Ssosstatic VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
8328328Ssosstatic byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
8453013Syokotastatic VGLBitmap VGLMouseSave =
8553013Syokota    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map);
8628328Ssosstatic int VGLMouseVisible = 0;
8728328Ssosstatic int VGLMouseFrozen = 0;
8828328Ssosstatic int VGLMouseShown = 0;
8928328Ssosstatic int VGLMouseXpos = 0;
9028328Ssosstatic int VGLMouseYpos = 0;
9128328Ssosstatic int VGLMouseButtons = 0;
9228328Ssos
9328328Ssosvoid
9428328SsosVGLMousePointerShow()
9528328Ssos{
9628328Ssos  byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
9753013Syokota  VGLBitmap buffer =
9853013Syokota    VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf);
9928328Ssos  byte crtcidx, crtcval, gdcidx, gdcval;
10028328Ssos  int pos;
10128328Ssos
10228328Ssos  if (!VGLMouseVisible) {
10328328Ssos    VGLMouseVisible = 1;
10428328Ssos    crtcidx = inb(0x3c4);
10528328Ssos    crtcval = inb(0x3c5);
10628328Ssos    gdcidx = inb(0x3ce);
10728328Ssos    gdcval = inb(0x3cf);
10828328Ssos    __VGLBitmapCopy(VGLDisplay, VGLMouseXpos, VGLMouseYpos,
10928328Ssos		  &VGLMouseSave, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
11028328Ssos    bcopy(VGLMouseSave.Bitmap, buffer.Bitmap, MOUSE_IMG_SIZE*MOUSE_IMG_SIZE);
11128328Ssos    for (pos = 0; pos <  MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++)
11228328Ssos      buffer.Bitmap[pos]=(buffer.Bitmap[pos]&~(VGLMouseAndMask->Bitmap[pos])) |
11328328Ssos			   VGLMouseOrMask->Bitmap[pos];
11428328Ssos    __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay,
11528328Ssos		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
11628328Ssos    outb(0x3c4, crtcidx);
11728328Ssos    outb(0x3c5, crtcval);
11828328Ssos    outb(0x3ce, gdcidx);
11928328Ssos    outb(0x3cf, gdcval);
12028328Ssos  }
12128328Ssos}
12228328Ssos
12328328Ssosvoid
12428328SsosVGLMousePointerHide()
12528328Ssos{
12628328Ssos  byte crtcidx, crtcval, gdcidx, gdcval;
12728328Ssos
12828328Ssos  if (VGLMouseVisible) {
12928328Ssos    VGLMouseVisible = 0;
13028328Ssos    crtcidx = inb(0x3c4);
13128328Ssos    crtcval = inb(0x3c5);
13228328Ssos    gdcidx = inb(0x3ce);
13328328Ssos    gdcval = inb(0x3cf);
13428328Ssos    __VGLBitmapCopy(&VGLMouseSave, 0, 0, VGLDisplay,
13528328Ssos		  VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE);
13628328Ssos    outb(0x3c4, crtcidx);
13728328Ssos    outb(0x3c5, crtcval);
13828328Ssos    outb(0x3ce, gdcidx);
13928328Ssos    outb(0x3cf, gdcval);
14028328Ssos  }
14128328Ssos}
14228328Ssos
14328328Ssosvoid
14428328SsosVGLMouseMode(int mode)
14528328Ssos{
14628328Ssos  if (mode == VGL_MOUSESHOW) {
14728328Ssos    if (VGLMouseShown == VGL_MOUSEHIDE) {
14828328Ssos      VGLMousePointerShow();
14928328Ssos      VGLMouseShown = VGL_MOUSESHOW;
15028328Ssos    }
15128328Ssos  }
15228328Ssos  else {
15328328Ssos    if (VGLMouseShown == VGL_MOUSESHOW) {
15428328Ssos      VGLMousePointerHide();
15528328Ssos      VGLMouseShown = VGL_MOUSEHIDE;
15628328Ssos    }
15728328Ssos  }
15828328Ssos}
15928328Ssos
16028328Ssosvoid
16128328SsosVGLMouseAction(int dummy)
16228328Ssos{
16328328Ssos  struct mouse_info mouseinfo;
16428328Ssos
16528328Ssos  if (VGLMouseFrozen) {
16628328Ssos    VGLMouseFrozen++;
16728328Ssos    return;
16828328Ssos  }
16928328Ssos  mouseinfo.operation = MOUSE_GETINFO;
17028328Ssos  ioctl(0, CONS_MOUSECTL, &mouseinfo);
17128328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
17228328Ssos    VGLMousePointerHide();
17328328Ssos  VGLMouseXpos = mouseinfo.u.data.x;
17428328Ssos  VGLMouseYpos = mouseinfo.u.data.y;
17528328Ssos  VGLMouseButtons = mouseinfo.u.data.buttons;
17628328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
17728328Ssos    VGLMousePointerShow();
17828328Ssos}
17928328Ssos
18028328Ssosvoid
18128328SsosVGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask)
18228328Ssos{
18328328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
18428328Ssos    VGLMousePointerHide();
18528328Ssos  VGLMouseAndMask = AndMask;
18628328Ssos  VGLMouseOrMask = OrMask;
18728328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
18828328Ssos    VGLMousePointerShow();
18928328Ssos}
19028328Ssos
19128328Ssosvoid
19228328SsosVGLMouseSetStdImage()
19328328Ssos{
19428328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
19528328Ssos    VGLMousePointerHide();
19628328Ssos  VGLMouseAndMask = &VGLMouseStdAndMask;
19728328Ssos  VGLMouseOrMask = &VGLMouseStdOrMask;
19828328Ssos  if (VGLMouseShown == VGL_MOUSESHOW)
19928328Ssos    VGLMousePointerShow();
20028328Ssos}
20128328Ssos
20228328Ssosint
20328328SsosVGLMouseInit(int mode)
20428328Ssos{
20528328Ssos  struct mouse_info mouseinfo;
20628328Ssos  int error;
20728328Ssos
20828328Ssos  VGLMouseSetStdImage();
20928328Ssos  mouseinfo.operation = MOUSE_MODE;
21028328Ssos  mouseinfo.u.mode.signal = SIGUSR2;
21128328Ssos  if ((error = ioctl(0, CONS_MOUSECTL, &mouseinfo)))
21228328Ssos    return error;
21328328Ssos  signal(SIGUSR2, VGLMouseAction);
21428328Ssos  mouseinfo.operation = MOUSE_GETINFO;
21528328Ssos  ioctl(0, CONS_MOUSECTL, &mouseinfo);
21628328Ssos  VGLMouseXpos = mouseinfo.u.data.x;
21728328Ssos  VGLMouseYpos = mouseinfo.u.data.y;
21828328Ssos  VGLMouseButtons = mouseinfo.u.data.buttons;
21928328Ssos  VGLMouseMode(mode);
22028328Ssos  return 0;
22128328Ssos}
22228328Ssos
22328328Ssosint
22428328SsosVGLMouseStatus(int *x, int *y, char *buttons)
22528328Ssos{
22628328Ssos  signal(SIGUSR2, SIG_IGN);
22728328Ssos  *x =  VGLMouseXpos;
22828328Ssos  *y =  VGLMouseYpos;
22928328Ssos  *buttons =  VGLMouseButtons;
23028328Ssos  signal(SIGUSR2, VGLMouseAction);
23128328Ssos  return VGLMouseShown;
23228328Ssos}
23328328Ssos
23428328Ssosint
23528328SsosVGLMouseFreeze(int x, int y, int width, int hight, byte color)
23628328Ssos{
23728328Ssos  if (!VGLMouseFrozen) {
23828328Ssos    VGLMouseFrozen = 1;
23928328Ssos    if (width > 1 || hight > 1) {		/* bitmap */
24028328Ssos      if (VGLMouseShown == 1) {
24128328Ssos        int overlap;
24228328Ssos
24328328Ssos        if (x > VGLMouseXpos)
24428328Ssos          overlap = (VGLMouseXpos + MOUSE_IMG_SIZE) - x;
24528328Ssos        else
24628328Ssos          overlap = (x + width) - VGLMouseXpos;
24728328Ssos        if (overlap > 0) {
24828328Ssos          if (y > VGLMouseYpos)
24928328Ssos            overlap = (VGLMouseYpos + MOUSE_IMG_SIZE) - y;
25028328Ssos          else
25128328Ssos            overlap = (y + hight) - VGLMouseYpos;
25228328Ssos          if (overlap > 0)
25328328Ssos            VGLMousePointerHide();
25428328Ssos        }
25528328Ssos      }
25628328Ssos    }
25728328Ssos    else {				/* bit */
25828328Ssos      if (VGLMouseShown &&
25928328Ssos          x >= VGLMouseXpos && x < VGLMouseXpos + MOUSE_IMG_SIZE &&
26028328Ssos          y >= VGLMouseYpos && y < VGLMouseYpos + MOUSE_IMG_SIZE) {
26128328Ssos        VGLMouseSave.Bitmap[(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)] =
26228328Ssos          (color);
26328328Ssos        if (VGLMouseAndMask->Bitmap
26428328Ssos          [(y-VGLMouseYpos)*MOUSE_IMG_SIZE+(x-VGLMouseXpos)]) {
26528328Ssos          return 1;
26628328Ssos        }
26728328Ssos      }
26828328Ssos    }
26928328Ssos  }
27028328Ssos  return 0;
27128328Ssos}
27228328Ssos
27328328Ssosvoid
27428328SsosVGLMouseUnFreeze()
27528328Ssos{
27628328Ssos  if (VGLMouseFrozen > 1) {
27728328Ssos    VGLMouseFrozen = 0;
27828328Ssos    VGLMouseAction(0);
27928328Ssos  }
28028328Ssos  else {
28128328Ssos    VGLMouseFrozen = 0;
28228328Ssos    if (VGLMouseShown == VGL_MOUSESHOW && !VGLMouseVisible)
28328328Ssos      VGLMousePointerShow();
28428328Ssos  }
28528328Ssos}
286