2 * Copyright 2001-2005 by J. Kean Johnston <jkj@sco.com>
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name J. Kean Johnston not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. J. Kean Johnston makes no
11 * representations about the suitability of this software for any purpose.
12 * It is provided "as is" without express or implied warranty.
14 * J. KEAN JOHNSTON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL J. KEAN JOHNSTON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
18 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
19 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
23 /* Re-written May 2001 to represent the current state of reality */
25 #ifdef HAVE_XORG_CONFIG_H
26 #include <xorg-config.h>
36 #include "xf86_OSlib.h"
38 static Bool KeepTty
= FALSE
;
39 static int VTnum
= -1;
40 static char vtdevice
[48];
41 static int sco_console_mode
= -1;
50 struct vid_info vidinf
;
51 struct sigaction sigvtsw
;
54 if (serverGeneration
== 1) {
55 /* check if we're run with euid==0 */
57 FatalError("xf86OpenConsole: Server must be setuid root\n");
60 /* If we are run in the background we will get SIGTTOU. Ignore it. */
61 OsSignal (SIGTTOU
, SIG_IGN
);
64 * Set up the virtual terminal (multiscreen in SCO parlance).
65 * For the actual console itself, screens are numbered from
66 * 1 to (usually) 16. However, it is possible to have a nested
67 * server, and it is also possible to be on a multi-console
68 * system such as MaxSpeed or SunRiver. Therefore, we should
69 * not make any assumptions about the TTY name we are on, and
70 * instead we rely on ttyname() to give us the real TTY name.
71 * Previously, we tried to determine the TTY name manually.
72 * This is wrong. The only time we need to futz with the TTY name
73 * is if we were given the name of a TTY to run on explicity on
79 * No device was specified. We need to query the kernel to see which
80 * console device we are on (and in fact if we are on a console at all).
84 if (ttn
== (char *)0) {
85 FatalError ("xf86OpenConsole: Could not determine TTY name: %s\n",
88 strlcpy (vtdevice
, ttn
, sizeof(vtdevice
));
89 } else if (VTnum
>= 0) {
90 snprintf (vtdevice
, sizeof(vtdevice
), "/dev/tty%02d", VTnum
);
94 * Now we can dispose of stdin/stdout
99 if ((xf86Info
.consoleFd
= open(vtdevice
, O_RDWR
| O_NDELAY
, 0)) < 0) {
100 FatalError("xf86OpenConsole: Cannot open %s: %s\n", vtdevice
,
105 * We make 100% sure we use the correct VT number. This can get ugly
106 * where there are multi-consoles in use, so we make sure we query
107 * the kernel for the correct VT number. It knows best, we don't.
109 vidinf
.size
= sizeof(vidinf
);
110 if (ioctl (xf86Info
.consoleFd
, CONS_GETINFO
, &vidinf
) < 0) {
111 FatalError ("xf86OpenConsole: %s not a console device "
112 "or error querying device: %s\n", vtdevice
, strerror (errno
));
114 xf86Info
.vtno
= vidinf
.m_num
;
115 VTnum
= vidinf
.m_num
+ 1; /* 0-based */
117 ErrorF("(using VT%02d device %s)\n\n", VTnum
, vtdevice
);
119 /* We activate the console just in case its not the one we are on */
120 if (ioctl(xf86Info
.consoleFd
, VT_ACTIVATE
, xf86Info
.vtno
) != 0) {
121 ErrorF("xf86OpenConsole: VT_ACTIVATE failed (%s)\n", strerror(errno
));
124 /* Disassociate from controling TTY */
130 * Now we get the current mode that the console device is in. We will
131 * use this later when we close the console device to restore it to
134 if ((sco_console_mode
= ioctl(xf86Info
.consoleFd
, CONS_GET
, 0L)) < 0) {
135 FatalError("xf86OpenConsole: CONS_GET failed on console (%s)\n",
139 if (ioctl(xf86Info
.consoleFd
, VT_GETMODE
, &VT
) < 0) {
140 FatalError("xf86OpenConsole: VT_GETMODE failed (%s)\n", strerror(errno
));
143 sigvtsw
.sa_handler
= xf86VTRequest
;
144 sigfillset(&sigvtsw
.sa_mask
);
145 sigvtsw
.sa_flags
= 0;
147 /* NOTE: Using sigaction means we dont have to re-arm the signal */
148 sigaction(SIGUSR1
, &sigvtsw
, NULL
);
150 VT
.mode
= VT_PROCESS
;
153 VT
.frsig
= SIGINT
; /* Not implemented */
157 * The SCO X server tries the following call 5 times. Lets do the same
158 * thing. It shouldn't really be required but sometimes things take a
159 * while to settle down when switching screens. *helpless shrug* I know
164 for (i
= 0; i
< 5; i
++) {
165 ioctl_ret
= ioctl(xf86Info
.consoleFd
, VT_SETMODE
, &VT
);
168 usleep(999999); /* Dont use nap() - it forces linking with -lx */
172 FatalError("xf86OpenConsole: VT_SETMODE failed (%s)\n", strerror(errno
));
176 * Convince the console driver we are in graphics mode.
178 if (ioctl(xf86Info
.consoleFd
, KDSETMODE
, KD_GRAPHICS
) < 0) {
179 ErrorF("Failed to set graphics mode (%s)\n", strerror(errno
));
181 } else { /* serverGeneration != 1 */
182 if (ioctl(xf86Info
.consoleFd
, VT_ACTIVATE
, xf86Info
.vtno
) != 0) {
183 ErrorF("xf86OpenConsole: VT_ACTIVATE failed (%s)\n", strerror(errno
));
189 * Restore the console to its previous state. This may cause flicker if
190 * the screen was previous in a graphics mode, because we first set it
191 * to text mode. This has the advantage of getting the console driver
192 * to do a soft reset on the card, which really does help settle the
193 * video card down again after coming out of Xfree86.
196 xf86CloseConsole(void)
199 struct sigaction sigvtsw
;
201 /* Set text mode (possibly briefly) */
202 ioctl(xf86Info
.consoleFd
, KDSETMODE
, KD_TEXT0
);
204 /* Restore the original mode */
205 if (sco_console_mode
!= -1) {
206 ioctl(xf86Info
.consoleFd
, MODESWITCH
| sco_console_mode
, 0L);
209 ioctl(xf86Info
.consoleFd
, VT_RELDISP
, 1); /* Release the display */
211 sigvtsw
.sa_handler
= SIG_DFL
;
212 sigfillset(&sigvtsw
.sa_mask
);
213 sigvtsw
.sa_flags
= 0;
215 sigaction(SIGUSR1
, &sigvtsw
, NULL
);
222 ioctl(xf86Info
.consoleFd
, VT_SETMODE
, &VT
); /* Revert to auto handling */
224 close(xf86Info
.consoleFd
); /* We're done with the device */
228 xf86ProcessArgument(int argc
, char *argv
[], int i
)
231 * Keep server from detaching from controlling tty. This is useful
232 * when debugging (so the server can receive keyboard signals).
234 if (!strcmp(argv
[i
], "-keeptty")) {
240 * By default, the X server wants to bind itself to CPU 0. This makes
241 * sure that the server has full access to the I/O ports at IOPL 3.
242 * Some SMP systems have trouble with I/O on CPU's other than 0. If,
243 * however, you have a system that is well behaved, you can specify
244 * this argument and let the scheduler decide which CPU the server
247 if (!strcmp(argv
[i
], "-nompxlock")) {
253 * Specify the VT number to run on (NOT the device).
255 if ((argv
[i
][0] == 'v') && (argv
[i
][1] == 't')) {
256 if (sscanf(argv
[i
], "vt%2d", &VTnum
) == 0) {
270 * Use a device the user specifies.
272 if (!strcmp(argv
[i
], "-crt")) {
279 strlcpy (vtdevice
, argv
[i
], sizeof(vtdevice
));
289 ErrorF("vtXX use the specified VT number\n");
290 ErrorF("-crt DEVICE use the specified VT device\n");
291 ErrorF("-nompxlock dont bind X server to CPU 0\n");
293 ErrorF("don't detach controlling tty (for debugging only)\n");