XFree86 4.3.0.1

This commit is contained in:
Kaleb Keithley 2003-11-14 16:49:22 +00:00
commit d568221710
438 changed files with 42562 additions and 37394 deletions

View file

@ -1,4 +1,4 @@
/* XFree86: $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/VTsw_sco.c,v 1.3 2001/06/30 22:41:49 tsi Exp $ */
/*
* Copyright 1993 by David Wexelblat <dwex@goblin.org>
* Copyright 1993 by David McCullough <davidm@stallion.oz.au>
@ -22,73 +22,93 @@
* PERFORMANCE OF THIS SOFTWARE.
*
*/
/* $Xorg: VTsw_sco.c,v 1.3 2000/08/17 19:51:28 cpqbld Exp $ */
/* $XConsortium: VTsw_sco.c /main/2 1995/11/13 06:08:36 kaleb $ */
#include "X.h"
#include "input.h"
#include "scrnintstr.h"
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
/* For the event driver prototypes */
#include <sys/event.h>
#include <mouse.h>
/*
* Handle the VT-switching interface for SCO
*/
/*
* This function is the signal handler for the VT-switching signal. It
* is only referenced inside the OS-support layer.
* is only referenced inside the OS-support layer. NOTE: we do NOT need
* to re-arm the signal here, since we used sigaction() to set the signal
* disposition in sco_init.c. If we had used signal(), we would need to
* re-arm the signal here. All we need to do now is record the fact that
* we got the signal. XFree86 handles the rest.
*/
void xf86VTRequest(sig)
int sig;
void
xf86VTRequest(int sig)
{
signal(sig, (void(*)())xf86VTRequest);
xf86Info.vtRequestsPending = TRUE;
return;
xf86Info.vtRequestsPending = TRUE;
return;
}
Bool xf86VTSwitchPending()
Bool
xf86VTSwitchPending()
{
return(xf86Info.vtRequestsPending ? TRUE : FALSE);
return(xf86Info.vtRequestsPending ? TRUE : FALSE);
}
Bool xf86VTSwitchAway()
/*
* When we switch away, we need to flush and suspend the event driver
* before the VT_RELDISP. We also need to get the current LED status
* and preserve it, so that we can restore it when we come back.
*/
static int sco_ledstatus = -1;
static unsigned int sco_ledstate = 0;
Bool
xf86VTSwitchAway()
{
xf86Info.vtRequestsPending = FALSE;
if (ioctl(xf86Info.consoleFd, VT_RELDISP, 1) < 0)
{
return(FALSE);
}
else
{
return(TRUE);
}
ev_flush();
ev_suspend();
sco_ledstatus = ioctl(xf86Info.consoleFd, KDGETLED, &sco_ledstate);
xf86Info.vtRequestsPending = FALSE;
if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_TRUE) < 0) {
return(FALSE);
} else {
return(TRUE);
}
}
Bool xf86VTSwitchTo()
/*
* When we come back to the X server, we need to resume the event driver,
* and we need to restore the LED settings to what they were when we
* switched away.
*/
Bool
xf86VTSwitchTo()
{
xf86Info.vtRequestsPending = FALSE;
if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
{
return(FALSE);
}
else
{
/*
* make sure the console driver thinks the console is in
* graphics mode. Under mono we have to do the two as the
* console driver only allows valid modes for the current
* video card and Herc or vga are the only devices currently
* supported.
*/
if (ioctl(xf86Info.consoleFd, SW_VGA12, 0) < 0)
if (ioctl(xf86Info.consoleFd, SW_HGC_P0, 0) < 0)
{
ErrorF("Failed to set graphics mode : %s\n",
strerror(errno));
}
ev_resume();
return(TRUE);
}
xf86Info.vtRequestsPending = FALSE;
if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0) {
return(FALSE);
} else {
if (sco_ledstatus >= 0) {
ioctl (xf86Info.consoleFd, KDSETLED, &sco_ledstate);
}
sco_ledstatus = -1;
/*
* Convince the console driver this screen is in graphics mode,
* otherwise it assumes it can do more to the screen than it should.
*/
if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) {
ErrorF("Failed to set graphics mode (%s)\n", strerror(errno));
}
return TRUE;
}
}

View file

