xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

lnx_init.c (12577B)


      1 /*
      2  * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
      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 Orest Zborowski and David Wexelblat
     10  * not be used in advertising or publicity pertaining to distribution of
     11  * the software without specific, written prior permission.  Orest Zborowski
     12  * and 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  * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
     17  * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
     18  * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT BE LIABLE
     19  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     20  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     21  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     22  * OR IN 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 #include <X11/Xmd.h>
     32 
     33 #include "compiler.h"
     34 #include "linux.h"
     35 
     36 #include "xf86.h"
     37 #include "xf86Priv.h"
     38 #include "xf86_OSlib.h"
     39 
     40 #include <sys/stat.h>
     41 #ifdef HAVE_SYS_SYSMACROS_H
     42 #include <sys/sysmacros.h>
     43 #endif
     44 
     45 #ifndef K_OFF
     46 #define K_OFF 0x4
     47 #endif
     48 
     49 static Bool KeepTty = FALSE;
     50 static int activeVT = -1;
     51 
     52 static char vtname[11];
     53 static struct termios tty_attr; /* tty state to restore */
     54 static int tty_mode;            /* kbd mode to restore */
     55 
     56 static void
     57 drain_console(int fd, void *closure)
     58 {
     59     errno = 0;
     60     if (tcflush(fd, TCIOFLUSH) == -1 && errno == EIO) {
     61         xf86SetConsoleHandler(NULL, NULL);
     62     }
     63 }
     64 
     65 static int
     66 switch_to(int vt, const char *from)
     67 {
     68     int ret;
     69 
     70     SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_ACTIVATE, vt));
     71     if (ret < 0) {
     72         xf86Msg(X_WARNING, "%s: VT_ACTIVATE failed: %s\n", from, strerror(errno));
     73         return 0;
     74     }
     75 
     76     SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_WAITACTIVE, vt));
     77     if (ret < 0) {
     78         xf86Msg(X_WARNING, "%s: VT_WAITACTIVE failed: %s\n", from, strerror(errno));
     79         return 0;
     80     }
     81 
     82     return 1;
     83 }
     84 
     85 #pragma GCC diagnostic push
     86 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
     87 
     88 int
     89 linux_parse_vt_settings(int may_fail)
     90 {
     91     int i, fd = -1, ret, current_vt = -1;
     92     struct vt_stat vts;
     93     struct stat st;
     94     MessageType from = X_PROBED;
     95 
     96     /* Only do this once */
     97     static int vt_settings_parsed = 0;
     98 
     99     if (vt_settings_parsed)
    100         return 1;
    101 
    102     /*
    103      * setup the virtual terminal manager
    104      */
    105     if (xf86Info.vtno != -1) {
    106         from = X_CMDLINE;
    107     }
    108     else {
    109         fd = open("/dev/tty0", O_WRONLY, 0);
    110         if (fd < 0) {
    111             if (may_fail)
    112                 return 0;
    113             FatalError("parse_vt_settings: Cannot open /dev/tty0 (%s)\n",
    114                        strerror(errno));
    115         }
    116 
    117         if (xf86Info.ShareVTs) {
    118             SYSCALL(ret = ioctl(fd, VT_GETSTATE, &vts));
    119             if (ret < 0) {
    120                 if (may_fail)
    121                     return 0;
    122                 FatalError("parse_vt_settings: Cannot find the current"
    123                            " VT (%s)\n", strerror(errno));
    124             }
    125             xf86Info.vtno = vts.v_active;
    126         }
    127         else {
    128             SYSCALL(ret = ioctl(fd, VT_OPENQRY, &xf86Info.vtno));
    129             if (ret < 0) {
    130                 if (may_fail)
    131                     return 0;
    132                 FatalError("parse_vt_settings: Cannot find a free VT: "
    133                            "%s\n", strerror(errno));
    134             }
    135             if (xf86Info.vtno == -1) {
    136                 if (may_fail)
    137                     return 0;
    138                 FatalError("parse_vt_settings: Cannot find a free VT\n");
    139             }
    140         }
    141         close(fd);
    142     }
    143 
    144     xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
    145 
    146     /* Some of stdin / stdout / stderr maybe redirected to a file */
    147     for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) {
    148         ret = fstat(i, &st);
    149         if (ret == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) {
    150             current_vt = minor(st.st_rdev);
    151             break;
    152         }
    153     }
    154 
    155     if (!KeepTty && current_vt == xf86Info.vtno) {
    156         xf86Msg(X_PROBED,
    157                 "controlling tty is VT number %d, auto-enabling KeepTty\n",
    158                 current_vt);
    159         KeepTty = TRUE;
    160     }
    161 
    162     vt_settings_parsed = 1;
    163     return 1;
    164 }
    165 
    166 int
    167 linux_get_keeptty(void)
    168 {
    169     return KeepTty;
    170 }
    171 
    172 void
    173 xf86OpenConsole(void)
    174 {
    175     int i, ret;
    176     struct vt_stat vts;
    177     struct vt_mode VT;
    178     const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
    179 
    180     if (serverGeneration == 1) {
    181         linux_parse_vt_settings(FALSE);
    182 
    183         if (!KeepTty) {
    184             pid_t ppid = getppid();
    185             pid_t ppgid;
    186 
    187             ppgid = getpgid(ppid);
    188 
    189             /*
    190              * change to parent process group that pgid != pid so
    191              * that setsid() doesn't fail and we become process
    192              * group leader
    193              */
    194             if (setpgid(0, ppgid) < 0)
    195                 xf86Msg(X_WARNING, "xf86OpenConsole: setpgid failed: %s\n",
    196                         strerror(errno));
    197 
    198             /* become process group leader */
    199             if ((setsid() < 0))
    200                 xf86Msg(X_WARNING, "xf86OpenConsole: setsid failed: %s\n",
    201                         strerror(errno));
    202         }
    203 
    204         i = 0;
    205         while (vcs[i] != NULL) {
    206             snprintf(vtname, sizeof(vtname), vcs[i], xf86Info.vtno);    /* /dev/tty1-64 */
    207             if ((xf86Info.consoleFd = open(vtname, O_RDWR | O_NDELAY, 0)) >= 0)
    208                 break;
    209             i++;
    210         }
    211 
    212         if (xf86Info.consoleFd < 0)
    213             FatalError("xf86OpenConsole: Cannot open virtual console"
    214                        " %d (%s)\n", xf86Info.vtno, strerror(errno));
    215 
    216         /*
    217          * Linux doesn't switch to an active vt after the last close of a vt,
    218          * so we do this ourselves by remembering which is active now.
    219          */
    220         SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts));
    221         if (ret < 0)
    222             xf86Msg(X_WARNING, "xf86OpenConsole: VT_GETSTATE failed: %s\n",
    223                     strerror(errno));
    224         else
    225             activeVT = vts.v_active;
    226 
    227         if (!xf86Info.ShareVTs) {
    228             struct termios nTty;
    229 
    230             /*
    231              * now get the VT.  This _must_ succeed, or else fail completely.
    232              */
    233             if (!switch_to(xf86Info.vtno, "xf86OpenConsole"))
    234                 FatalError("xf86OpenConsole: Switching VT failed\n");
    235 
    236             SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT));
    237             if (ret < 0)
    238                 FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
    239                            strerror(errno));
    240 
    241             OsSignal(SIGUSR1, xf86VTRequest);
    242 
    243             VT.mode = VT_PROCESS;
    244             VT.relsig = SIGUSR1;
    245             VT.acqsig = SIGUSR1;
    246 
    247             SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT));
    248             if (ret < 0)
    249                 FatalError
    250                     ("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
    251                      strerror(errno));
    252 
    253             SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS));
    254             if (ret < 0)
    255                 FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
    256                            strerror(errno));
    257 
    258             tcgetattr(xf86Info.consoleFd, &tty_attr);
    259             SYSCALL(ioctl(xf86Info.consoleFd, KDGKBMODE, &tty_mode));
    260 
    261             /* disable kernel special keys and buffering */
    262             SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMODE, K_OFF));
    263             if (ret < 0)
    264             {
    265                 /* fine, just disable special keys */
    266                 SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW));
    267                 if (ret < 0)
    268                     FatalError("xf86OpenConsole: KDSKBMODE K_RAW failed %s\n",
    269                                strerror(errno));
    270 
    271                 /* ... and drain events, else the kernel gets angry */
    272                 xf86SetConsoleHandler(drain_console, NULL);
    273             }
    274 
    275             nTty = tty_attr;
    276             nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
    277             nTty.c_oflag = 0;
    278             nTty.c_cflag = CREAD | CS8;
    279             nTty.c_lflag = 0;
    280             nTty.c_cc[VTIME] = 0;
    281             nTty.c_cc[VMIN] = 1;
    282             cfsetispeed(&nTty, 9600);
    283             cfsetospeed(&nTty, 9600);
    284             tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
    285         }
    286     }
    287     else {                      /* serverGeneration != 1 */
    288         if (!xf86Info.ShareVTs && xf86Info.autoVTSwitch) {
    289             /* now get the VT */
    290             if (!switch_to(xf86Info.vtno, "xf86OpenConsole"))
    291                 FatalError("xf86OpenConsole: Switching VT failed\n");
    292         }
    293     }
    294 }
    295 
    296 #pragma GCC diagnostic pop
    297 
    298 void
    299 xf86CloseConsole(void)
    300 {
    301     struct vt_mode VT;
    302     struct vt_stat vts;
    303     int ret;
    304 
    305     if (xf86Info.ShareVTs) {
    306         close(xf86Info.consoleFd);
    307         return;
    308     }
    309 
    310     /*
    311      * unregister the drain_console handler
    312      * - what to do if someone else changed it in the meantime?
    313      */
    314     xf86SetConsoleHandler(NULL, NULL);
    315 
    316     /* Back to text mode ... */
    317     SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT));
    318     if (ret < 0)
    319         xf86Msg(X_WARNING, "xf86CloseConsole: KDSETMODE failed: %s\n",
    320                 strerror(errno));
    321 
    322     SYSCALL(ioctl(xf86Info.consoleFd, KDSKBMODE, tty_mode));
    323     tcsetattr(xf86Info.consoleFd, TCSANOW, &tty_attr);
    324 
    325     SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT));
    326     if (ret < 0)
    327         xf86Msg(X_WARNING, "xf86CloseConsole: VT_GETMODE failed: %s\n",
    328                 strerror(errno));
    329     else {
    330         /* set dflt vt handling */
    331         VT.mode = VT_AUTO;
    332         SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT));
    333         if (ret < 0)
    334             xf86Msg(X_WARNING, "xf86CloseConsole: VT_SETMODE failed: %s\n",
    335                     strerror(errno));
    336     }
    337 
    338     if (xf86Info.autoVTSwitch) {
    339         /*
    340         * Perform a switch back to the active VT when we were started if our
    341         * vt is active now.
    342         */
    343         if (activeVT >= 0) {
    344             SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts));
    345             if (ret < 0) {
    346                 xf86Msg(X_WARNING, "xf86OpenConsole: VT_GETSTATE failed: %s\n",
    347                         strerror(errno));
    348             } else {
    349                 if (vts.v_active == xf86Info.vtno) {
    350                     switch_to(activeVT, "xf86CloseConsole");
    351                 }
    352             }
    353             activeVT = -1;
    354         }
    355     }
    356     close(xf86Info.consoleFd);  /* make the vt-manager happy */
    357 }
    358 
    359 #define CHECK_FOR_REQUIRED_ARGUMENT() \
    360     if (((i + 1) >= argc) || (!argv[i + 1])) { 				\
    361       ErrorF("Required argument to %s not specified\n", argv[i]); 	\
    362       UseMsg(); 							\
    363       FatalError("Required argument to %s not specified\n", argv[i]);	\
    364     }
    365 
    366 int
    367 xf86ProcessArgument(int argc, char *argv[], int i)
    368 {
    369     /*
    370      * Keep server from detaching from controlling tty.  This is useful
    371      * when debugging (so the server can receive keyboard signals.
    372      */
    373     if (!strcmp(argv[i], "-keeptty")) {
    374         KeepTty = TRUE;
    375         return 1;
    376     }
    377 
    378     if ((argv[i][0] == 'v') && (argv[i][1] == 't')) {
    379         if (sscanf(argv[i], "vt%2d", &xf86Info.vtno) == 0) {
    380             UseMsg();
    381             xf86Info.vtno = -1;
    382             return 0;
    383         }
    384         return 1;
    385     }
    386 
    387     if (!strcmp(argv[i], "-masterfd")) {
    388         CHECK_FOR_REQUIRED_ARGUMENT();
    389         if (xf86PrivsElevated())
    390             FatalError("\nCannot specify -masterfd when server is setuid/setgid\n");
    391         if (sscanf(argv[++i], "%d", &xf86DRMMasterFd) != 1) {
    392             UseMsg();
    393             xf86DRMMasterFd = -1;
    394             return 0;
    395         }
    396         return 2;
    397     }
    398 
    399     return 0;
    400 }
    401 
    402 void
    403 xf86UseMsg(void)
    404 {
    405     ErrorF("vtXX                   use the specified VT number\n");
    406     ErrorF("-keeptty               ");
    407     ErrorF("don't detach controlling tty (for debugging only)\n");
    408     ErrorF("-masterfd <fd>         use the specified fd as the DRM master fd (not if setuid/gid)\n");
    409 }
    410 
    411 void
    412 xf86OSInputThreadInit(void)
    413 {
    414     return;
    415 }