~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/xfree86/os-support/bsd/bsd_init.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

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