@ -1,261 +1,324 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_init.c,v 3.10.2.1 1998/02/06 22:36:53 hohndel Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_init.c,v 3.14 2002/11/20 23:00:44 dawes Exp $ */
/*
* Copyright 1993 by David McCullough <davidm@stallion.oz.au>
* Copyright 1993 by David Wexelblat <dwex@goblin.org>
* Copyright 2001 by J. Kean Johnston <jkj@sco.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the names of David McCullough and David Wexelblat
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. David McCullough and
* David Wexelblat makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID MCCULLOUGH AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL DAVID MCCULLOUGH OR DAVID WEXELBLAT BE
* LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* documentation, and that the name J. Kean Johnston not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. J. Kean Johnston makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* J. KEAN JOHNSTON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL J. KEAN JOHNSTON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Xorg: sco_init.c,v 1.3 2000/08/17 19:51:28 cpqbld Exp $ */
/* $XConsortium$ */
/* Re-written May 2001 to represent the current state of reality */
#include "X.h"
#include "Xmd.h"
#include "input.h"
#include "scrnintstr.h"
#include "compiler.h"
#include "xf86.h"
#include "xf86Procs.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
static Bool KeepTty = FALSE;
static int VTnum = -1;
static char *vtdevice = NULL;
static int sco_console_mode = -1;
extern void xf86VTRequest(
#if NeedFunctionPrototypes
int
#endif
);
extern Bool mpxLock;
void xf86OpenConsole()
void
xf86OpenConsole()
{
int fd,wc;
struct vt_mode VT;
struct stat status;
char vtname[11];
if (serverGeneration == 1)
{
/* check if we're run with euid==0 */
if (geteuid() != 0)
{
FatalError("xf86OpenConsole: Server must be running with root "
"permissions\n"
"You should be using Xwrapper to start the server or xdm.\n"
"We strongly advise against making the server SUID root!\n");
}
/*
* setup the virtual terminal manager
*
* SCO vts start at tty01 which is vt00, if you could call them VT's.
* We use the numbers 1..X as it fits nicer with the device naming
* scheme.
*
* In os/osinit.c we took the precuation of not closing stdin so that
* we can use the current vt if no vt was specified on the command line
*
* Under SCO VT_OPENQRY does nothing at all
* if nothing was specified we try to determine the VT from stdin
*/
if ((VTnum != -1) && (VTnum != 0))
{
wc = VTnum - 1;
}
else
{
if ((fstat(0, &status) >= 0) && (status.st_mode & S_IFCHR))
{
wc = minor(status.st_rdev);
}
else
{
ErrorF("%s: Failed to stat stdin, using tty02 (%s)\n",
"xf86OpenConsole", strerror(errno));
wc = 1; /* tty02 */
}
}
ErrorF("(using VT number %d)\n\n", wc + 1);
sprintf(vtname,"/dev/tty%02d", wc+1); /* /dev/tty[01-12] */
if ((xf86Info.consoleFd = open(vtname, O_RDWR | O_NDELAY, 0)) < 0)
{
FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
vtname, strerror(errno));
}
/* now we can dispose of stdin */
if (freopen(vtname, "r+", stdin) == (FILE *) NULL)
{
FatalError("xf86OpenConsole: Cannot reopen stdin as %s (%s)\n",
vtname, strerror(errno));
}
/* now we can fixup stdout */
if (freopen(vtname, "r+", stdout) == (FILE *) NULL)
{
FatalError("xf86OpenConsole: Cannot reopen stdout as %s (%s)\n",
vtname, strerror(errno));
}
/* We activate the console just in case its not the one we are on */
xf86Info.vtno = wc;
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, wc) != 0)
{
ErrorF("xf86OpenConsole: VT_ACTIVATE failed\n");
}
xf86Config(FALSE); /* Read XF86Config */
if (!KeepTty)
{
setpgrp();
}
/*
* now get the VT
*/
if ((sco_console_mode = ioctl(xf86Info.consoleFd, CONS_GET, 0L)) < 0)
{
FatalError("xf86OpenConsole: VT_GETMODE failed on console (%s)\n",
strerror(errno));
}
if (ioctl(xf86Info.consoleFd, VGA_IOPRIVL, 1) < 0)
{
FatalError("xf86OpenConsole: VGA_IOPRIVL failed for VGA acc (%s)\n",
strerror(errno));
}
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
{
FatalError("xf86OpenConsole: VT_GETMODE failed (%s)\n",
strerror(errno));
}
signal(SIGUSR1, xf86VTRequest);
VT.mode = VT_PROCESS;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
VT.frsig = SIGUSR1;
VT.waitv = 0;
if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
{
FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
}
/*
* make sure the console driver thinks the console is in graphics
* mode. Under mono we have to do the two as the console driver only
* allows valid modes for the current video card and Herc or vga are
* the only devices currently supported.
*/
if (ioctl(xf86Info.consoleFd, SW_VGA12, 0) < 0)
if (ioctl(xf86Info.consoleFd, SW_HGC_P0, 0) < 0)
{
ErrorF("Failed to set graphics mode (%s)\n",
strerror(errno));
}
int fd,i, ioctl_ret;
struct vt_mode VT;
static char vtname[32];
struct vid_info vidinf;
struct sigaction sigvtsw;
if (serverGeneration == 1) {
/* check if we're run with euid==0 */
if (geteuid() != 0) {
FatalError("xf86OpenConsole: Server must be setuid root\n");
}
else
{
/* serverGeneration != 1 */
/*
* now get the VT
*/
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
{
ErrorF("xf86OpenConsole: VT_ACTIVATE failed\n");
}
/*
* Set up the virtual terminal (multiscreen in SCO parlance).
* For the actual console itself, screens are numbered from
* 1 to (usually) 16. However, it is possible to have a nested
* server, and it is also possible to be on a multi-console
* system such as MaxSpeed or SunRiver. Therefore, we should
* not make any assumptions about the TTY name we are on, and
* instead we rely on ttyname() to give us the real TTY name.
* Previously, XFree86 tried to determine the TTY name manually.
* This is wrong. The only time we need to futz with the TTY name
* if if we were given the name of a TTY to run on explicity on
* the command line.
*/
if (VTnum == -1) {
/*
* We can query the current VT number using CONS_GETINFO.
*/
char *ttn;
vidinf.size = sizeof(vidinf);
if (ioctl (0, CONS_GETINFO, &vidinf) < 0) {
FatalError ("xf86OpenConsole: Not on a console device "
"or error querying device (%s)\n", strerror (errno));
}
VTnum = vidinf.m_num + 1; /* 0-based */
ttn = ttyname (0);
if (ttn == (char *)0) {
ErrorF ("xf86OpenConsole: Error determining TTY name (%s)\n",
strerror(errno));
snprintf (vtname, sizeof(vtname)-1, "/dev/tty%02d", VTnum);
} else {
strlcpy (vtname, ttn, sizeof(vtname));
}
vtdevice = vtname;
} else if (VTnum == -2 || VTnum >= 0) {
/*
* An explicit device was specified. Make sure its a console device.
*/
if (VTnum != -2) {
snprintf (vtname, sizeof(vtname)-1, "/dev/tty%02d", VTnum);
vtdevice = vtname;
}
fd = open (vtdevice, O_RDWR | O_NDELAY, 0);
if (fd < 0) {
FatalError ("xf86OpenConsole: Can not open device '%s' (%s)\n",
vtdevice, strerror(errno));
}
vidinf.size = sizeof(vidinf);
if (ioctl (fd, CONS_GETINFO, &vidinf) < 0) {
FatalError ("xf86OpenConsole: '%s' is not a console device "
"or error querying device (%s)\n", vtname, strerror (errno));
}
VTnum = vidinf.m_num + 1; /* 0-based */
close (fd); /* We're done with it for now */
}
return;
ErrorF("(using VT%02d device %s)\n\n", VTnum, vtdevice);
if ((xf86Info.consoleFd = open(vtdevice, O_RDWR | O_NDELAY, 0)) < 0) {
FatalError("xf86OpenConsole: Cannot open %s (%s)\n", vtdevice,
strerror(errno));
}
/* Dispose of stdin and stdout */
if (freopen(vtdevice, "r+", stdin) == (FILE *) NULL) {
FatalError("xf86OpenConsole: Cannot reopen stdin as %s (%s)\n",
vtdevice, strerror(errno));
}
if (freopen(vtname, "r+", stdout) == (FILE *) NULL) {
FatalError("xf86OpenConsole: Cannot reopen stdout as %s (%s)\n",
vtdevice, strerror(errno));
}
/*
* We make 100% sure we use the correct VT number. This can get ugly
* where there are multi-consoles in use, so we make sure we query
* the kernel for the correct VT number. It knows best, we don't.
*/
vidinf.size = sizeof(vidinf);
if (ioctl (xf86Info.consoleFd, CONS_GETINFO, &vidinf) < 0) {
FatalError ("xf86OpenConsole: Failed to query console number (%s)\n",
strerror (errno));
}
xf86Info.vtno = vidinf.m_num;
/* We activate the console just in case its not the one we are on */
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) {
ErrorF("xf86OpenConsole: VT_ACTIVATE failed (%s)\n", strerror(errno));
}
/* Disassociate from controling TTY */
if (!KeepTty) {
setpgrp();
}
/*
* Now we get the current mode that the console device is on. We will
* use this later when we close the console device to restore it to
* that same mode.
*/
if ((sco_console_mode = ioctl(xf86Info.consoleFd, CONS_GET, 0L)) < 0) {
FatalError("xf86OpenConsole: CONS_GET failed on console (%s)\n",
strerror(errno));
}
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0) {
FatalError("xf86OpenConsole: VT_GETMODE failed (%s)\n", strerror(errno));
}
sigvtsw.sa_handler = xf86VTRequest;
sigfillset(&sigvtsw.sa_mask);
sigvtsw.sa_flags = 0;
/* NOTE: Using sigaction means we dont have to re-arm the signal */
sigaction(SIGUSR1, &sigvtsw, NULL);
VT.mode = VT_PROCESS;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
VT.frsig = SIGINT; /* Not implemented */
VT.waitv = 0;
/*
* The SCO X server tries the following call 5 times. Lets do the same
* thing. It shouldn't really be required but sometimes things take a
* while to settle down when switching screens. *helpless shrug* I know
* its sucks but ...
*/
ioctl_ret = 0;
for (i = 0; i < 5; i++) {
ioctl_ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT);
if (ioctl_ret >= 0)
break;
usleep(999999); /* Dont use nap() - it forces linking with -lx */
}
if (ioctl_ret < 0) {
FatalError("xf86OpenConsole: VT_SETMODE failed (%s)\n", strerror(errno));
}
/*
* Convince the console driver we are in graphics mode.
*/
if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) {
ErrorF("Failed to set graphics mode (%s)\n", strerror(errno));
}
} else { /* serverGeneration != 1 */
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) {
ErrorF("xf86OpenConsole: VT_ACTIVATE failed (%s)\n", strerror(errno));
}
}
}
void xf86CloseConsole()
/*
* Restore the console to its previous state. This may cause flicker if
* the screen was previous in a graphics mode, because we first set it
* to text mode. This has the advantage of getting the console driver
* to do a soft reset on the card, which really does help settle the
* video card down again after coming out of Xfree86.
*/
void
xf86CloseConsole()
{
struct vt_mode VT;
struct vt_mode VT;
struct sigaction sigvtsw;
ioctl(xf86Info.consoleFd, VT_RELDISP, 1);
if (sco_console_mode != -1)
{
ioctl(xf86Info.consoleFd, MODESWITCH | sco_console_mode, 0L);
}
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
{
VT.mode = VT_AUTO;
ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
}
close(xf86Info.consoleFd); /* make the vt-manager happy */
return;
/* Set text mode (possibly briefly) */
ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT0);
/* Restore the original mode */
if (sco_console_mode != -1) {
ioctl(xf86Info.consoleFd, MODESWITCH | sco_console_mode, 0L);
}
ioctl(xf86Info.consoleFd, VT_RELDISP, 1); /* Release the display */
sigvtsw.sa_handler = SIG_DFL;
sigfillset(&sigvtsw.sa_mask);
sigvtsw.sa_flags = 0;
sigaction(SIGUSR1, &sigvtsw, NULL);
VT.mode = VT_AUTO;
VT.waitv = 0;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
VT.frsig = SIGINT;
ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* Revert to auto handling */
close(xf86Info.consoleFd); /* We're done with the device */
}
int xf86ProcessArgument(argc, argv, i)
int argc;
char *argv[];
int i;
int
xf86ProcessArgument(int argc, char *argv[], int i)
{
/*
* Keep server from detaching from controlling tty. This is useful
* when debugging (so the server can receive keyboard signals.
*/
if (!strcmp(argv[i], "-keeptty"))
{
KeepTty = TRUE;
return(1);
}
if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
{
if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
{
UseMsg();
VTnum = -1;
return(0);
}
return(1);
}
if (!strcmp(argv[i], "-crt"))
{
if ((++i > argc) ||
(sscanf(argv[i], "/dev/tty%2d", &VTnum) == 0))
{
UseMsg();
VTnum = -1;
return(0);
}
else
{
return(2);
}
}
return(0);
/*
* Keep server from detaching from controlling tty. This is useful
* when debugging (so the server can receive keyboard signals).
*/
if (!strcmp(argv[i], "-keeptty")) {
KeepTty = TRUE;
return(1);
}
/*
* By default, the X server wants to bind itself to CPU 0. This makes
* sure that the server has full access to the I/O ports at IOPL 3.
* Some SMP systems have trouble with I/O on CPU's other than 0. If,
* however, you have a system that is well behaved, you can specify
* this argument and let the scheduler decide which CPU the server
* should run on.
*/
if (!strcmp(argv[i], "-nompxlock")) {
mpxLock = FALSE;
return (1);
}
/*
* Specify the VT number to run on (NOT the device).
*/
if ((argv[i][0] == 'v') && (argv[i][1] == 't')) {
if (sscanf(argv[i], "vt%2d", &VTnum) == 0) {
UseMsg();
VTnum = -1;
return(0);
}
if (VTnum <= 0) {
UseMsg();
VTnum = -1;
return(0);
}
return(1);
}
/*
* Use a device the user specifies.
*/
if (!strcmp(argv[i], "-crt")) {
if (++i > argc) {
UseMsg();
VTnum = -1;
return(0);
} else {
VTnum = -2;
vtdevice = argv[i];
return(2);
}
}
return(0);
}
void xf86UseMsg()
void
xf86UseMsg()
{
ErrorF("vtXX use the specified VT number\n");
ErrorF("-crt /dev/ttyXX use the specified VT number\n");
ErrorF("-crt DEVICE use the specified VT device\n");
ErrorF("-nompxlock dont bind X server to CPU 0\n");
ErrorF("-keeptty ");
ErrorF("don't detach controlling tty (for debugging only)\n");
return;
}

