1 /*
2  * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
3  * Copyright 1993 by David Wexelblat <dwex@goblin.org>
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the names of Rich Murphey and David Wexelblat
10  * not be used in advertising or publicity pertaining to distribution of
11  * the software without specific, written prior permission.  Rich Murphey and
12  * David Wexelblat make no representations about the suitability of this
13  * software for any purpose.  It is provided "as is" without express or
14  * implied warranty.
15  *
16  * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
17  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT BE LIABLE FOR
19  * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  *
24  */
25 
26 #ifdef HAVE_XORG_CONFIG_H
27 #include <xorg-config.h>
28 #endif
29 
30 #include <X11/X.h>
31 
32 #include "compiler.h"
33 
34 #include "xf86.h"
35 #include "xf86Priv.h"
36 #include "xf86_OSlib.h"
37 
38 #include <sys/utsname.h>
39 #include <sys/ioctl.h>
40 #include <stdlib.h>
41 #include <errno.h>
42 
43 static Bool KeepTty = FALSE;
44 
45 #ifdef PCCONS_SUPPORT
46 static int devConsoleFd = -1;
47 #endif
48 #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
49 static int VTnum = -1;
50 static int initialVT = -1;
51 static struct termios tty_attr;	/* tty state to restore */
52 static int tty_mode;		/* kbd mode to restore */
53 #endif
54 
55 #ifdef PCCONS_SUPPORT
56 /* Stock 0.1 386bsd pccons console driver interface */
57 #define PCCONS_CONSOLE_DEV1 "/dev/ttyv0"
58 #define PCCONS_CONSOLE_DEV2 "/dev/vga"
59 #define PCCONS_CONSOLE_MODE O_RDWR|O_NDELAY
60 #endif
61 
62 #ifdef SYSCONS_SUPPORT
63 /* The FreeBSD 1.1 version syscons driver uses /dev/ttyv0 */
64 #define SYSCONS_CONSOLE_DEV1 "/dev/ttyv0"
65 #define SYSCONS_CONSOLE_DEV2 "/dev/vga"
66 #define SYSCONS_CONSOLE_MODE O_RDWR|O_NDELAY
67 #endif
68 
69 #ifdef PCVT_SUPPORT
70 /* Hellmuth Michaelis' pcvt driver */
71 #ifndef __OpenBSD__
72 #define PCVT_CONSOLE_DEV "/dev/ttyv0"
73 #else
74 #define PCVT_CONSOLE_DEV "/dev/ttyC0"
75 #endif
76 #define PCVT_CONSOLE_MODE O_RDWR|O_NDELAY
77 #endif
78 
79 #if defined(WSCONS_SUPPORT) && defined(__NetBSD__)
80 /* NetBSD's new console driver */
81 #define WSCONS_PCVT_COMPAT_CONSOLE_DEV "/dev/ttyE0"
82 #endif
83 
84 #ifdef __GLIBC__
85 #define setpgrp setpgid
86 #endif
87 
88 #define CHECK_DRIVER_MSG \
89   "Check your kernel's console driver configuration and /dev entries"
90 
91 static char *supported_drivers[] = {
92 #ifdef PCCONS_SUPPORT
93     "pccons (with X support)",
94 #endif
95 #ifdef SYSCONS_SUPPORT
96     "syscons",
97 #endif
98 #ifdef PCVT_SUPPORT
99     "pcvt",
100 #endif
101 #ifdef WSCONS_SUPPORT
102     "wscons",
103 #endif
104 };
105 
106 /*
107  * Functions to probe for the existance of a supported console driver.
108  * Any function returns either a valid file descriptor (driver probed
109  * succesfully), -1 (driver not found), or uses FatalError() if the
110  * driver was found but proved to not support the required mode to run
111  * an X server.
112  */
113 
114 typedef int (*xf86ConsOpen_t) (void);
115 
116 #ifdef PCCONS_SUPPORT
117 static int xf86OpenPccons(void);
118 #endif                          /* PCCONS_SUPPORT */
119 
120 #ifdef SYSCONS_SUPPORT
121 static int xf86OpenSyscons(void);
122 #endif                          /* SYSCONS_SUPPORT */
123 
124 #ifdef PCVT_SUPPORT
125 static int xf86OpenPcvt(void);
126 #endif                          /* PCVT_SUPPORT */
127 
128 #ifdef WSCONS_SUPPORT
129 static int xf86OpenWScons(void);
130 #endif
131 
132 /*
133  * The sequence of the driver probes is important; start with the
134  * driver that is best distinguishable, and end with the most generic
135  * driver.  (Otherwise, pcvt would also probe as syscons, and either
136  * pcvt or syscons might succesfully probe as pccons.)
137  */
138 static xf86ConsOpen_t xf86ConsTab[] = {
139 #ifdef PCVT_SUPPORT
140     xf86OpenPcvt,
141 #endif
142 #ifdef SYSCONS_SUPPORT
143     xf86OpenSyscons,
144 #endif
145 #ifdef PCCONS_SUPPORT
146     xf86OpenPccons,
147 #endif
148 #ifdef WSCONS_SUPPORT
149     xf86OpenWScons,
150 #endif
151     (xf86ConsOpen_t) NULL
152 };
153 
154 void
xf86OpenConsole()155 xf86OpenConsole()
156 {
157     int i, fd = -1;
158     xf86ConsOpen_t *driver;
159 
160 #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
161     int result;
162 
163 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
164     struct utsname uts;
165 #endif
166     vtmode_t vtmode;
167 #endif
168 
169     if (serverGeneration == 1) {
170         /* check if we are run with euid==0 */
171         if (geteuid() != 0) {
172             FatalError("xf86OpenConsole: Server must be suid root");
173         }
174 
175         if (!KeepTty) {
176             /*
177              * detaching the controlling tty solves problems of kbd character
178              * loss.  This is not interesting for CO driver, because it is
179              * exclusive.
180              */
181             setpgrp(0, getpid());
182             if ((i = open("/dev/tty", O_RDWR)) >= 0) {
183                 ioctl(i, TIOCNOTTY, (char *) 0);
184                 close(i);
185             }
186         }
187 
188         /* detect which driver we are running on */
189         for (driver = xf86ConsTab; *driver; driver++) {
190             if ((fd = (*driver) ()) >= 0)
191                 break;
192         }
193 
194         /* Check that a supported console driver was found */
195         if (fd < 0) {
196             char cons_drivers[80] = { 0, };
197             for (i = 0; i < ARRAY_SIZE(supported_drivers); i++) {
198                 if (i) {
199                     strcat(cons_drivers, ", ");
200                 }
201                 strcat(cons_drivers, supported_drivers[i]);
202             }
203             FatalError
204                 ("%s: No console driver found\n\tSupported drivers: %s\n\t%s",
205                  "xf86OpenConsole", cons_drivers, CHECK_DRIVER_MSG);
206         }
207         xf86Info.consoleFd = fd;
208 
209         switch (xf86Info.consType) {
210 #ifdef PCCONS_SUPPORT
211         case PCCONS:
212             if (ioctl(xf86Info.consoleFd, CONSOLE_X_MODE_ON, 0) < 0) {
213                 FatalError("%s: CONSOLE_X_MODE_ON failed (%s)\n%s",
214                            "xf86OpenConsole", strerror(errno),
215                            CHECK_DRIVER_MSG);
216             }
217             /*
218              * Hack to prevent keyboard hanging when syslogd closes
219              * /dev/console
220              */
221             if ((devConsoleFd = open("/dev/console", O_WRONLY, 0)) < 0) {
222                 xf86Msg(X_WARNING,
223                         "xf86OpenConsole: couldn't open /dev/console (%s)\n",
224                         strerror(errno));
225             }
226             break;
227 #endif
228 #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
229         case SYSCONS:
230             /* as of FreeBSD 2.2.8, syscons driver does not need the #1 vt
231              * switching anymore. Here we check for FreeBSD 3.1 and up.
232              * Add cases for other *BSD that behave the same.
233              */
234 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
235 #if defined(__sparc64__)
236 	    pci_system_init_dev_mem(fd);
237 #endif
238             uname(&uts);
239             i = atof(uts.release) * 100;
240             if (i >= 310)
241                 goto acquire_vt;
242 #endif
243             /* otherwise fall through */
244         case PCVT:
245 #if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 200000000))
246             /*
247              * First activate the #1 VT.  This is a hack to allow a server
248              * to be started while another one is active.  There should be
249              * a better way.
250              */
251             if (initialVT != 1) {
252 
253                 if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) != 0) {
254                     xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
255                 }
256                 sleep(1);
257             }
258 #endif
259  acquire_vt:
260             if (!xf86Info.ShareVTs) {
261                 struct termios nTty;
262                 /*
263                  * now get the VT
264                  */
265                 SYSCALL(result =
266                         ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno));
267                 if (result != 0) {
268                     xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
269                 }
270                 SYSCALL(result =
271                         ioctl(xf86Info.consoleFd, VT_WAITACTIVE,
272                               xf86Info.vtno));
273                 if (result != 0) {
274                     xf86Msg(X_WARNING,
275                             "xf86OpenConsole: VT_WAITACTIVE failed\n");
276                 }
277 
278                 OsSignal(SIGUSR1, xf86VTRequest);
279 
280                 vtmode.mode = VT_PROCESS;
281                 vtmode.relsig = SIGUSR1;
282                 vtmode.acqsig = SIGUSR1;
283                 vtmode.frsig = SIGUSR1;
284                 if (ioctl(xf86Info.consoleFd, VT_SETMODE, &vtmode) < 0) {
285                     FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed");
286                 }
287 #if !defined(__OpenBSD__) && !defined(USE_DEV_IO) && !defined(USE_I386_IOPL)
288                 if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0) {
289                     FatalError("xf86OpenConsole: KDENABIO failed (%s)",
290                                strerror(errno));
291                 }
292 #endif
293                 if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) {
294                     FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed");
295                 }
296 
297                 tcgetattr(xf86Info.consoleFd, &tty_attr);
298                 ioctl(xf86Info.consoleFd, KDGKBMODE, &tty_mode);
299 
300                 /* disable special keys */
301                 if (ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW) < 0) {
302                     FatalError("xf86OpenConsole: KDSKBMODE K_RAW failed (%s)",
303                                strerror(errno));
304                 }
305 
306                 nTty = tty_attr;
307                 nTty.c_iflag = IGNPAR | IGNBRK;
308                 nTty.c_oflag = 0;
309                 nTty.c_cflag = CREAD | CS8;
310                 nTty.c_lflag = 0;
311                 nTty.c_cc[VTIME] = 0;
312                 nTty.c_cc[VMIN] = 1;
313                 cfsetispeed(&nTty, 9600);
314                 cfsetospeed(&nTty, 9600);
315                 tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
316             }
317             else {              /* xf86Info.ShareVTs */
318                 close(xf86Info.consoleFd);
319             }
320             break;
321 #endif                          /* SYSCONS_SUPPORT || PCVT_SUPPORT */
322 #ifdef WSCONS_SUPPORT
323         case WSCONS:
324             /* Nothing to do */
325             break;
326 #endif
327         }
328     }
329     else {
330         /* serverGeneration != 1 */
331 #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
332         if (!xf86Info.ShareVTs &&
333             (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT)) {
334             if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) {
335                 xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
336             }
337         }
338 #endif                          /* SYSCONS_SUPPORT || PCVT_SUPPORT */
339     }
340     return;
341 }
342 
343 #ifdef PCCONS_SUPPORT
344 
345 static int
xf86OpenPccons()346 xf86OpenPccons()
347 {
348     int fd = -1;
349 
350     if ((fd = open(PCCONS_CONSOLE_DEV1, PCCONS_CONSOLE_MODE, 0))
351         >= 0 || (fd = open(PCCONS_CONSOLE_DEV2, PCCONS_CONSOLE_MODE, 0))
352         >= 0) {
353         if (ioctl(fd, CONSOLE_X_MODE_OFF, 0) < 0) {
354             FatalError("%s: CONSOLE_X_MODE_OFF failed (%s)\n%s\n%s",
355                        "xf86OpenPccons",
356                        strerror(errno),
357                        "Was expecting pccons driver with X support",
358                        CHECK_DRIVER_MSG);
359         }
360         xf86Info.consType = PCCONS;
361         xf86Msg(X_PROBED, "Using pccons driver with X support\n");
362     }
363     return fd;
364 }
365 
366 #endif                          /* PCCONS_SUPPORT */
367 
368 #ifdef SYSCONS_SUPPORT
369 
370 static int
xf86OpenSyscons()371 xf86OpenSyscons()
372 {
373     int fd = -1;
374     vtmode_t vtmode;
375     char vtname[12];
376     long syscons_version;
377     MessageType from;
378 
379     /* Check for syscons */
380     if ((fd = open(SYSCONS_CONSOLE_DEV1, SYSCONS_CONSOLE_MODE, 0)) >= 0
381         || (fd = open(SYSCONS_CONSOLE_DEV2, SYSCONS_CONSOLE_MODE, 0)) >= 0) {
382         if (ioctl(fd, VT_GETMODE, &vtmode) >= 0) {
383             /* Get syscons version */
384             if (ioctl(fd, CONS_GETVERS, &syscons_version) < 0) {
385                 syscons_version = 0;
386             }
387 
388             xf86Info.vtno = VTnum;
389             from = X_CMDLINE;
390 
391 #ifdef VT_GETACTIVE
392             if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0)
393                 initialVT = -1;
394 #endif
395             if (xf86Info.ShareVTs)
396                 xf86Info.vtno = initialVT;
397 
398             if (xf86Info.vtno == -1) {
399                 /*
400                  * For old syscons versions (<0x100), VT_OPENQRY returns
401                  * the current VT rather than the next free VT.  In this
402                  * case, the server gets started on the current VT instead
403                  * of the next free VT.
404                  */
405 
406 #if 0
407                 /* check for the fixed VT_OPENQRY */
408                 if (syscons_version >= 0x100) {
409 #endif
410                     if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) {
411                         /* No free VTs */
412                         xf86Info.vtno = -1;
413                     }
414 #if 0
415                 }
416 #endif
417 
418                 if (xf86Info.vtno == -1) {
419                     /*
420                      * All VTs are in use.  If initialVT was found, use it.
421                      */
422                     if (initialVT != -1) {
423                         xf86Info.vtno = initialVT;
424                     }
425                     else {
426                         if (syscons_version >= 0x100) {
427                             FatalError("%s: Cannot find a free VT",
428                                        "xf86OpenSyscons");
429                         }
430                         /* Should no longer reach here */
431                         FatalError("%s: %s %s\n\t%s %s",
432                                    "xf86OpenSyscons",
433                                    "syscons versions prior to 1.0 require",
434                                    "either the",
435                                    "server's stdin be a VT",
436                                    "or the use of the vtxx server option");
437                     }
438                 }
439                 from = X_PROBED;
440             }
441 
442             close(fd);
443             snprintf(vtname, sizeof(vtname), "/dev/ttyv%01x",
444                      xf86Info.vtno - 1);
445             if ((fd = open(vtname, SYSCONS_CONSOLE_MODE, 0)) < 0) {
446                 FatalError("xf86OpenSyscons: Cannot open %s (%s)",
447                            vtname, strerror(errno));
448             }
449             if (ioctl(fd, VT_GETMODE, &vtmode) < 0) {
450                 FatalError("xf86OpenSyscons: VT_GETMODE failed");
451             }
452             xf86Info.consType = SYSCONS;
453             xf86Msg(X_PROBED, "Using syscons driver with X support");
454             if (syscons_version >= 0x100) {
455                 xf86ErrorF(" (version %ld.%ld)\n", syscons_version >> 8,
456                            syscons_version & 0xFF);
457             }
458             else {
459                 xf86ErrorF(" (version 0.x)\n");
460             }
461             xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
462         }
463         else {
464             /* VT_GETMODE failed, probably not syscons */
465             close(fd);
466             fd = -1;
467         }
468     }
469     return fd;
470 }
471 
472 #endif                          /* SYSCONS_SUPPORT */
473 
474 #ifdef PCVT_SUPPORT
475 
476 static int
xf86OpenPcvt()477 xf86OpenPcvt()
478 {
479     /* This looks much like syscons, since pcvt is API compatible */
480     int fd = -1;
481     vtmode_t vtmode;
482     char vtname[12], *vtprefix;
483     struct pcvtid pcvt_version;
484 
485 #ifndef __OpenBSD__
486     vtprefix = "/dev/ttyv";
487 #else
488     vtprefix = "/dev/ttyC";
489 #endif
490 
491     fd = open(PCVT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
492 #ifdef WSCONS_PCVT_COMPAT_CONSOLE_DEV
493     if (fd < 0) {
494         fd = open(WSCONS_PCVT_COMPAT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
495         vtprefix = "/dev/ttyE";
496     }
497 #endif
498     if (fd >= 0) {
499         if (ioctl(fd, VGAPCVTID, &pcvt_version) >= 0) {
500             if (ioctl(fd, VT_GETMODE, &vtmode) < 0) {
501                 FatalError("%s: VT_GETMODE failed\n%s%s\n%s",
502                            "xf86OpenPcvt",
503                            "Found pcvt driver but X11 seems to be",
504                            " not supported.", CHECK_DRIVER_MSG);
505             }
506 
507             xf86Info.vtno = VTnum;
508 
509             if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0)
510                 initialVT = -1;
511 
512             if (xf86Info.vtno == -1) {
513                 if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) {
514                     /* No free VTs */
515                     xf86Info.vtno = -1;
516                 }
517 
518                 if (xf86Info.vtno == -1) {
519                     /*
520                      * All VTs are in use.  If initialVT was found, use it.
521                      */
522                     if (initialVT != -1) {
523                         xf86Info.vtno = initialVT;
524                     }
525                     else {
526                         FatalError("%s: Cannot find a free VT", "xf86OpenPcvt");
527                     }
528                 }
529             }
530 
531             close(fd);
532             snprintf(vtname, sizeof(vtname), "%s%01x", vtprefix,
533                      xf86Info.vtno - 1);
534             if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) {
535                 ErrorF("xf86OpenPcvt: Cannot open %s (%s)",
536                        vtname, strerror(errno));
537                 xf86Info.vtno = initialVT;
538                 snprintf(vtname, sizeof(vtname), "%s%01x", vtprefix,
539                          xf86Info.vtno - 1);
540                 if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) {
541                     FatalError("xf86OpenPcvt: Cannot open %s (%s)",
542                                vtname, strerror(errno));
543                 }
544             }
545             if (ioctl(fd, VT_GETMODE, &vtmode) < 0) {
546                 FatalError("xf86OpenPcvt: VT_GETMODE failed");
547             }
548             xf86Info.consType = PCVT;
549 #ifdef WSCONS_SUPPORT
550             xf86Msg(X_PROBED,
551                     "Using wscons driver on %s in pcvt compatibility mode "
552                     "(version %d.%d)\n", vtname,
553                     pcvt_version.rmajor, pcvt_version.rminor);
554 #else
555             xf86Msg(X_PROBED, "Using pcvt driver (version %d.%d)\n",
556                     pcvt_version.rmajor, pcvt_version.rminor);
557 #endif
558         }
559         else {
560             /* Not pcvt */
561             close(fd);
562             fd = -1;
563         }
564     }
565     return fd;
566 }
567 
568 #endif                          /* PCVT_SUPPORT */
569 
570 #ifdef WSCONS_SUPPORT
571 
572 static int
xf86OpenWScons()573 xf86OpenWScons()
574 {
575     int fd = -1;
576     int mode = WSDISPLAYIO_MODE_MAPPED;
577     int i;
578     char ttyname[16];
579 
580     /* XXX Is this ok? */
581     for (i = 0; i < 8; i++) {
582 #if defined(__NetBSD__)
583         snprintf(ttyname, sizeof(ttyname), "/dev/ttyE%d", i);
584 #elif defined(__OpenBSD__)
585         snprintf(ttyname, sizeof(ttyname), "/dev/ttyC%x", i);
586 #endif
587         if ((fd = open(ttyname, 2)) != -1)
588             break;
589     }
590     if (fd != -1) {
591         if (ioctl(fd, WSDISPLAYIO_SMODE, &mode) < 0) {
592             FatalError("%s: WSDISPLAYIO_MODE_MAPPED failed (%s)\n%s",
593                        "xf86OpenConsole", strerror(errno), CHECK_DRIVER_MSG);
594         }
595         xf86Info.consType = WSCONS;
596         xf86Msg(X_PROBED, "Using wscons driver\n");
597     }
598     return fd;
599 }
600 
601 #endif                          /* WSCONS_SUPPORT */
602 
603 void
xf86CloseConsole()604 xf86CloseConsole()
605 {
606 #if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)
607     struct vt_mode VT;
608 #endif
609 
610     if (xf86Info.ShareVTs)
611         return;
612 
613     switch (xf86Info.consType) {
614 #ifdef PCCONS_SUPPORT
615     case PCCONS:
616         ioctl(xf86Info.consoleFd, CONSOLE_X_MODE_OFF, 0);
617         break;
618 #endif                          /* PCCONS_SUPPORT */
619 #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
620     case SYSCONS:
621     case PCVT:
622         ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT);  /* Back to text mode */
623         ioctl(xf86Info.consoleFd, KDSKBMODE, tty_mode);
624         tcsetattr(xf86Info.consoleFd, TCSANOW, &tty_attr);
625         if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) {
626             VT.mode = VT_AUTO;
627             ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* dflt vt handling */
628         }
629 #if !defined(__OpenBSD__) && !defined(USE_DEV_IO) && !defined(USE_I386_IOPL)
630         if (ioctl(xf86Info.consoleFd, KDDISABIO, 0) < 0) {
631             xf86FatalError("xf86CloseConsole: KDDISABIO failed (%s)",
632                            strerror(errno));
633         }
634 #endif
635         if (initialVT != -1)
636             ioctl(xf86Info.consoleFd, VT_ACTIVATE, initialVT);
637         break;
638 #endif                          /* SYSCONS_SUPPORT || PCVT_SUPPORT */
639 #ifdef WSCONS_SUPPORT
640     case WSCONS:
641     {
642         int mode = WSDISPLAYIO_MODE_EMUL;
643 
644         ioctl(xf86Info.consoleFd, WSDISPLAYIO_SMODE, &mode);
645         break;
646     }
647 #endif
648     }
649 
650     close(xf86Info.consoleFd);
651 #ifdef PCCONS_SUPPORT
652     if (devConsoleFd >= 0)
653         close(devConsoleFd);
654 #endif
655     return;
656 }
657 
658 int
xf86ProcessArgument(int argc,char * argv[],int i)659 xf86ProcessArgument(int argc, char *argv[], int i)
660 {
661     /*
662      * Keep server from detaching from controlling tty.  This is useful
663      * when debugging (so the server can receive keyboard signals.
664      */
665     if (!strcmp(argv[i], "-keeptty")) {
666         KeepTty = TRUE;
667         return 1;
668     }
669 #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
670     if ((argv[i][0] == 'v') && (argv[i][1] == 't')) {
671         if (sscanf(argv[i], "vt%2d", &VTnum) == 0 || VTnum < 1 || VTnum > 12) {
672             UseMsg();
673             VTnum = -1;
674             return 0;
675         }
676         return 1;
677     }
678 #endif                          /* SYSCONS_SUPPORT || PCVT_SUPPORT */
679     return 0;
680 }
681 
682 void
xf86UseMsg()683 xf86UseMsg()
684 {
685 #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
686     ErrorF("vtXX                   use the specified VT number (1-12)\n");
687 #endif                          /* SYSCONS_SUPPORT || PCVT_SUPPORT */
688     ErrorF("-keeptty               ");
689     ErrorF("don't detach controlling tty (for debugging only)\n");
690     return;
691 }
692 
693 void
xf86OSInputThreadInit(void)694 xf86OSInputThreadInit(void)
695 {
696     return;
697 }
698