df0a9badc6
means that the dynamic linker gets mapped in at the top of available user virtual memory (typically just below the stack), shared libraries get mapped downwards from that point, and calls to mmap() that don't specify a preferred address will get mapped in below those. This means that the heap and the mmap()ed allocations will grow towards each other, allowing one or the other to grow larger than before. Previously, the heap was limited to MAXDSIZ by the placement of the dynamic linker (and the process's rlimits) and the space available to mmap was hobbled by this reservation. This is currently only enabled via an *option* for the i386 platform (though other platforms are expected to follow). Add "options USE_TOPDOWN_VM" to your kernel config file, rerun config, and rebuild your kernel to take advantage of this. Note that the pmap_prefer() interface has not yet been modified to play nicely with this, so those platforms require a bit more work (most notably the sparc) before they can use this new memory arrangement. This change also introduces a VM_DEFAULT_ADDRESS() macro that picks the appropriate default address based on the size of the allocation or the size of the process's text segment accordingly. Several drivers and the SYSV SHM address assignment were changed to use this instead of each one picking their own "default".
652 lines
16 KiB
C
652 lines
16 KiB
C
/* $NetBSD: qvss_compat.c,v 1.32 2003/02/20 22:16:06 atatat Exp $ */
|
|
|
|
/*-
|
|
* Copyright (c) 1992, 1993
|
|
* The Regents of the University of California. All rights reserved.
|
|
*
|
|
* This code is derived from software contributed to Berkeley by
|
|
* Ralph Campbell and Rick Macklem.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by the University of
|
|
* California, Berkeley and its contributors.
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* @(#)fb.c 8.1 (Berkeley) 6/10/93
|
|
*/
|
|
|
|
/*
|
|
* devGraphics.c --
|
|
*
|
|
* This file contains machine-dependent routines for the graphics device.
|
|
*
|
|
* Copyright (C) 1989 Digital Equipment Corporation.
|
|
* Permission to use, copy, modify, and distribute this software and
|
|
* its documentation for any purpose and without fee is hereby granted,
|
|
* provided that the above copyright notice appears in all copies.
|
|
* Digital Equipment Corporation makes no representations about the
|
|
* suitability of this software for any purpose. It is provided "as is"
|
|
* without express or implied warranty.
|
|
*
|
|
* from: Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
|
|
* v 9.2 90/02/13 22:16:24 shirriff Exp SPRITE (DECWRL)";
|
|
*/
|
|
|
|
/*
|
|
* This file has all the routines common to the various frame buffer drivers
|
|
* including a generic ioctl routine. The pmax_fb structure is passed into the
|
|
* routines and has device specifics stored in it.
|
|
* The LK201 keycode mapping routine is also here along with initialization
|
|
* functions for the keyboard and mouse.
|
|
*/
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/device.h>
|
|
#include <sys/kernel.h>
|
|
#include <sys/proc.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/vnode.h>
|
|
#include <sys/resourcevar.h>
|
|
|
|
#include <uvm/uvm_extern.h>
|
|
#include <miscfs/specfs/specdev.h>
|
|
|
|
#include <dev/cons.h>
|
|
#include <dev/dec/lk201.h> /* LK-201 keycodes */
|
|
|
|
#include <dev/sun/fbio.h>
|
|
#include <machine/fbvar.h>
|
|
#include <machine/pmioctl.h> /* X11R5 Xserver ioctls */
|
|
|
|
#include <pmax/dev/dcvar.h> /* DZ-11 chip console I/O */
|
|
#include <pmax/dev/dtopvar.h> /* dtop console I/O decls */
|
|
#include <pmax/dev/fbreg.h> /* XXX should be renamed fbvar.h */
|
|
#include <pmax/dev/qvssvar.h> /* our own externs */
|
|
|
|
#include <pmax/pmax/pmaxtype.h>
|
|
|
|
#include <pmax/tc/sccvar.h> /* ioasic z8530 I/O decls */
|
|
|
|
#include "dc.h"
|
|
#include "scc.h"
|
|
#include "dtop.h"
|
|
|
|
|
|
/*
|
|
* Prototypes of local functions
|
|
*/
|
|
static void genKbdEvent __P((int ch));
|
|
static void genMouseEvent __P((void *newRepPtr));
|
|
static void genMouseButtons __P((void *newRepPtr));
|
|
|
|
extern struct fbinfo *firstfi; /* XXX */
|
|
|
|
|
|
/*
|
|
* Initialize the old-style pmax framebuffer structure from a new-style
|
|
* rcons structure. Can die when all the old style pmax_fb structures
|
|
* are gone. Note that the QVSS/pm mapped event buffer includes the
|
|
* fbu field initialized below.
|
|
*/
|
|
void
|
|
init_pmaxfbu(fi)
|
|
struct fbinfo *fi;
|
|
{
|
|
|
|
int tty_rows, tty_cols; /* rows, cols for glass-tty mode */
|
|
struct fbuaccess *fbu = NULL;
|
|
|
|
if (fi == NULL || fi->fi_fbu == NULL)
|
|
panic("init_pmaxfb: given null pointer to framebuffer");
|
|
|
|
/* XXX don't rely on there being a pmax_fb struct */
|
|
fbu = fi->fi_fbu;
|
|
|
|
|
|
/* fb dimensions */
|
|
fbu->scrInfo.max_x = fi->fi_type.fb_width;
|
|
fbu->scrInfo.max_y = fi->fi_type.fb_height;
|
|
fbu->scrInfo.max_cur_x = fbu->scrInfo.max_x - 1;
|
|
fbu->scrInfo.max_cur_y = fbu->scrInfo.max_y - 1;
|
|
|
|
/* these have the same initial value on qvss-style framebuffers */
|
|
fbu->scrInfo.version = 11;
|
|
fbu->scrInfo.mthreshold = 4;
|
|
fbu->scrInfo.mscale = 2;
|
|
|
|
/* this is not always right (pm on kn01) but it's a common case */
|
|
fbu->scrInfo.min_cur_x = 0;
|
|
fbu->scrInfo.min_cur_y = 0;
|
|
|
|
/*
|
|
* Compute glass-tty dimensions. These don't belong here
|
|
* anymore, but the Ultrix and 4.3+ bsd drivers put them
|
|
* in the event structure mapped into user address space.
|
|
*/
|
|
|
|
tty_cols = 80;
|
|
|
|
/* A guess, but correct for 1024x864, 1024x768 and 1280x1024 */
|
|
tty_rows = (fi->fi_type.fb_height / 15) - 1;
|
|
|
|
#ifdef notdef
|
|
if (tty_rows != fbu->scrInfo.max_row ||
|
|
tty_cols != fbu->scrInfo.max_col)
|
|
printf("framebuffer init: size mismatch: given %dx%d, compute %dx%d\n",
|
|
fbu->scrInfo.max_row, fbu->scrInfo.max_col,
|
|
tty_rows, tty_cols);
|
|
#endif
|
|
|
|
pmEventQueueInit(&fi->fi_fbu->scrInfo.qe);
|
|
}
|
|
|
|
|
|
/*
|
|
* Initialize the qvss-style ringbuffer of mouse button/move
|
|
* events to be empty. Called both when initializing the
|
|
* console softc and on each new open of that device.
|
|
*/
|
|
void
|
|
pmEventQueueInit(qe)
|
|
pmEventQueue *qe;
|
|
{
|
|
qe->timestamp_ms = TO_MS(time);
|
|
qe->eSize = PM_MAXEVQ;
|
|
qe->eHead = qe->eTail = 0;
|
|
qe->tcSize = MOTION_BUFFER_SIZE;
|
|
qe->tcNext = 0;
|
|
}
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* fbKbdEvent --
|
|
*
|
|
* Process a received character.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* Events added to the queue.
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
void
|
|
fbKbdEvent(ch, fi)
|
|
int ch;
|
|
struct fbinfo *fi;
|
|
{
|
|
pmEvent *eventPtr;
|
|
int i;
|
|
struct fbuaccess *fbu = NULL;
|
|
|
|
if (!fi->fi_open)
|
|
return;
|
|
|
|
fbu = fi->fi_fbu;
|
|
|
|
/*
|
|
* See if there is room in the queue.
|
|
*/
|
|
i = PM_EVROUND(fbu->scrInfo.qe.eTail + 1);
|
|
if (i == fbu->scrInfo.qe.eHead)
|
|
return;
|
|
|
|
/*
|
|
* Add the event to the queue.
|
|
*/
|
|
eventPtr = &fbu->events[fbu->scrInfo.qe.eTail];
|
|
eventPtr->type = BUTTON_RAW_TYPE;
|
|
eventPtr->device = KEYBOARD_DEVICE;
|
|
eventPtr->x = fbu->scrInfo.mouse.x;
|
|
eventPtr->y = fbu->scrInfo.mouse.y;
|
|
eventPtr->time = TO_MS(time);
|
|
eventPtr->key = ch;
|
|
fbu->scrInfo.qe.eTail = i;
|
|
selnotify(&fi->fi_selp, 0);
|
|
}
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* fbMouseEvent --
|
|
*
|
|
* Process a mouse event.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* An event is added to the event queue.
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
void
|
|
fbMouseEvent(newRepPtr, fi)
|
|
MouseReport *newRepPtr;
|
|
struct fbinfo *fi;
|
|
{
|
|
unsigned milliSec;
|
|
int i;
|
|
pmEvent *eventPtr;
|
|
struct fbuaccess *fbu = NULL;
|
|
|
|
if (!fi->fi_open)
|
|
return;
|
|
|
|
fbu = fi->fi_fbu;
|
|
|
|
milliSec = TO_MS(time);
|
|
|
|
/*
|
|
* Check to see if we have to accelerate the mouse
|
|
*/
|
|
if (fbu->scrInfo.mscale >= 0) {
|
|
if (newRepPtr->dx >= fbu->scrInfo.mthreshold) {
|
|
newRepPtr->dx +=
|
|
(newRepPtr->dx - fbu->scrInfo.mthreshold) *
|
|
fbu->scrInfo.mscale;
|
|
}
|
|
if (newRepPtr->dy >= fbu->scrInfo.mthreshold) {
|
|
newRepPtr->dy +=
|
|
(newRepPtr->dy - fbu->scrInfo.mthreshold) *
|
|
fbu->scrInfo.mscale;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Update mouse position
|
|
*/
|
|
if (newRepPtr->state & MOUSE_X_SIGN) {
|
|
fbu->scrInfo.mouse.x += newRepPtr->dx;
|
|
if (fbu->scrInfo.mouse.x > fbu->scrInfo.max_cur_x)
|
|
fbu->scrInfo.mouse.x = fbu->scrInfo.max_cur_x;
|
|
} else {
|
|
fbu->scrInfo.mouse.x -= newRepPtr->dx;
|
|
if (fbu->scrInfo.mouse.x < fbu->scrInfo.min_cur_x)
|
|
fbu->scrInfo.mouse.x = fbu->scrInfo.min_cur_x;
|
|
}
|
|
if (newRepPtr->state & MOUSE_Y_SIGN) {
|
|
fbu->scrInfo.mouse.y -= newRepPtr->dy;
|
|
if (fbu->scrInfo.mouse.y < fbu->scrInfo.min_cur_y)
|
|
fbu->scrInfo.mouse.y = fbu->scrInfo.min_cur_y;
|
|
} else {
|
|
fbu->scrInfo.mouse.y += newRepPtr->dy;
|
|
if (fbu->scrInfo.mouse.y > fbu->scrInfo.max_cur_y)
|
|
fbu->scrInfo.mouse.y = fbu->scrInfo.max_cur_y;
|
|
}
|
|
|
|
/*
|
|
* Move the hardware cursor.
|
|
*/
|
|
(*fi->fi_driver->fbd_poscursor)
|
|
(fi, fbu->scrInfo.mouse.x, fbu->scrInfo.mouse.y);
|
|
|
|
/*
|
|
* Store the motion event in the motion buffer.
|
|
*/
|
|
fbu->tcs[fbu->scrInfo.qe.tcNext].time = milliSec;
|
|
fbu->tcs[fbu->scrInfo.qe.tcNext].x = fbu->scrInfo.mouse.x;
|
|
fbu->tcs[fbu->scrInfo.qe.tcNext].y = fbu->scrInfo.mouse.y;
|
|
if (++fbu->scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE)
|
|
fbu->scrInfo.qe.tcNext = 0;
|
|
if (fbu->scrInfo.mouse.y < fbu->scrInfo.mbox.bottom &&
|
|
fbu->scrInfo.mouse.y >= fbu->scrInfo.mbox.top &&
|
|
fbu->scrInfo.mouse.x < fbu->scrInfo.mbox.right &&
|
|
fbu->scrInfo.mouse.x >= fbu->scrInfo.mbox.left)
|
|
return;
|
|
|
|
fbu->scrInfo.mbox.bottom = 0;
|
|
if (PM_EVROUND(fbu->scrInfo.qe.eTail + 1) == fbu->scrInfo.qe.eHead)
|
|
return;
|
|
|
|
i = PM_EVROUND(fbu->scrInfo.qe.eTail - 1);
|
|
if ((fbu->scrInfo.qe.eTail != fbu->scrInfo.qe.eHead) &&
|
|
(i != fbu->scrInfo.qe.eHead)) {
|
|
pmEvent *eventPtr;
|
|
|
|
eventPtr = &fbu->events[i];
|
|
if (eventPtr->type == MOTION_TYPE) {
|
|
eventPtr->x = fbu->scrInfo.mouse.x;
|
|
eventPtr->y = fbu->scrInfo.mouse.y;
|
|
eventPtr->time = milliSec;
|
|
eventPtr->device = MOUSE_DEVICE;
|
|
return;
|
|
}
|
|
}
|
|
/*
|
|
* Put event into queue and wakeup any waiters.
|
|
*/
|
|
eventPtr = &fbu->events[fbu->scrInfo.qe.eTail];
|
|
eventPtr->type = MOTION_TYPE;
|
|
eventPtr->time = milliSec;
|
|
eventPtr->x = fbu->scrInfo.mouse.x;
|
|
eventPtr->y = fbu->scrInfo.mouse.y;
|
|
eventPtr->device = MOUSE_DEVICE;
|
|
fbu->scrInfo.qe.eTail = PM_EVROUND(fbu->scrInfo.qe.eTail + 1);
|
|
selnotify(&fi->fi_selp, 0);
|
|
}
|
|
|
|
/*
|
|
*----------------------------------------------------------------------
|
|
*
|
|
* fbMouseButtons --
|
|
*
|
|
* Process mouse buttons.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* None.
|
|
*
|
|
*----------------------------------------------------------------------
|
|
*/
|
|
void
|
|
fbMouseButtons(newRepPtr, fi)
|
|
MouseReport *newRepPtr;
|
|
struct fbinfo *fi;
|
|
{
|
|
static char temp, oldSwitch, newSwitch;
|
|
int i, j;
|
|
pmEvent *eventPtr;
|
|
static MouseReport lastRep;
|
|
struct fbuaccess *fbu = NULL;
|
|
|
|
if (!fi->fi_open)
|
|
return;
|
|
|
|
fbu = fi->fi_fbu;
|
|
|
|
newSwitch = newRepPtr->state & 0x07;
|
|
oldSwitch = lastRep.state & 0x07;
|
|
|
|
temp = oldSwitch ^ newSwitch;
|
|
if (temp == 0)
|
|
return;
|
|
for (j = 1; j < 8; j <<= 1) {
|
|
if ((j & temp) == 0)
|
|
continue;
|
|
|
|
/*
|
|
* Check for room in the queue
|
|
*/
|
|
i = PM_EVROUND(fbu->scrInfo.qe.eTail+1);
|
|
if (i == fbu->scrInfo.qe.eHead)
|
|
return;
|
|
|
|
/*
|
|
* Put event into queue.
|
|
*/
|
|
eventPtr = &fbu->events[fbu->scrInfo.qe.eTail];
|
|
|
|
switch (j) {
|
|
case RIGHT_BUTTON:
|
|
eventPtr->key = EVENT_RIGHT_BUTTON;
|
|
break;
|
|
|
|
case MIDDLE_BUTTON:
|
|
eventPtr->key = EVENT_MIDDLE_BUTTON;
|
|
break;
|
|
|
|
case LEFT_BUTTON:
|
|
eventPtr->key = EVENT_LEFT_BUTTON;
|
|
}
|
|
if (newSwitch & j)
|
|
eventPtr->type = BUTTON_DOWN_TYPE;
|
|
else
|
|
eventPtr->type = BUTTON_UP_TYPE;
|
|
eventPtr->device = MOUSE_DEVICE;
|
|
|
|
eventPtr->time = TO_MS(time);
|
|
eventPtr->x = fbu->scrInfo.mouse.x;
|
|
eventPtr->y = fbu->scrInfo.mouse.y;
|
|
fbu->scrInfo.qe.eTail = i;
|
|
}
|
|
selnotify(&fi->fi_selp, 0);
|
|
|
|
lastRep = *newRepPtr;
|
|
fbu->scrInfo.mswitches = newSwitch;
|
|
}
|
|
|
|
/*
|
|
* Use vm_mmap() to map the frame buffer and shared data into the user's
|
|
* address space.
|
|
* Return errno if there was an error.
|
|
*/
|
|
int
|
|
fbmmap_fb(fi, dev, data, p)
|
|
struct fbinfo *fi;
|
|
dev_t dev;
|
|
caddr_t data;
|
|
struct proc *p;
|
|
{
|
|
int error;
|
|
vaddr_t addr;
|
|
vsize_t len;
|
|
struct vnode vn;
|
|
struct specinfo si;
|
|
struct fbuaccess *fbp;
|
|
struct fbuaccess *fbu = fi->fi_fbu;
|
|
|
|
len = mips_round_page(((vaddr_t)fbu & PGOFSET) +
|
|
sizeof(struct fbuaccess)) +
|
|
mips_round_page(fi->fi_type.fb_size);
|
|
addr = VM_DEFAULT_ADDRESS(p->p_vmspace->vm_daddr, len);
|
|
vn.v_type = VCHR; /* XXX */
|
|
vn.v_specinfo = &si; /* XXX */
|
|
vn.v_rdev = dev; /* XXX */
|
|
/*
|
|
* Map the all the data the user needs access to into
|
|
* user space.
|
|
*/
|
|
error = uvm_mmap(&p->p_vmspace->vm_map, &addr, len,
|
|
VM_PROT_ALL, VM_PROT_ALL, MAP_SHARED, &vn, 0,
|
|
p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
|
|
if (error)
|
|
return (error);
|
|
fbp = (struct fbuaccess *)(addr + ((vaddr_t)fbu & PGOFSET));
|
|
*(PM_Info **)data = &fbp->scrInfo;
|
|
fbu->scrInfo.qe.events = fbp->events;
|
|
fbu->scrInfo.qe.tcs = fbp->tcs;
|
|
fbu->scrInfo.planemask = (char *)0;
|
|
/*
|
|
* Map the frame buffer into the user's address space.
|
|
*/
|
|
fbu->scrInfo.bitmap = (char *)mips_round_page(fbp + 1);
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* Generic functions for keyboard and mouse input.
|
|
* Just use the "generic" qvss/pm-compatible functions above, but pass them
|
|
* the soft state for the first framebuffer found on this system.
|
|
* We don't support more than one mouse, even for multiple
|
|
* framebuffers, so this should be adequate.
|
|
* It also relieves each fb driver from having to provide its own
|
|
* version of these functions.
|
|
*
|
|
* TODO: change the callers of these to pass a pointer to the struct fbinfo,
|
|
* thus finessing the problem.
|
|
*/
|
|
|
|
static void
|
|
genKbdEvent(ch)
|
|
int ch;
|
|
{
|
|
fbKbdEvent(ch, firstfi);
|
|
}
|
|
|
|
static void
|
|
genMouseEvent(newRepPtr)
|
|
void *newRepPtr;
|
|
{
|
|
fbMouseEvent(newRepPtr, firstfi);
|
|
}
|
|
|
|
static void
|
|
genMouseButtons(newRepPtr)
|
|
void *newRepPtr;
|
|
{
|
|
fbMouseButtons(newRepPtr, firstfi);
|
|
}
|
|
|
|
/*
|
|
* Configure the mouse and keyboard based on machine type
|
|
*/
|
|
void
|
|
genConfigMouse()
|
|
{
|
|
int s;
|
|
|
|
s = spltty();
|
|
switch (systype) {
|
|
|
|
#if NDC > 0
|
|
case DS_PMAX:
|
|
case DS_3MAX:
|
|
dcDivertXInput = genKbdEvent;
|
|
dcMouseEvent = genMouseEvent;
|
|
dcMouseButtons = genMouseButtons;
|
|
break;
|
|
#endif /* NDC */
|
|
|
|
#if NSCC > 0
|
|
case DS_3MIN:
|
|
case DS_3MAXPLUS:
|
|
sccDivertXInput = genKbdEvent;
|
|
sccMouseEvent = genMouseEvent;
|
|
sccMouseButtons = genMouseButtons;
|
|
break;
|
|
#endif
|
|
#if NDTOP > 0
|
|
case DS_MAXINE:
|
|
dtopDivertXInput = genKbdEvent;
|
|
dtopMouseEvent = genMouseEvent;
|
|
dtopMouseButtons = genMouseButtons;
|
|
break;
|
|
#endif
|
|
default:
|
|
printf("Can't configure mouse/keyboard\n");
|
|
};
|
|
splx(s);
|
|
}
|
|
|
|
/*
|
|
* and deconfigure them
|
|
*/
|
|
void
|
|
genDeconfigMouse()
|
|
{
|
|
int s;
|
|
|
|
s = spltty();
|
|
switch (systype) {
|
|
|
|
#if NDC > 0
|
|
case DS_PMAX:
|
|
case DS_3MAX:
|
|
dcDivertXInput = NULL;
|
|
dcMouseEvent = NULL;
|
|
dcMouseButtons = NULL;
|
|
break;
|
|
#endif /* NDC */
|
|
|
|
#if NSCC > 0
|
|
case DS_3MIN:
|
|
case DS_3MAXPLUS:
|
|
sccDivertXInput = NULL;
|
|
sccMouseEvent = NULL;
|
|
sccMouseButtons = NULL;
|
|
break;
|
|
#endif
|
|
|
|
#if NDTOP > 0
|
|
case DS_MAXINE:
|
|
dtopDivertXInput = NULL;
|
|
dtopMouseEvent = NULL;
|
|
dtopMouseButtons = NULL;
|
|
break;
|
|
#endif
|
|
default:
|
|
printf("Can't deconfigure mouse/keyboard\n");
|
|
};
|
|
}
|
|
|
|
|
|
/**
|
|
** And a mouse-report handler for redirected mouse input.
|
|
** Could arguably be in its own source file, but it's only
|
|
** used when the kernel is performing mouse tracking.
|
|
**/
|
|
|
|
/*
|
|
* Mouse-event parser. Called as an upcall with each character
|
|
* read from a serial port. Accumulates complete mouse-event
|
|
* reports and passes them up to framebuffer layer.
|
|
* Mouse events are reported as a 3-byte sequence:
|
|
* header+button state, delta-x, delta-y
|
|
*/
|
|
void
|
|
mouseInput(cc)
|
|
int cc;
|
|
{
|
|
MouseReport *mrp;
|
|
static MouseReport currentRep;
|
|
|
|
mrp = ¤tRep;
|
|
mrp->byteCount++;
|
|
if (cc & MOUSE_START_FRAME) {
|
|
/*
|
|
* The first mouse report byte (button state).
|
|
*/
|
|
mrp->state = cc;
|
|
if (mrp->byteCount > 1)
|
|
mrp->byteCount = 1;
|
|
} else if (mrp->byteCount == 2) {
|
|
/*
|
|
* The second mouse report byte (delta x).
|
|
*/
|
|
mrp->dx = cc;
|
|
} else if (mrp->byteCount == 3) {
|
|
/*
|
|
* The final mouse report byte (delta y).
|
|
*/
|
|
mrp->dy = cc;
|
|
mrp->byteCount = 0;
|
|
if (mrp->dx != 0 || mrp->dy != 0) {
|
|
/*
|
|
* If the mouse moved,
|
|
* post a motion event.
|
|
*/
|
|
(genMouseEvent)(mrp);
|
|
}
|
|
(genMouseButtons)(mrp);
|
|
}
|
|
}
|