View file

@ -1,117 +1,273 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_io.c,v 3.3 1996/12/23 06:50:49 dawes Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_io.c,v 3.10 2003/02/17 15:11:59 dawes Exp $ */
/*
* Copyright 1993 by David McCullough <davidm@stallion.oz.au>
* Copyright 1993 by David Dawes <dawes@physics.su.oz.au>
* Copyright 2001 by J. Kean Johnston <jkj@sco.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the names of David McCullough and David Dawes
* not be used in advertising or publicity pertaining to distribution of
* the software without specific, written prior permission. David McCullough
* and David Dawes makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID MCCULLOUGH AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL DAVID MCCULLOUGH OR DAVID DAWES BE LIABLE FOR
* ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* documentation, and that the name J. Kean Johnston not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. J. Kean Johnston makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* J. KEAN JOHNSTON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL J. KEAN JOHNSTON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Xorg: sco_io.c,v 1.3 2000/08/17 19:51:29 cpqbld Exp $ */
/* $XConsortium$ */
/* Re-written May 2001 to represent the current state of reality */
#define NEED_EVENTS
#include "X.h"
#include "Xproto.h"
#include "inputstr.h"
#include "scrnintstr.h"
#include "compiler.h"
#include "xf86Procs.h"
#define _NEED_SYSI86
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86OSpriv.h"
#include "xf86_OSlib.h"
#include "xf86_Config.h"
void xf86SoundKbdBell(loudness, pitch, duration)
int loudness;
int pitch;
int duration;
#include <sys/param.h>
#include <sys/emap.h>
#include <sys/nmap.h>
void
xf86SoundKbdBell(int loudness, int pitch, int duration)
{
if (loudness && pitch)
{
ioctl(xf86Info.consoleFd, KIOCSOUND, 1193180 / pitch);
usleep(duration * loudness * 20);
ioctl(xf86Info.consoleFd, KIOCSOUND, 0);
}
if (loudness && pitch) {
ioctl(xf86Info.consoleFd, KIOCSOUND, 1193180 / pitch);
usleep(duration * loudness * 20);
ioctl(xf86Info.consoleFd, KIOCSOUND, 0);
}
}
void xf86SetKbdLeds(leds)
int leds;
void
xf86SetKbdLeds(int leds)
{
/*
* sleep the first time through under SCO. There appears to be a
* timing problem in the driver which causes the keyboard to be lost.
* This sleep stops it from occurring. The sleep could proably be
* a lot shorter as even trace can fix the problem. You may
* prefer a usleep(100).
*/
static int once = 1;
/*
* sleep the first time through under SCO. There appears to be a
* timing problem in the driver which causes the keyboard to be lost.
* This usleep stops it from occurring. NOTE: this was in the old code.
* I am not convinced it is true any longer, but it doesn't hurt to
* leave this in here.
*/
static int once = 1;
if (once)
{
sleep(1);
once = 0;
}
ioctl(xf86Info.consoleFd, KDSETLED, leds );
if (once) {
usleep(100);
once = 0;
}
ioctl(xf86Info.consoleFd, KDSETLED, leds );
}
void xf86MouseInit(mouse)
MouseDevPtr mouse;
int
xf86GetKbdLeds()
{
if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NDELAY)) < 0)
{
if (xf86AllowMouseOpenFail) {
ErrorF("Cannot open mouse (%s) - Continuing...\n",
strerror(errno));
return;
}
FatalError("Cannot open mouse (%s)\n", strerror(errno));
}
int leds;
ioctl (xf86Info.consoleFd, KDGETLED, &leds);
return leds;
}
int xf86MouseOn(mouse)
MouseDevPtr mouse;
/*
* Much of the code in this function is duplicated from the Linux code
* by Orest Zborowski <obz@Kodak.com> and David Dawes <dawes@xfree86.org>.
* Please see the file ../linux/lnx_io.c for full copyright information.
*
* NOTE: Only OpenServer Release 5.0.6 with Release Supplement 5.0.6A
* and later have the required ioctl. 5.0.6A or higher is HIGHLY
* recommended. The console driver is quite a different beast on that OS.
*/
void
xf86SetKbdRepeat(char rad)
{
xf86SetupMouse(mouse);
#if defined(KBIO_SETRATE)
int i;
int value = 0x7f; /* Maximum delay with slowest rate */
int delay = 250; /* Default delay */
int rate = 300; /* Default repeat rate */
/* Flush any pending input */
ioctl(mouse->mseFd, TCFLSH, 0);
static int valid_rates[] = { 300, 267, 240, 218, 200, 185, 171, 160, 150,
133, 120, 109, 100, 92, 86, 80, 75, 67,
60, 55, 50, 46, 43, 40, 37, 33, 30, 27,
25, 23, 21, 20 };
#define RATE_COUNT (sizeof( valid_rates ) / sizeof( int ))
return(mouse->mseFd);
static int valid_delays[] = { 250, 500, 750, 1000 };
#define DELAY_COUNT (sizeof( valid_delays ) / sizeof( int ))
if (xf86Info.kbdRate >= 0)
rate = xf86Info.kbdRate * 10;
if (xf86Info.kbdDelay >= 0)
delay = xf86Info.kbdDelay;
for (i = 0; i < RATE_COUNT; i++)
if (rate >= valid_rates[i]) {
value &= 0x60;
value |= i;
break;
}
for (i = 0; i < DELAY_COUNT; i++)
if (delay <= valid_delays[i]) {
value &= 0x1f;
value |= i << 5;
break;
}
ioctl (xf86Info.consoleFd, KBIO_SETRATE, value);
#endif /* defined(KBIO_SETRATE) */
}
int xf86MouseOff(mouse, doclose)
MouseDevPtr mouse;
Bool doclose;
static Bool use_tcs = TRUE, use_kd = TRUE;
static Bool no_nmap = TRUE, no_emap = TRUE;
static int orig_getsc, orig_kbm;
static struct termios orig_termios;
static keymap_t keymap, noledmap;
static uchar_t *sc_mapbuf;
static uchar_t *sc_mapbuf2;
void
xf86KbdInit()
{
if (mouse->mseFd >= 0)
{
if (mouse->mseType == P_LOGI)
{
write(mouse->mseFd, "U", 1);
xf86SetMouseSpeed(mouse, mouse->baudRate,
mouse->oldBaudRate,
xf86MouseCflags[P_LOGI]);
}
if (doclose)
{
close(mouse->mseFd);
}
}
return(mouse->mseFd);
orig_getsc = 0;
if (ioctl (xf86Info.consoleFd, TCGETSC, &orig_getsc) < 0)
use_tcs = FALSE;
if (ioctl (xf86Info.consoleFd, KDGKBMODE, &orig_kbm) < 0)
use_kd = FALSE;
if (!use_tcs && !use_kd)
FatalError ("xf86KbdInit: Could not determine keyboard mode\n");
/*
* One day this should be fixed to translate normal ASCII characters
* back into scancodes or into events that XFree86 wants, but not
* now. For the time being, we only support scancode mode screens.
*/
if (use_tcs && !(orig_getsc & KB_ISSCANCODE))
FatalError ("xf86KbdInit: Keyboard can not send scancodes\n");
/*
* We need to get the original keyboard map and NUL out the lock
* modifiers. This prevents the scancode API from messing with
* the keyboard LED's. We restore the original map when we exit.
*/
if (ioctl (xf86Info.consoleFd, GIO_KEYMAP, &keymap) < 0) {
FatalError ("xf86KbdInit: Failed to get keyboard map (%s)\n",
strerror(errno));
}
if (ioctl (xf86Info.consoleFd, GIO_KEYMAP, &noledmap) < 0) {
FatalError ("xf86KbdInit: Failed to get keyboard map (%s)\n",
strerror(errno));
} else {
int i, j;
for (i = 0; i < noledmap.n_keys; i++) {
for (j = 0; j < NUM_STATES; j++) {
if (IS_SPECIAL(noledmap, i, j) &&
((noledmap.key[i].map[j] == K_CLK) ||
(noledmap.key[i].map[j] == K_NLK) ||
(noledmap.key[i].map[j] == K_SLK))) {
noledmap.key[i].map[j] = K_NOP;
}
}
}
}
if (ioctl (xf86Info.consoleFd, XCGETA, &orig_termios) < 0) {
FatalError ("xf86KbdInit: Failed to get terminal modes (%s)\n",
strerror(errno));
}
sc_mapbuf = xalloc (10*BSIZE);
sc_mapbuf2 = xalloc(10*BSIZE);
/* Get the emap */
if (ioctl (xf86Info.consoleFd, LDGMAP, sc_mapbuf) < 0) {
if (errno != ENAVAIL) {
FatalError ("xf86KbdInit: Failed to retrieve e-map (%s)\n",
strerror (errno));
}
no_emap = FALSE;
}
/* Get the nmap */
if (ioctl (xf86Info.consoleFd, NMGMAP, sc_mapbuf2) < 0) {
if (errno != ENAVAIL) {
FatalError ("xf86KbdInit: Failed to retrieve n-map (%s)\n",
strerror (errno));
}
no_nmap = FALSE;
}
}
int
xf86KbdOn()
{
struct termios newtio;
ioctl (xf86Info.consoleFd, LDNMAP); /* Turn e-mapping off */
ioctl (xf86Info.consoleFd, NMNMAP); /* Turn n-mapping off */
newtio = orig_termios; /* structure copy */
newtio.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
newtio.c_oflag = 0;
newtio.c_cflag = CREAD | CS8 | B9600;
newtio.c_lflag = 0;
newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=1;
cfsetispeed(&newtio, 9600);
cfsetospeed(&newtio, 9600);
ioctl(xf86Info.consoleFd, XCSETA, &newtio);
/* Now tell the keyboard driver to send us raw scancodes */
if (use_tcs) {
int nm = orig_getsc;
nm &= ~KB_XSCANCODE;
ioctl (xf86Info.consoleFd, TCSETSC, &nm);
}
if (use_kd)
ioctl (xf86Info.consoleFd, KDSKBMODE, K_RAW);
ioctl (xf86Info.consoleFd, PIO_KEYMAP, &noledmap);
return(xf86Info.consoleFd);
}
int
xf86KbdOff()
{
/* Revert back to original translate scancode mode */
if (use_tcs)
ioctl (xf86Info.consoleFd, TCSETSC, &orig_getsc);
if (use_kd)
ioctl (xf86Info.consoleFd, KDSKBMODE, orig_kbm);
ioctl (xf86Info.consoleFd, PIO_KEYMAP, &keymap);
if (no_emap)
ioctl (xf86Info.consoleFd, LDSMAP, sc_mapbuf);
if (no_nmap)
ioctl (xf86Info.consoleFd, NMSMAP, sc_mapbuf2);
ioctl(xf86Info.consoleFd, XCSETA, &orig_termios);
return(xf86Info.consoleFd);
}
#include "xf86OSKbd.h"
Bool
xf86OSKbdPreInit(InputInfoPtr pInfo)
{
return FALSE;
}

