summaryrefslogtreecommitdiff
path: root/hw/xfree86/os-support/sco/sco_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/os-support/sco/sco_init.c')
-rw-r--r--hw/xfree86/os-support/sco/sco_init.c503
1 files changed, 283 insertions, 220 deletions
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;
}