diff options
Diffstat (limited to 'hw/xfree86/os-support/sco')
-rw-r--r-- | hw/xfree86/os-support/sco/VTsw_sco.c | 110 | ||||
-rw-r--r-- | hw/xfree86/os-support/sco/sco_init.c | 503 | ||||
-rw-r--r-- | hw/xfree86/os-support/sco/sco_io.c | 328 | ||||
-rw-r--r-- | hw/xfree86/os-support/sco/sco_mouse.c | 384 | ||||
-rw-r--r-- | hw/xfree86/os-support/sco/sco_video.c | 457 |
5 files changed, 1059 insertions, 723 deletions
diff --git a/hw/xfree86/os-support/sco/VTsw_sco.c b/hw/xfree86/os-support/sco/VTsw_sco.c index 386cd21ff..d06bd3949 100644 --- a/hw/xfree86/os-support/sco/VTsw_sco.c +++ b/hw/xfree86/os-support/sco/VTsw_sco.c @@ -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(); + + 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); - } + return TRUE; + } } diff --git a/hw/xfree86/os-support/sco/sco_init.c b/hw/xfree86/os-support/sco/sco_init.c index a61dcdfce..389664647 100644 --- a/hw/xfree86/os-support/sco/sco_init.c +++ b/hw/xfree86/os-support/sco/sco_init.c @@ -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", + 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"); + } + + /* + * 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 */ + } + + 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)); - } - - 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)); - } + } + /* Dispose of stdin and stdout */ + if (freopen(vtdevice, "r+", stdin) == (FILE *) NULL) { + FatalError("xf86OpenConsole: Cannot reopen stdin as %s (%s)\n", + vtdevice, strerror(errno)); } - else - { - /* serverGeneration != 1 */ - /* - * now get the VT - */ - if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) - { - ErrorF("xf86OpenConsole: VT_ACTIVATE failed\n"); - } + + if (freopen(vtname, "r+", stdout) == (FILE *) NULL) { + FatalError("xf86OpenConsole: Cannot reopen stdout as %s (%s)\n", + vtdevice, strerror(errno)); } - return; -} -void xf86CloseConsole() -{ - struct vt_mode VT; + /* + * 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; - ioctl(xf86Info.consoleFd, VT_RELDISP, 1); - if (sco_console_mode != -1) - { - ioctl(xf86Info.consoleFd, MODESWITCH | sco_console_mode, 0L); + /* 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)); } - if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) - { - VT.mode = VT_AUTO; - ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */ + + /* 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)); } - close(xf86Info.consoleFd); /* make the vt-manager happy */ - return; + + 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)); + } + } } -int xf86ProcessArgument(argc, argv, i) -int argc; -char *argv[]; -int i; +/* + * 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() { - /* - * 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); + struct vt_mode VT; + struct sigaction sigvtsw; + + /* 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(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); + } + + /* + * 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; } diff --git a/hw/xfree86/os-support/sco/sco_io.c b/hw/xfree86/os-support/sco/sco_io.c index 162d1b76b..a018e3434 100644 --- a/hw/xfree86/os-support/sco/sco_io.c +++ b/hw/xfree86/os-support/sco/sco_io.c @@ -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); + } +} + +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 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) { + usleep(100); + once = 0; + } + + ioctl(xf86Info.consoleFd, KDSETLED, leds ); +} + +int +xf86GetKbdLeds() { - if (loudness && pitch) - { - ioctl(xf86Info.consoleFd, KIOCSOUND, 1193180 / pitch); - usleep(duration * loudness * 20); - ioctl(xf86Info.consoleFd, KIOCSOUND, 0); - } + int leds; + + ioctl (xf86Info.consoleFd, KDGETLED, &leds); + return leds; +} + +/* + * 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) +{ +#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 */ + + 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 )) + + 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) */ } -void xf86SetKbdLeds(leds) -int leds; +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() { - /* - * 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; - - if (once) - { - sleep(1); - once = 0; - } - ioctl(xf86Info.consoleFd, KDSETLED, leds ); + 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; + } } -void xf86MouseInit(mouse) -MouseDevPtr mouse; +int +xf86KbdOn() { - 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)); - } + 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 xf86MouseOn(mouse) -MouseDevPtr mouse; +int +xf86KbdOff() { - xf86SetupMouse(mouse); + /* 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); - /* Flush any pending input */ - ioctl(mouse->mseFd, TCFLSH, 0); + if (no_emap) + ioctl (xf86Info.consoleFd, LDSMAP, sc_mapbuf); + if (no_nmap) + ioctl (xf86Info.consoleFd, NMSMAP, sc_mapbuf2); - return(mouse->mseFd); + ioctl(xf86Info.consoleFd, XCSETA, &orig_termios); + + return(xf86Info.consoleFd); } -int xf86MouseOff(mouse, doclose) -MouseDevPtr mouse; -Bool doclose; +#include "xf86OSKbd.h" + +Bool +xf86OSKbdPreInit(InputInfoPtr pInfo) { - 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); + return FALSE; } diff --git a/hw/xfree86/os-support/sco/sco_mouse.c b/hw/xfree86/os-support/sco/sco_mouse.c index 564852ae3..37b9eb5a8 100644 --- a/hw/xfree86/os-support/sco/sco_mouse.c +++ b/hw/xfree86/os-support/sco/sco_mouse.c @@ -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 $ */ - - - - - -/* $Xorg: sco_mouse.c,v 1.3 2000/08/17 19:51:29 cpqbld 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$ */ -#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 -/******************************************************************************/ +static int +SupportedInterfaces (void) +{ + /* FIXME: Is this correct? Should we just return MSE_MISC? */ + return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_MISC | MSE_AUTO; +} -#include <sys/event.h> -#include <mouse.h> -#include "xf86_Config.h" +static const char *internalNames[] = { + "OSMouse", + NULL +}; -static dmask_t real_mask = (dmask_t) (D_REL | D_BUTTON); -static int config_buttons = 0; +static const char ** +BuiltinNames (void) +{ + return internalNames; +} -extern int miPointerGetMotionEvents(DeviceIntPtr pPtr, xTimecoord *coords, - unsigned long start, unsigned long stop, - ScreenPtr pScreen); +static Bool +CheckProtocol (const char *protocol) +{ + int i; -/******************************************************************************/ -/* - * Handle any XF86Config options for "OsMouse", How you treat errors - * is up to you, they may or may not be Fatal - */ + for (i = 0; internalNames[i]; i++) { + if (xf86NameCmp (protocol, internalNames[i]) == 0) + return TRUE; + } -void -xf86OsMouseOption(lt, lp) - int lt; /* type returned by gettoken */ - pointer lp; /* The lexical return symbol */ + return FALSE; +} + +static const char * +DefaultProtocol (void) { - if (lt != NUMBER) { - ErrorF("%s: Invalid Argument to OsMouse, %s\n", - "xf86OsMouseOption", "Number of buttons expected"); - return; - } - config_buttons = ((LexPtr)lp)->num; + return "OSMouse"; } -/******************************************************************************/ -/* - * xf86OsMouseProc -- - * Handle the initialization, etc. of a mouse - */ +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"; + } +} -int -xf86OsMouseProc(pPointer, what) - DeviceIntPtr pPointer; - int what; +static int +OsMouseProc (DeviceIntPtr pPointer, int what) { - unchar *map; - int i, err, buttons; - struct devinfo *dip; - dmask_t dmask; + 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; - - 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; + case DEVICE_INIT: + pPointer->public.on = FALSE; + + 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. - */ +static void +OsMouseReadInput (InputInfoPtr pInfo) +{ + MouseDevPtr pMse; + EVENT *evp; + + pMse = pInfo->private; + + 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(); + } +} -void -xf86OsMouseEvents() +static Bool +OsMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags) { - EVENT *evp; - static long time = -1; - - 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(); - } - - xf86Info.inputPending = TRUE; + 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; } -/******************************************************************************/ -#endif /* USE_OSMOUSE */ -/******************************************************************************/ +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; +} diff --git a/hw/xfree86/os-support/sco/sco_video.c b/hw/xfree86/os-support/sco/sco_video.c index 14947fa85..eb4b80c48 100644 --- a/hw/xfree86/os-support/sco/sco_video.c +++ b/hw/xfree86/os-support/sco/sco_video.c @@ -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. + * 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. * - * 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. + * 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 -/* ARGSUSED */ -pointer xf86MapVidMem(ScreenNum, Region, Base, Size) -int ScreenNum; -int Region; -pointer Base; -unsigned long Size; +static int +scoIsMultiConsole (void) { - int i; - char *class = (char *)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; - -#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 */ -#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); + 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; } /* - * Nothing to do here if it wasn't mapped using the dmmap driver + * This maps memory using mmap() */ -/* ARGSUSED */ -void xf86UnMapVidMem(ScreenNum, Region, Base, Size) -int ScreenNum; -int Region; -pointer Base; -unsigned long Size; +static pointer +mapVidMemMMAP(int ScreenNum, unsigned long Base, unsigned long Size, int flags) { - 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; - } + 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 - return; -} - -/* ARGSUSED */ -Bool xf86LinearVidMem() -{ - int fd, ver; -#if defined(SVR4) || defined(SCO325) - return TRUE; -#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); + 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); } -/***************************************************************************/ -/* I/O Permissions section */ -/***************************************************************************/ +#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; -static Bool ScreenEnabled[MAXSCREENS]; -static Bool IOEnabled = FALSE; -static Bool InitDone = FALSE; + vas.base = (long)Base; + vas.size = (long)Size; -void xf86ClearIOPortList(ScreenNum) -int ScreenNum; -{ - int i; - - if (!InitDone) - { - for (i = 0; i < MAXSCREENS; i++) - ScreenEnabled[i] = FALSE; - InitDone = TRUE; - } + 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 */ -void xf86AddIOPorts(ScreenNum, NumPorts, Ports) -int ScreenNum; -int NumPorts; -unsigned *Ports; +static pointer +mapVidMemVC(int ScreenNum, unsigned long Base, unsigned long Size, int flags) { + struct vidclass *vcp; + char *class = NULL; + pointer base; + + for (vcp = vidclasslist; vcp->name; vcp++) { + if ((vcp->base == Base) && (vcp->size == Size)) { + class = vcp->name; + break; + } + } + + 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 + } + + /* + * 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; } -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; -} +/* + * 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). + */ -void xf86DisableIOPorts(ScreenNum) -int ScreenNum; +static void +unmapVidMem(int ScreenNum, pointer Base, unsigned long Size) { - int i; +#if USE_VASMETHOD + struct vidvasmem vas; + int x; - ScreenEnabled[ScreenNum] = FALSE; + vas.base = (long)Base; + vas.size = (long)Size; - if (!IOEnabled) - return; + x = ioctl (xf86Info.consoleFd, CONS_DELVAS, &vas); + if (x == 0) + return; +#endif /* USE_VASMETHOD */ - for (i = 0; i < MAXSCREENS; i++) - if (ScreenEnabled[i]) - return; - sysi86(SI86V86, V86SC_IOPL, 0); - IOEnabled = FALSE; - return; + munmap(Base, Size); } -void xf86DisableIOPrivs() +/* + * 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) { - if (IOEnabled) - sysi86(SI86V86, V86SC_IOPL, 0); - return; -} + int mpx_fd; -/***************************************************************************/ -/* Interrupt Handling section */ -/***************************************************************************/ - -Bool xf86DisableInterrupts() -{ -#ifdef __GNUC__ - __asm__ __volatile__("cli"); -#else - asm("cli"); -#endif /* __GNUC__ */ - - return(TRUE); + if (scoIsMultiConsole ()) { + pVidMem->mapMem = mapVidMemVC; + } else { +#if USE_VASMETHOD + pVidMem->mapMem = mapVidMemVAS; +#else + 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); + } } -void xf86EnableInterrupts() -{ -#ifdef __GNUC__ - __asm__ __volatile__("sti"); -#else - asm("sti"); -#endif /* __GNUC__ */ - - return; -} |