View file

@ -1,175 +1,265 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c,v 3.8 1996/12/23 06:50:50 dawes Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c,v 3.13 2002/11/20 23:07:50 dawes Exp $ */
/*
* Copyright 2001 by J. Kean Johnston <jkj@sco.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name J. Kean Johnston not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. J. Kean Johnston makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* J. KEAN JOHNSTON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL J. KEAN JOHNSTON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XConsortium$ */
/* $Xorg: sco_mouse.c,v 1.3 2000/08/17 19:51:29 cpqbld Exp $ */
/******************************************************************************/
#define NEED_EVENTS
#include "X.h"
#include "Xproto.h"
#include "inputstr.h"
#include "scrnintstr.h"
#include "compiler.h"
#include "xf86.h"
#include "xf86Procs.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
#include "xf86Xinput.h"
#include "xf86OSmouse.h"
#include "mipointer.h"
#include <sys/event.h>
#include <mouse.h>
/******************************************************************************/
#ifdef USE_OSMOUSE
/******************************************************************************/
#include <sys/event.h>
#include <mouse.h>
#include "xf86_Config.h"
static dmask_t real_mask = (dmask_t) (D_REL | D_BUTTON);
static int config_buttons = 0;
extern int miPointerGetMotionEvents(DeviceIntPtr pPtr, xTimecoord *coords,
unsigned long start, unsigned long stop,
ScreenPtr pScreen);
/******************************************************************************/
/*
* Handle any XF86Config options for "OsMouse", How you treat errors
* is up to you, they may or may not be Fatal
*/
void
xf86OsMouseOption(lt, lp)
int lt; /* type returned by gettoken */
pointer lp; /* The lexical return symbol */
static int
SupportedInterfaces (void)
{
if (lt != NUMBER) {
ErrorF("%s: Invalid Argument to OsMouse, %s\n",
"xf86OsMouseOption", "Number of buttons expected");
return;
}
config_buttons = ((LexPtr)lp)->num;
/* FIXME: Is this correct? Should we just return MSE_MISC? */
return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_MISC | MSE_AUTO;
}
/******************************************************************************/
/*
* xf86OsMouseProc --
* Handle the initialization, etc. of a mouse
*/
static const char *internalNames[] = {
"OSMouse",
NULL
};
int
xf86OsMouseProc(pPointer, what)
DeviceIntPtr pPointer;
int what;
static const char **
BuiltinNames (void)
{
unchar *map;
int i, err, buttons;
struct devinfo *dip;
dmask_t dmask;
return internalNames;
}
static Bool
CheckProtocol (const char *protocol)
{
int i;
for (i = 0; internalNames[i]; i++) {
if (xf86NameCmp (protocol, internalNames[i]) == 0)
return TRUE;
}
return FALSE;
}
static const char *
DefaultProtocol (void)
{
return "OSMouse";
}
static const char *
evtErrStr (int evterr)
{
switch (evterr) {
case -1: return "error in config files";
case -2: return "no mouse devices to attach";
case -3: return "unable to open device";
case -4: return "unable to open event queue";
case -999: return "unable to initialize event driver";
default: return "unknown event driver error";
}
}
static int
OsMouseProc (DeviceIntPtr pPointer, int what)
{
InputInfoPtr pInfo;
MouseDevPtr pMse;
unsigned char map[9];
dmask_t dmask;
MessageType from = X_CONFIG;
int evi;
pInfo = pPointer->public.devicePrivate;
pMse = pInfo->private;
pMse->device = pPointer;
switch (what) {
case DEVICE_INIT:
pPointer->public.on = FALSE;
case DEVICE_INIT:
pPointer->public.on = FALSE;
if (ev_init() < 0)
ErrorF("ev_init: Failed to initialize event driver\n");
dmask = real_mask;
xf86Info.mouseDev->mseFd = ev_open(&dmask);
switch (xf86Info.mouseDev->mseFd) {
case -1: FatalError("ev_open: Error in Configuration files\n");
case -2: FatalError("ev_open: No mouse devices to attach\n");
case -3: FatalError("ev_open: Unable to open a found device\n");
case -4: FatalError("ev_open: unable to open an event queue\n");
default:
if (xf86Info.mouseDev->mseFd < 0)
FatalError("ev_open: Failed to open device, reason unkown\n");
break;
}
if (dmask != real_mask)
FatalError("Could not attach the mouse device (0x%x)\n", dmask);
dip = (struct devinfo *) NULL;
if ((dip = ev_getdev(D_REL, dip)) == (struct devinfo *) NULL)
FatalError("Could not find info on mouse device\n");
buttons = config_buttons > 0 ? config_buttons : ((int) dip->buttons);
buttons = buttons > 0 ? buttons : 3; /* just in case */
ErrorF("%s OsMouse has %d buttons\n",
buttons == config_buttons ? XCONFIG_GIVEN : XCONFIG_PROBED,
buttons);
map = (unchar *) xalloc(buttons + 1);
if (map == (unchar *) NULL)
FatalError("Failed to allocate OsMouse map structure\n");
for (i = 1; i <= buttons; i++)
map[i] = i;
InitPointerDeviceStruct((DevicePtr)pPointer,
map,
buttons,
miPointerGetMotionEvents,
(PtrCtrlProcPtr)xf86MseCtrl,
0);
xfree(map);
ev_suspend(); /* suspend device until its turned on */
break;
case DEVICE_ON:
ev_resume();
AddEnabledDevice(xf86Info.mouseDev->mseFd);
xf86Info.mouseDev->lastButtons = 0;
xf86Info.mouseDev->emulateState = 0;
pPointer->public.on = TRUE;
break;
case DEVICE_CLOSE:
case DEVICE_OFF:
pPointer->public.on = FALSE;
RemoveEnabledDevice(xf86Info.mouseDev->mseFd);
if (what == DEVICE_CLOSE) {
ev_close();
xf86Info.mouseDev->mseFd = -1;
} else
ev_suspend();
break;
dmask = D_REL | D_BUTTON;
if ((evi = ev_init()) < 0) {
FatalError ("OsMouseProc: Event driver initialization failed (%s)\n",
evtErrStr(evi));
}
pInfo->fd = ev_open (&dmask);
if (pInfo->fd < 0) {
FatalError ("OsMouseProc: DEVICE_INIT failed (%s)\n", evtErrStr(pInfo->fd));
}
pMse->buttons = xf86SetIntOption (pInfo->options, "Buttons", 0);
if (pMse->buttons == 0) {
pMse->buttons = 8;
from = X_DEFAULT;
}
xf86Msg (from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons);
map[1] = 1;
map[2] = 2;
map[3] = 3;
map[4] = 6;
map[5] = 7;
map[6] = 8;
map[7] = 4;
map[8] = 5; /* Compatibile with SCO X server */
InitPointerDeviceStruct((DevicePtr)pPointer, map, 8,
miPointerGetMotionEvents, pMse->Ctrl,
miPointerGetMotionBufferSize());
/* X valuator */
xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
xf86InitValuatorDefaults(pPointer, 0);
/* Y valuator */
xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
xf86InitValuatorDefaults(pPointer, 1);
xf86MotionHistoryAllocate(pInfo);
ev_flush();
ev_suspend();
break;
case DEVICE_ON:
pMse->lastButtons = 0;
pMse->emulateState = 0;
pPointer->public.on = TRUE;
ev_resume();
AddEnabledDevice (pInfo->fd);
break;
case DEVICE_OFF:
case DEVICE_CLOSE:
pPointer->public.on = TRUE;
RemoveEnabledDevice (pInfo->fd);
if (what == DEVICE_CLOSE) {
ev_close();
pInfo->fd = -1;
} else {
ev_suspend();
}
break;
}
return Success;
}
/******************************************************************************/
/*
* xf86OsMouseEvents --
* Get some events from our queue. Process all outstanding events now.
*/
void
xf86OsMouseEvents()
static void
OsMouseReadInput (InputInfoPtr pInfo)
{
EVENT *evp;
static long time = -1;
MouseDevPtr pMse;
EVENT *evp;
while ((evp = ev_read()) != (EVENT *) NULL ) {
#if DEBUG
if (time == -1)
time = EV_TIME(*evp);
ErrorF("sco_event time(%ld) tag(%d) butts(%d) x(%ld) y(%ld)\n",
EV_TIME(*evp) - time, EV_TAG(*evp), EV_BUTTONS(*evp),
EV_DX(*evp), EV_DY(*evp));
#endif
xf86PostMseEvent(xf86Info.pMouse,EV_BUTTONS(*evp), EV_DX(*evp), -(EV_DY(*evp)));
ev_pop();
}
pMse = pInfo->private;
xf86Info.inputPending = TRUE;
while ((evp = ev_read()) != (EVENT *)0) {
int buttons = EV_BUTTONS(*evp);
int dx = EV_DX(*evp), dy = -(EV_DY(*evp)), dz = 0, dw = 0;
if (EV_TAG(*evp) & T_WHEEL) {
dz = (dy & 0x08) ? (dy & 0x0f) - 16 : (dy & 0x0f);
dx = dy = 0;
pMse->PostEvent (pInfo, buttons, dx, dy, dz, dw);
/* Simulate button release */
dz = 0;
buttons &= ~(WHEEL_FWD | WHEEL_BACK);
}
pMse->PostEvent (pInfo, buttons, dx, dy, dz, dw);
ev_pop();
}
}
/******************************************************************************/
#endif /* USE_OSMOUSE */
/******************************************************************************/
static Bool
OsMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags)
{
MouseDevPtr pMse;
/* This is called when the protocol is "OSMouse". */
pMse = pInfo->private;
pMse->protocol = protocol;
xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
/* Collect the options, and process the common options. */
xf86CollectInputOptions(pInfo, NULL, NULL);
xf86ProcessCommonOptions(pInfo, pInfo->options);
/* Check if the device can be opened. */
pInfo->fd = ev_init();
if (pInfo->fd != -1) {
dmask_t dmask = (D_REL | D_BUTTON);
pInfo->fd = ev_open(&dmask);
} else {
pInfo->fd = -999;
}
if (pInfo->fd < 0) {
if (xf86GetAllowMouseOpenFail())
xf86Msg(X_WARNING, "%s: cannot open event manager (%s)\n",
pInfo->name, evtErrStr(pInfo->fd));
else {
xf86Msg(X_ERROR, "%s: cannot open event manager (%s)\n",
pInfo->name, evtErrStr(pInfo->fd));
xfree(pMse);
return FALSE;
}
}
ev_close();
pInfo->fd = -1;
/* Process common mouse options (like Emulate3Buttons, etc). */
pMse->CommonOptions(pInfo);
/* Setup the local procs. */
pInfo->device_control = OsMouseProc;
pInfo->read_input = OsMouseReadInput;
pInfo->flags |= XI86_CONFIGURED;
return TRUE;
}
OSMouseInfoPtr
xf86OSMouseInit (int flags)
{
OSMouseInfoPtr p;
p = xcalloc(sizeof(OSMouseInfoRec), 1);
if (!p)
return NULL;
p->SupportedInterfaces = SupportedInterfaces;
p->BuiltinNames = BuiltinNames;
p->DefaultProtocol = DefaultProtocol;
p->CheckProtocol = CheckProtocol;
p->PreInit = OsMousePreInit;
return p;
}

