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 43static Bool KeepTty = FALSE; 44static int devConsoleFd = -1; 45#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) 46static int VTnum = -1; 47static int initialVT = -1; 48static Bool ShareVTs = FALSE; 49#endif 50 51#ifdef PCCONS_SUPPORT 52/* Stock 0.1 386bsd pccons console driver interface */ 53#define PCCONS_CONSOLE_DEV1 "/dev/ttyv0" 54#define PCCONS_CONSOLE_DEV2 "/dev/vga" 55#define PCCONS_CONSOLE_MODE O_RDWR|O_NDELAY 56#endif 57 58#ifdef SYSCONS_SUPPORT 59/* The FreeBSD 1.1 version syscons driver uses /dev/ttyv0 */ 60#define SYSCONS_CONSOLE_DEV1 "/dev/ttyv0" 61#define SYSCONS_CONSOLE_DEV2 "/dev/vga" 62#define SYSCONS_CONSOLE_MODE O_RDWR|O_NDELAY 63#endif 64 65#ifdef PCVT_SUPPORT 66/* Hellmuth Michaelis' pcvt driver */ 67#ifndef __OpenBSD__ 68# define PCVT_CONSOLE_DEV "/dev/ttyv0" 69#else 70# define PCVT_CONSOLE_DEV "/dev/ttyC0" 71#endif 72#define PCVT_CONSOLE_MODE O_RDWR|O_NDELAY 73#endif 74 75#if defined(WSCONS_SUPPORT) && defined(__NetBSD__) 76/* NetBSD's new console driver */ 77#define WSCONS_PCVT_COMPAT_CONSOLE_DEV "/dev/ttyE0" 78#endif 79 80#ifdef __GLIBC__ 81#define setpgrp setpgid 82#endif 83 84#define CHECK_DRIVER_MSG \ 85 "Check your kernel's console driver configuration and /dev entries" 86 87static char *supported_drivers[] = { 88#ifdef PCCONS_SUPPORT 89 "pccons (with X support)", 90#endif 91#ifdef SYSCONS_SUPPORT 92 "syscons", 93#endif 94#ifdef PCVT_SUPPORT 95 "pcvt", 96#endif 97#ifdef WSCONS_SUPPORT 98 "wscons", 99#endif 100}; 101 102 103/* 104 * Functions to probe for the existance of a supported console driver. 105 * Any function returns either a valid file descriptor (driver probed 106 * succesfully), -1 (driver not found), or uses FatalError() if the 107 * driver was found but proved to not support the required mode to run 108 * an X server. 109 */ 110 111typedef int (*xf86ConsOpen_t)(void); 112 113#ifdef PCCONS_SUPPORT 114static int xf86OpenPccons(void); 115#endif /* PCCONS_SUPPORT */ 116 117#ifdef SYSCONS_SUPPORT 118static int xf86OpenSyscons(void); 119#endif /* SYSCONS_SUPPORT */ 120 121#ifdef PCVT_SUPPORT 122static int xf86OpenPcvt(void); 123#endif /* PCVT_SUPPORT */ 124 125#ifdef WSCONS_SUPPORT 126static int xf86OpenWScons(void); 127#endif 128 129/* 130 * The sequence of the driver probes is important; start with the 131 * driver that is best distinguishable, and end with the most generic 132 * driver. (Otherwise, pcvt would also probe as syscons, and either 133 * pcvt or syscons might succesfully probe as pccons.) 134 */ 135static xf86ConsOpen_t xf86ConsTab[] = { 136#ifdef PCVT_SUPPORT 137 xf86OpenPcvt, 138#endif 139#ifdef SYSCONS_SUPPORT 140 xf86OpenSyscons, 141#endif 142#ifdef PCCONS_SUPPORT 143 xf86OpenPccons, 144#endif 145#ifdef WSCONS_SUPPORT 146 xf86OpenWScons, 147#endif 148 (xf86ConsOpen_t)NULL 149}; 150 151 152void 153xf86OpenConsole() 154{ 155 int i, fd = -1; 156 xf86ConsOpen_t *driver; 157#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) 158 int result; 159#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 160 struct utsname uts; 161#endif 162 vtmode_t vtmode; 163#endif 164 165 if (serverGeneration == 1) 166 { 167 /* check if we are run with euid==0 */ 168 if (geteuid() != 0) 169 { 170 FatalError("xf86OpenConsole: Server must be suid root"); 171 } 172 173 if (!KeepTty) 174 { 175 /* 176 * detaching the controlling tty solves problems of kbd character 177 * loss. This is not interesting for CO driver, because it is 178 * exclusive. 179 */ 180 setpgrp(0, getpid()); 181 if ((i = open("/dev/tty",O_RDWR)) >= 0) 182 { 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 { 191 if ((fd = (*driver)()) >= 0) 192 break; 193 } 194 195 /* Check that a supported console driver was found */ 196 if (fd < 0) 197 { 198 char cons_drivers[80] = {0, }; 199 for (i = 0; i < sizeof(supported_drivers) / sizeof(char *); i++) 200 { 201 if (i) 202 { 203 strcat(cons_drivers, ", "); 204 } 205 strcat(cons_drivers, supported_drivers[i]); 206 } 207 FatalError( 208 "%s: No console driver found\n\tSupported drivers: %s\n\t%s", 209 "xf86OpenConsole", cons_drivers, CHECK_DRIVER_MSG); 210 } 211#if 0 /* stdin is already closed in OsInit() */ 212 fclose(stdin); 213#endif 214 xf86Info.consoleFd = fd; 215 xf86Info.screenFd = fd; 216 217 switch (xf86Info.consType) 218 { 219#ifdef PCCONS_SUPPORT 220 case PCCONS: 221 if (ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_ON, 0) < 0) 222 { 223 FatalError("%s: CONSOLE_X_MODE_ON failed (%s)\n%s", 224 "xf86OpenConsole", strerror(errno), 225 CHECK_DRIVER_MSG); 226 } 227 /* 228 * Hack to prevent keyboard hanging when syslogd closes 229 * /dev/console 230 */ 231 if ((devConsoleFd = open("/dev/console", O_WRONLY,0)) < 0) 232 { 233 xf86Msg(X_WARNING, 234 "xf86OpenConsole: couldn't open /dev/console (%s)\n", 235 strerror(errno)); 236 } 237 break; 238#endif 239#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) 240 case SYSCONS: 241 /* as of FreeBSD 2.2.8, syscons driver does not need the #1 vt 242 * switching anymore. Here we check for FreeBSD 3.1 and up. 243 * Add cases for other *BSD that behave the same. 244 */ 245#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 246 uname (&uts); 247 i = atof(uts.release) * 100; 248 if (i >= 310) goto acquire_vt; 249#endif 250 /* otherwise fall through */ 251 case PCVT: 252#if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 200000000)) 253 /* 254 * First activate the #1 VT. This is a hack to allow a server 255 * to be started while another one is active. There should be 256 * a better way. 257 */ 258 if (initialVT != 1) { 259 260 if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) != 0) 261 { 262 xf86Msg(X_WARNING, 263 "xf86OpenConsole: VT_ACTIVATE failed\n"); 264 } 265 sleep(1); 266 } 267#endif 268acquire_vt: 269 if (!ShareVTs) { 270 /* 271 * now get the VT 272 */ 273 SYSCALL(result = 274 ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno)); 275 if (result != 0) 276 { 277 xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); 278 } 279 SYSCALL(result = 280 ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno)); 281 if (result != 0) 282 { 283 xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); 284 } 285 286 signal(SIGUSR1, xf86VTRequest); 287 288 vtmode.mode = VT_PROCESS; 289 vtmode.relsig = SIGUSR1; 290 vtmode.acqsig = SIGUSR1; 291 vtmode.frsig = SIGUSR1; 292 if (ioctl(xf86Info.consoleFd, VT_SETMODE, &vtmode) < 0) 293 { 294 FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed"); 295 } 296 #if !defined(USE_DEV_IO) && !defined(USE_I386_IOPL) 297 if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0) 298 { 299 FatalError("xf86OpenConsole: KDENABIO failed (%s)", 300 strerror(errno)); 301 } 302 #endif 303 if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) 304 { 305 FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed"); 306 } 307 } else { /* ShareVTs */ 308 close(xf86Info.consoleFd); 309 } 310 break; 311#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ 312#ifdef WSCONS_SUPPORT 313 case WSCONS: 314 /* Nothing to do */ 315 break; 316#endif 317 } 318 } 319 else 320 { 321 /* serverGeneration != 1 */ 322#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) 323 if (!ShareVTs) if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT) 324 { 325 if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) 326 { 327 xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); 328 } 329 } 330#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ 331 } 332 return; 333} 334 335 336#ifdef PCCONS_SUPPORT 337 338static int 339xf86OpenPccons() 340{ 341 int fd = -1; 342 343 if ((fd = open(PCCONS_CONSOLE_DEV1, PCCONS_CONSOLE_MODE, 0)) 344 >= 0 || 345 (fd = open(PCCONS_CONSOLE_DEV2, PCCONS_CONSOLE_MODE, 0)) 346 >= 0) 347 { 348 if (ioctl(fd, CONSOLE_X_MODE_OFF, 0) < 0) 349 { 350 FatalError( 351 "%s: CONSOLE_X_MODE_OFF failed (%s)\n%s\n%s", 352 "xf86OpenPccons", 353 strerror(errno), 354 "Was expecting pccons driver with X support", 355 CHECK_DRIVER_MSG); 356 } 357 xf86Info.consType = PCCONS; 358 xf86Msg(X_PROBED, "Using pccons driver with X support\n"); 359 } 360 return fd; 361} 362 363#endif /* PCCONS_SUPPORT */ 364 365#ifdef SYSCONS_SUPPORT 366 367static int 368xf86OpenSyscons() 369{ 370 int fd = -1; 371 vtmode_t vtmode; 372 char vtname[12]; 373 struct stat status; 374 long syscons_version; 375 MessageType from; 376 377 /* Check for syscons */ 378 if ((fd = open(SYSCONS_CONSOLE_DEV1, SYSCONS_CONSOLE_MODE, 0)) >= 0 379 || (fd = open(SYSCONS_CONSOLE_DEV2, SYSCONS_CONSOLE_MODE, 0)) >= 0) 380 { 381 if (ioctl(fd, VT_GETMODE, &vtmode) >= 0) 382 { 383 /* Get syscons version */ 384 if (ioctl(fd, CONS_GETVERS, &syscons_version) < 0) 385 { 386 syscons_version = 0; 387 } 388 389 xf86Info.vtno = VTnum; 390 from = X_CMDLINE; 391 392#ifdef VT_GETACTIVE 393 if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0) 394 initialVT = -1; 395#endif 396 if (ShareVTs) 397 xf86Info.vtno = initialVT; 398 399 if (xf86Info.vtno == -1) 400 { 401 /* 402 * For old syscons versions (<0x100), VT_OPENQRY returns 403 * the current VT rather than the next free VT. In this 404 * case, the server gets started on the current VT instead 405 * of the next free VT. 406 */ 407 408#if 0 409 /* check for the fixed VT_OPENQRY */ 410 if (syscons_version >= 0x100) 411 { 412#endif 413 if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) 414 { 415 /* No free VTs */ 416 xf86Info.vtno = -1; 417 } 418#if 0 419 } 420#endif 421 422 if (xf86Info.vtno == -1) 423 { 424 /* 425 * All VTs are in use. If initialVT was found, use it. 426 * Otherwise, if stdin is a VT, use that one. 427 * XXX stdin is already closed, so this won't work. 428 */ 429 if (initialVT != -1) 430 { 431 xf86Info.vtno = initialVT; 432 } 433 else if ((fstat(0, &status) >= 0) 434 && S_ISCHR(status.st_mode) 435 && (ioctl(0, VT_GETMODE, &vtmode) >= 0)) 436 { 437 /* stdin is a VT */ 438 xf86Info.vtno = minor(status.st_rdev) + 1; 439 } 440 else 441 { 442 if (syscons_version >= 0x100) 443 { 444 FatalError("%s: Cannot find a free VT", 445 "xf86OpenSyscons"); 446 } 447 /* Should no longer reach here */ 448 FatalError("%s: %s %s\n\t%s %s", 449 "xf86OpenSyscons", 450 "syscons versions prior to 1.0 require", 451 "either the", 452 "server's stdin be a VT", 453 "or the use of the vtxx server option"); 454 } 455 } 456 from = X_PROBED; 457 } 458 459 close(fd); 460#ifndef __OpenBSD__ 461 sprintf(vtname, "/dev/ttyv%01x", xf86Info.vtno - 1); 462#else 463 sprintf(vtname, "/dev/ttyC%01x", xf86Info.vtno - 1); 464#endif 465 if ((fd = open(vtname, SYSCONS_CONSOLE_MODE, 0)) < 0) 466 { 467 FatalError("xf86OpenSyscons: Cannot open %s (%s)", 468 vtname, strerror(errno)); 469 } 470 if (ioctl(fd, VT_GETMODE, &vtmode) < 0) 471 { 472 FatalError("xf86OpenSyscons: VT_GETMODE failed"); 473 } 474 xf86Info.consType = SYSCONS; 475 xf86Msg(X_PROBED, "Using syscons driver with X support"); 476 if (syscons_version >= 0x100) 477 { 478 xf86ErrorF(" (version %ld.%ld)\n", syscons_version >> 8, 479 syscons_version & 0xFF); 480 } 481 else 482 { 483 xf86ErrorF(" (version 0.x)\n"); 484 } 485 xf86Msg(from, "using VT number %d\n", xf86Info.vtno); 486 } 487 else 488 { 489 /* VT_GETMODE failed, probably not syscons */ 490 close(fd); 491 fd = -1; 492 } 493 } 494 return fd; 495} 496 497#endif /* SYSCONS_SUPPORT */ 498 499 500#ifdef PCVT_SUPPORT 501 502static int 503xf86OpenPcvt() 504{ 505 /* This looks much like syscons, since pcvt is API compatible */ 506 int fd = -1; 507 vtmode_t vtmode; 508 char vtname[12], *vtprefix; 509 struct stat status; 510 struct pcvtid pcvt_version; 511 512#ifndef __OpenBSD__ 513 vtprefix = "/dev/ttyv"; 514#else 515 vtprefix = "/dev/ttyC"; 516#endif 517 518 fd = open(PCVT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0); 519#ifdef WSCONS_PCVT_COMPAT_CONSOLE_DEV 520 if (fd < 0) 521 { 522 fd = open(WSCONS_PCVT_COMPAT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0); 523 vtprefix = "/dev/ttyE"; 524 } 525#endif 526 if (fd >= 0) 527 { 528 if (ioctl(fd, VGAPCVTID, &pcvt_version) >= 0) 529 { 530 if(ioctl(fd, VT_GETMODE, &vtmode) < 0) 531 { 532 FatalError("%s: VT_GETMODE failed\n%s%s\n%s", 533 "xf86OpenPcvt", 534 "Found pcvt driver but X11 seems to be", 535 " not supported.", CHECK_DRIVER_MSG); 536 } 537 538 xf86Info.vtno = VTnum; 539 540 if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0) 541 initialVT = -1; 542 543 if (xf86Info.vtno == -1) 544 { 545 if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) 546 { 547 /* No free VTs */ 548 xf86Info.vtno = -1; 549 } 550 551 if (xf86Info.vtno == -1) 552 { 553 /* 554 * All VTs are in use. If initialVT was found, use it. 555 * Otherwise, if stdin is a VT, use that one. 556 * XXX stdin is already closed, so this won't work. 557 */ 558 if (initialVT != -1) 559 { 560 xf86Info.vtno = initialVT; 561 } 562 else if ((fstat(0, &status) >= 0) 563 && S_ISCHR(status.st_mode) 564 && (ioctl(0, VT_GETMODE, &vtmode) >= 0)) 565 { 566 /* stdin is a VT */ 567 xf86Info.vtno = minor(status.st_rdev) + 1; 568 } 569 else 570 { 571 FatalError("%s: Cannot find a free VT", 572 "xf86OpenPcvt"); 573 } 574 } 575 } 576 577 close(fd); 578 sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1); 579 if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) 580 { 581 ErrorF("xf86OpenPcvt: Cannot open %s (%s)", 582 vtname, strerror(errno)); 583 xf86Info.vtno = initialVT; 584 sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1); 585 if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0) { 586 FatalError("xf86OpenPcvt: Cannot open %s (%s)", 587 vtname, strerror(errno)); 588 } 589 } 590 if (ioctl(fd, VT_GETMODE, &vtmode) < 0) 591 { 592 FatalError("xf86OpenPcvt: VT_GETMODE failed"); 593 } 594 xf86Info.consType = PCVT; 595#ifdef WSCONS_SUPPORT 596 xf86Msg(X_PROBED, 597 "Using wscons driver on %s in pcvt compatibility mode " 598 "(version %d.%d)\n", vtname, 599 pcvt_version.rmajor, pcvt_version.rminor); 600#else 601 xf86Msg(X_PROBED, "Using pcvt driver (version %d.%d)\n", 602 pcvt_version.rmajor, pcvt_version.rminor); 603#endif 604 xf86Msg(X_PROBED, "using VT number %d\n", xf86Info.vtno); 605 } 606 else 607 { 608 /* Not pcvt */ 609 close(fd); 610 fd = -1; 611 } 612 } 613 return fd; 614} 615 616#endif /* PCVT_SUPPORT */ 617 618#ifdef WSCONS_SUPPORT 619 620static int 621xf86OpenWScons() 622{ 623 int fd = -1; 624 int mode = WSDISPLAYIO_MODE_MAPPED; 625 int i; 626 char ttyname[16]; 627 628 /* XXX Is this ok? */ 629 for (i = 0; i < 8; i++) { 630#if defined(__NetBSD__) 631 sprintf(ttyname, "/dev/ttyE%d", i); 632#elif defined(__OpenBSD__) 633 sprintf(ttyname, "/dev/ttyC%x", i); 634#endif 635 if ((fd = open(ttyname, 2)) != -1) 636 break; 637 } 638 if (fd != -1) { 639 if (ioctl(fd, WSDISPLAYIO_SMODE, &mode) < 0) { 640 FatalError("%s: WSDISPLAYIO_MODE_MAPPED failed (%s)\n%s", 641 "xf86OpenConsole", strerror(errno), 642 CHECK_DRIVER_MSG); 643 } 644 xf86Info.consType = WSCONS; 645 xf86Msg(X_PROBED, "Using wscons driver\n"); 646 } 647 return fd; 648} 649 650#endif /* WSCONS_SUPPORT */ 651 652void 653xf86CloseConsole() 654{ 655#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) 656 struct vt_mode VT; 657#endif 658 659#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) 660 if (ShareVTs) return; 661#endif 662 663 switch (xf86Info.consType) 664 { 665#ifdef PCCONS_SUPPORT 666 case PCCONS: 667 ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_OFF, 0); 668 break; 669#endif /* PCCONS_SUPPORT */ 670#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) 671 case SYSCONS: 672 case PCVT: 673 ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode */ 674 if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) 675 { 676 VT.mode = VT_AUTO; 677 ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* dflt vt handling */ 678 } 679#if !defined(OpenBSD) && !defined(USE_DEV_IO) && !defined(USE_I386_IOPL) 680 if (ioctl(xf86Info.consoleFd, KDDISABIO, 0) < 0) 681 { 682 xf86FatalError("xf86CloseConsole: KDDISABIO failed (%s)", 683 strerror(errno)); 684 } 685#endif 686 if (initialVT != -1) 687 ioctl(xf86Info.consoleFd, VT_ACTIVATE, initialVT); 688 break; 689#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ 690#ifdef WSCONS_SUPPORT 691 case WSCONS: 692 { 693 int mode = WSDISPLAYIO_MODE_EMUL; 694 ioctl(xf86Info.screenFd, WSDISPLAYIO_SMODE, &mode); 695 break; 696 } 697#endif 698 } 699 700 if (xf86Info.screenFd != xf86Info.consoleFd) 701 { 702 close(xf86Info.screenFd); 703 close(xf86Info.consoleFd); 704 if ((xf86Info.consoleFd = open("/dev/console",O_RDONLY,0)) <0) 705 { 706 xf86FatalError("xf86CloseConsole: Cannot open /dev/console (%s)", 707 strerror(errno)); 708 } 709 } 710 close(xf86Info.consoleFd); 711 if (devConsoleFd >= 0) 712 close(devConsoleFd); 713 return; 714} 715 716int 717xf86ProcessArgument(int argc, char *argv[], int i) 718{ 719 /* 720 * Keep server from detaching from controlling tty. This is useful 721 * when debugging (so the server can receive keyboard signals. 722 */ 723 if (!strcmp(argv[i], "-keeptty")) 724 { 725 KeepTty = TRUE; 726 return 1; 727 } 728#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) 729 if (!strcmp(argv[i], "-sharevts")) 730 { 731 ShareVTs = TRUE; 732 return 1; 733 } 734 if ((argv[i][0] == 'v') && (argv[i][1] == 't')) 735 { 736 if (sscanf(argv[i], "vt%2d", &VTnum) == 0 || 737 VTnum < 1 || VTnum > 12) 738 { 739 UseMsg(); 740 VTnum = -1; 741 return 0; 742 } 743 return 1; 744 } 745#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ 746 return 0; 747} 748 749void 750xf86UseMsg() 751{ 752#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) 753 ErrorF("vtXX use the specified VT number (1-12)\n"); 754 ErrorF("-sharevts share VTs with another X server\n"); 755#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ 756 ErrorF("-keeptty "); 757 ErrorF("don't detach controlling tty (for debugging only)\n"); 758 return; 759} 760