View file

@ -1,29 +1,41 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_video.c,v 3.2.2.1 1997/07/19 04:59:31 dawes Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_video.c,v 3.8 2002/06/03 21:22:10 dawes Exp $ */
/*
* Copyright 1993 by David McCullough <davidm@stallion.oz.au>
* Copyright 1993 by David Wexelblat <dwex@goblin.org>
* Copyright 2001 by J. Kean Johnston <jkj@sco.com>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the names of David McCullough and David Wexelblat
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. David McCullough and
* David Wexelblat makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID MCCULLOUGH AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL DAVID MCCULLOUGH OR DAVID WEXELBLAT BE
* LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* documentation, and that the name J. Kean Johnston not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. J. Kean Johnston makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* J. KEAN JOHNSTON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL J. KEAN JOHNSTON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XConsortium$ */
/* Re-written May 2001 to represent the current state of reality */
/*
* This file contains the completely re-written SCO OpenServer video
* routines for XFree86 4.x. Much of this is based on the SCO X server
* code (which is an X11R5 server) and will probably only work on
* OpenServer versions 5.0.5, 5.0.6 and later. Please send me (jkj@sco.com)
* email if you have any questions.
*
* Ideally, you should use OSR5.0.6A or later, with the updated console
* driver for 5.0.6A (its the default driver in 5.0.7 and later).
* However, if you are running on an older system, this code will detect
* that and adjust accordingly.
*/
/* $Xorg: sco_video.c,v 1.3 2000/08/17 19:51:29 cpqbld Exp $ */
#include "X.h"
#include "input.h"
@ -32,253 +44,248 @@
#define _NEED_SYSI86
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86OSpriv.h"
#include "xf86_OSlib.h"
#include <sys/ci/ciioctl.h>
#define MPXNAME "/dev/atp1"
#define BASECPU 1
Bool mpxLock = TRUE;
#define USE_VASMETHOD 1
/***************************************************************************/
/* Video Memory Mapping section */
/***************************************************************************/
static struct kd_memloc MapDSC[MAXSCREENS][NUM_REGIONS];
static int ver_once = 1;
static int sco_mcdone = 0, sco_ismc = 0;
/***************************************************************************/
/*
* To map the video-memory, we use the MAP_CLASS ioctl.
* Different drivers may have to do another one of these
* for their own special registers (ie., ATI). To find
* out which strings are valid look in /etc/conf/pack.d/cn/class.h
* To map the video memory, we first need to see if we are on a multi-console
* system. If we are, we need to try to use an existing video class in the
* kernel. We do this by retrieving the list of currently defined classes
* (via the new CONS_GETCLASS ioctl()) to see if we have a class that will
* match the range of memory we desire. If we can't find one, we have an
* error and we abort.
*
* if we fail to find one of these we try for the dmmap driver
* If we are not using a multi-console, we can simply use mmap() to map in
* the frame buffer, using the classs-access method as a fall-back only if
* the mmap() fails (it shouldn't). We always set the appropriate pointers
* in the config structure to point ot the right function to map and unmap
* the video memory. An alternative to using mmap() is to use the new
* CONS_ADDVAS call, which will use vasmalloc() and vasbind() in the kernel
* to map the physical address to a virtual one, which it then returns.
* I am not 100% sure if this is faster or not, but it may prove easier to
* debug things. Just to be on the safe side, I have included both methods
* here, and the mmap() method can be used by setting USE_VASMETHOD to 0
* above.
*/
struct {
unsigned long base, size;
char *class;
} SCO_Mapping[] = {
{0xA0000, 0x10000, "VGA"},
{0xA0000, 0x20000, "SVGA"},
{0xB0000, 0x08000, "HGA"},
{0x0, 0x0, ""},
#if !defined(CONS_ADDVAS)
# undef USE_VASMETHOD
# define USE_VASMETHOD 0
#endif
static int
scoIsMultiConsole (void)
{
int x;
if (sco_mcdone)
return sco_ismc;
x = access ("/usr/lib/vidconf/.multiconsole", F_OK);
if (x == 0)
sco_ismc = 1;
sco_mcdone = 1;
return sco_ismc;
}
/*
* This maps memory using mmap()
*/
static pointer
mapVidMemMMAP(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
{
int fd;
unsigned long realBase, alignOff;
pointer base;
fd = open (DEV_MEM, O_RDWR);
if (fd < 0) {
FatalError("xf86MapVidMem: failed to open %s (%s)\n", DEV_MEM,
strerror(errno));
return 0; /* NOTREACHED */
}
realBase = Base & ~(getpagesize() - 1);
alignOff = Base - realBase;
#ifdef DEBUG
ErrorF("base: %lx, realBase: %lx, alignOff: %lx\n", Base,realBase,alignOff);
#endif
base = mmap((caddr_t)0, Size + alignOff, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, (off_t)realBase);
close(fd);
if (base == MAP_FAILED) {
FatalError("xf86MapVidMem: Could not mmap framebuffer (0x%08x,0x%x) (%s)\n",
Base, Size, strerror(errno));
return 0; /* NOTREACHED */
}
#ifdef DEBUG
ErrorF("base: %lx aligned base: %lx\n",base, base + alignOff);
#endif
return (pointer)((char *)base + alignOff);
}
#if (USE_VASMETHOD)
/*
* This maps memory using the virtual address space (VAS) console calls.
*/
static pointer
mapVidMemVAS(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
{
struct vidvasmem vas;
pointer base;
vas.base = (long)Base;
vas.size = (long)Size;
base = (pointer)ioctl (xf86Info.consoleFd, CONS_ADDVAS, &vas);
if (base == (pointer)-1) {
return mapVidMemMMAP(ScreenNum, Base, Size, flags);
}
return base;
}
#endif /* USE_VASMETHOD */
struct vidclass vidclasslist[] = {
{ "VBE", "", 0xf0000000, 0x2000000, 0 },
{ "P9000", "", 0xc0000000, 0x400000, 0 },
{ "TULIP", "", 0x80000000, 0x400000, 0 },
{ "VIPER", "", 0xa0000000, 0x400000, 0 },
{ "S3T", "", 0xa0000000, 0x200000, 0 },
{ "S3DT", "", 0x4000000, 0x400000, 0 },
{ "MGA", "", 0x2200000, 0x4000, 0 },
{ "CLVGA", "", 0xa0000, 0x20000, 0 },
{ "OLIVE", "", 0xd8000000, 0x400000, 0 },
{ "S3C", "", 0xa0000, 0x10000, 0 },
{ "MGAVLB", "", 0xac000, 0x34000, 0 },
{ "ATI8514", "", 0xFF000, 0x1000, 0 },
{ "GXREGS", "", 0xb0000, 0x10000, 0 },
{ "GX", "", 0xa0000, 0x10000, 0 },
{ "CT64300", "", 0xa0000000, 0x400000, 0 },
{ "SVGA", "", 0xa0000, 0x20000, 0 },
{ "S3V", "", 0xa0000000, 0x400000, 0 },
{ "8514A", "", 0xFF000, 0x1000, 0 },
{ "VGA", "", 0xa0000, 0x10000, 0 },
{ 0 }
};
/* ARGSUSED */
pointer xf86MapVidMem(ScreenNum, Region, Base, Size)
int ScreenNum;
int Region;
pointer Base;
unsigned long Size;
static pointer
mapVidMemVC(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
{
int i;
char *class = (char *)NULL;
pointer base;
struct vidclass *vcp;
char *class = NULL;
pointer base;
for (i=0; SCO_Mapping[i].base != 0; i++)
{
if (((pointer)SCO_Mapping[i].base == Base) &&
(SCO_Mapping[i].size == Size))
{
class = SCO_Mapping[i].class;
break;
}
}
if (class == (char *)NULL)
{
int fd;
for (vcp = vidclasslist; vcp->name; vcp++) {
if ((vcp->base == Base) && (vcp->size == Size)) {
class = vcp->name;
break;
}
}
#if defined(SVR4) || defined(SCO325)
if ((fd = open(DEV_MEM, O_RDWR)) < 0)
{
FatalError("xf86MapVidMem: failed to open %s (%s)\n",
DEV_MEM, strerror(errno));
}
base = (pointer)mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, (off_t)Base);
close(fd);
if ((long)base == -1)
{
FatalError("%s: Could not mmap framebuffer [s=%x,a=%x] (%s)\n",
"xf86MapVidMem", Size, Base, strerror(errno));
}
return(base);
#else
MapDSC[ScreenNum][Region].vaddr = (char *) NULL;
MapDSC[ScreenNum][Region].physaddr = (char *) Base;
MapDSC[ScreenNum][Region].length = Size;
MapDSC[ScreenNum][Region].ioflg = 1;
if ((fd = open("/dev/dmmap", O_RDWR)) >= 0) {
if (ioctl(fd, KDMAPDISP, &MapDSC[ScreenNum][Region]) == -1)
ErrorF("xf86MapVidMem: dmmap KDMAPDISP failed (%s)\n",
strerror(errno));
else {
if (ver_once)
ErrorF("Using dmmap version 0x%04x.\n",
ioctl(fd, -1));
ver_once = 0;
close(fd);
return(MapDSC[ScreenNum][Region].vaddr);
}
close(fd);
}
FatalError("xf86MapVidMem:No class map defined for (%x,%x)\n",
Base, Size);
/* NOTREACHED */
if (class == NULL) {
/*
* As a fall-back, we will try and use the mmap() approach. This may
* prove to be the wrong thing to do, but time and testing will tell.
*/
ErrorF("xf86MapVidMem: No class map defined for (0x%08x,0x%08x)\n", Base, Size);
#if USE_VASMETHOD
return mapVidMemVAS(ScreenNum, Base, Size, flags);
#else /* !USE_VASMETHOD */
return mapVidMemMMAP(ScreenNum, Base, Size, flags);
#endif
}
}
base = (pointer)ioctl(xf86Info.consoleFd, MAP_CLASS, class);
if ((int)base == -1)
{
FatalError("xf86MapVidMem:Failed to map video mem class %s\n",
class);
/* NOTREACHED */
}
return(base);
/*
* We found a suitable class. Try and use it.
*/
base = (pointer)ioctl(xf86Info.consoleFd, MAP_CLASS, class);
if ((int)base == -1) {
FatalError("xf86MapVidMem: Failed to map video memory class `%s'\n", class);
return 0; /* NOTREACHED */
}
return base;
}
/*
* Nothing to do here if it wasn't mapped using the dmmap driver
* Unmapping the video memory is easy. We always call munmap(), as it is
* safe to do so even if we haven't actually mapped in any pages via mmap().
* In the case where we used the video class, we don't need to do anything
* as the kernel will clean up the TSS when we exit, and will undo the
* vasbind() that was done when the class was originally mapped. If we used
* vasmap, we simply undo the map. Again, it is benign to call vasunmap
* even if we got the frame buffer via some other mechanism (like mmap).
*/
/* ARGSUSED */
void xf86UnMapVidMem(ScreenNum, Region, Base, Size)
int ScreenNum;
int Region;
pointer Base;
unsigned long Size;
{
int fd;
#if defined (SVR4) || defined(SCO325)
munmap(Base, Size);
#else /* SVR4 */
if (MapDSC[ScreenNum][Region].vaddr) {
if ((fd = open("/dev/dmmap", O_RDWR)) < 0) {
if (ioctl(fd, KDUNMAPDISP, &MapDSC[ScreenNum][Region]) == -1)
ErrorF("xf86UnMapVidMem: dmmap KDUNMAPDISP failed (%s)\n",
strerror(errno));
close(fd);
}
MapDSC[ScreenNum][Region].vaddr = (char *) NULL;
MapDSC[ScreenNum][Region].physaddr = (char *) NULL;
MapDSC[ScreenNum][Region].length = 0;
MapDSC[ScreenNum][Region].ioflg = 0;
}
#endif
return;
static void
unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
{
#if USE_VASMETHOD
struct vidvasmem vas;
int x;
vas.base = (long)Base;
vas.size = (long)Size;
x = ioctl (xf86Info.consoleFd, CONS_DELVAS, &vas);
if (x == 0)
return;
#endif /* USE_VASMETHOD */
munmap(Base, Size);
}
/* ARGSUSED */
Bool xf86LinearVidMem()
/*
* Set things up to point to our local functions. When the kernel gets
* MTRR support, we will need to add the required functions for that
* here too. MTRR support will most likely appear in 5.0.8 or 5.1.0.
*
* We also want to lock the X server process to the base CPU in an MPX
* system, since we will be going to IOPL 3. Most engine drivers can cope
* with I/O access on any CPU but there are a few (AST Manhattan I believe)
* that can't, so the server needs to be locked to CPU0.
*/
void
xf86OSInitVidMem(VidMemInfoPtr pVidMem)
{
int fd, ver;
int mpx_fd;
#if defined(SVR4) || defined(SCO325)
return TRUE;
if (scoIsMultiConsole ()) {
pVidMem->mapMem = mapVidMemVC;
} else {
#if USE_VASMETHOD
pVidMem->mapMem = mapVidMemVAS;
#else
if ((fd = open("/dev/dmmap", O_RDWR)) >= 0) {
ver = ioctl(fd, -1);
close(fd);
if (ver >= 0) {
if (ver_once)
ErrorF("Using dmmap version 0x%04x.\n", ver);
ver_once = 0;
return(TRUE);
}
}
return(FALSE);
pVidMem->mapMem = mapVidMemMMAP;
#endif
}
pVidMem->unmapMem = unmapVidMem;
pVidMem->linearSupported = TRUE;
pVidMem->initialised = TRUE;
if (mpxLock && (mpx_fd = open (MPXNAME, O_RDONLY)) > 0) {
if (ioctl (mpx_fd, ACPU_XLOCK, BASECPU) < 0)
ErrorF ("xf86OSInitVidMem: Can not bind to CPU 0 (%s)\n",
strerror(errno));
close (mpx_fd);
}
}
/***************************************************************************/
/* I/O Permissions section */
/***************************************************************************/
static Bool ScreenEnabled[MAXSCREENS];
static Bool IOEnabled = FALSE;
static Bool InitDone = FALSE;
void xf86ClearIOPortList(ScreenNum)
int ScreenNum;
{
int i;
if (!InitDone)
{
for (i = 0; i < MAXSCREENS; i++)
ScreenEnabled[i] = FALSE;
InitDone = TRUE;
}
}
/* ARGSUSED */
void xf86AddIOPorts(ScreenNum, NumPorts, Ports)
int ScreenNum;
int NumPorts;
unsigned *Ports;
{
}
void xf86EnableIOPorts(ScreenNum)
int ScreenNum;
{
ScreenEnabled[ScreenNum] = TRUE;
if (IOEnabled)
return;
if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0)
FatalError("Failed to set IOPL for extended I/O\n");
IOEnabled = TRUE;
return;
}
void xf86DisableIOPorts(ScreenNum)
int ScreenNum;
{
int i;
ScreenEnabled[ScreenNum] = FALSE;
if (!IOEnabled)
return;
for (i = 0; i < MAXSCREENS; i++)
if (ScreenEnabled[i])
return;
sysi86(SI86V86, V86SC_IOPL, 0);
IOEnabled = FALSE;
return;
}
void xf86DisableIOPrivs()
{
if (IOEnabled)
sysi86(SI86V86, V86SC_IOPL, 0);
return;
}
/***************************************************************************/
/* Interrupt Handling section */
/***************************************************************************/
Bool xf86DisableInterrupts()
{
#ifdef __GNUC__
__asm__ __volatile__("cli");
#else
asm("cli");
#endif /* __GNUC__ */
return(TRUE);
}
void xf86EnableInterrupts()
{
#ifdef __GNUC__
__asm__ __volatile__("sti");
#else
asm("sti");
#endif /* __GNUC__ */
return;
}