xserver

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

posix_tty.c (14188B)


      1 /*
      2  * Copyright 1993-2003 by The XFree86 Project, Inc.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17  * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     20  * SOFTWARE.
     21  *
     22  * Except as contained in this notice, the name of the XFree86 Project shall
     23  * not be used in advertising or otherwise to promote the sale, use or other
     24  * dealings in this Software without prior written authorization from the
     25  * XFree86 Project.
     26  */
     27 /*
     28  *
     29  * Copyright (c) 1997  Metro Link Incorporated
     30  *
     31  * Permission is hereby granted, free of charge, to any person obtaining a
     32  * copy of this software and associated documentation files (the "Software"),
     33  * to deal in the Software without restriction, including without limitation
     34  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     35  * and/or sell copies of the Software, and to permit persons to whom the
     36  * Software is furnished to do so, subject to the following conditions:
     37  *
     38  * The above copyright notice and this permission notice shall be included in
     39  * all copies or substantial portions of the Software.
     40  *
     41  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     42  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     43  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     44  * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     45  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     46  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     47  * SOFTWARE.
     48  *
     49  * Except as contained in this notice, the name of the Metro Link shall not be
     50  * used in advertising or otherwise to promote the sale, use or other dealings
     51  * in this Software without prior written authorization from Metro Link.
     52  *
     53  */
     54 
     55 #ifdef HAVE_XORG_CONFIG_H
     56 #include <xorg-config.h>
     57 #endif
     58 
     59 #include <X11/X.h>
     60 #include <xserver_poll.h>
     61 #include "xf86.h"
     62 #include "xf86Priv.h"
     63 #include "xf86_OSlib.h"
     64 
     65 static int
     66 GetBaud(int baudrate)
     67 {
     68 #ifdef B300
     69     if (baudrate == 300)
     70         return B300;
     71 #endif
     72 #ifdef B1200
     73     if (baudrate == 1200)
     74         return B1200;
     75 #endif
     76 #ifdef B2400
     77     if (baudrate == 2400)
     78         return B2400;
     79 #endif
     80 #ifdef B4800
     81     if (baudrate == 4800)
     82         return B4800;
     83 #endif
     84 #ifdef B9600
     85     if (baudrate == 9600)
     86         return B9600;
     87 #endif
     88 #ifdef B19200
     89     if (baudrate == 19200)
     90         return B19200;
     91 #endif
     92 #ifdef B38400
     93     if (baudrate == 38400)
     94         return B38400;
     95 #endif
     96 #ifdef B57600
     97     if (baudrate == 57600)
     98         return B57600;
     99 #endif
    100 #ifdef B115200
    101     if (baudrate == 115200)
    102         return B115200;
    103 #endif
    104 #ifdef B230400
    105     if (baudrate == 230400)
    106         return B230400;
    107 #endif
    108 #ifdef B460800
    109     if (baudrate == 460800)
    110         return B460800;
    111 #endif
    112     return 0;
    113 }
    114 
    115 int
    116 xf86OpenSerial(XF86OptionPtr options)
    117 {
    118     struct termios t;
    119     int fd, i;
    120     char *dev;
    121 
    122     dev = xf86SetStrOption(options, "Device", NULL);
    123     if (!dev) {
    124         xf86Msg(X_ERROR, "xf86OpenSerial: No Device specified.\n");
    125         return -1;
    126     }
    127 
    128     fd = xf86CheckIntOption(options, "fd", -1);
    129 
    130     if (fd == -1)
    131         SYSCALL(fd = open(dev, O_RDWR | O_NONBLOCK));
    132 
    133     if (fd == -1) {
    134         xf86Msg(X_ERROR,
    135                 "xf86OpenSerial: Cannot open device %s\n\t%s.\n",
    136                 dev, strerror(errno));
    137         free(dev);
    138         return -1;
    139     }
    140 
    141     if (!isatty(fd)) {
    142         /* Allow non-tty devices to be opened. */
    143         free(dev);
    144         return fd;
    145     }
    146 
    147     /* set up default port parameters */
    148     SYSCALL(tcgetattr(fd, &t));
    149     t.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR
    150                    | IGNCR | ICRNL | IXON);
    151     t.c_oflag &= ~OPOST;
    152     t.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    153     t.c_cflag &= ~(CSIZE | PARENB);
    154     t.c_cflag |= CS8 | CLOCAL;
    155 
    156     cfsetispeed(&t, B9600);
    157     cfsetospeed(&t, B9600);
    158     t.c_cc[VMIN] = 1;
    159     t.c_cc[VTIME] = 0;
    160 
    161     SYSCALL(tcsetattr(fd, TCSANOW, &t));
    162 
    163     if (xf86SetSerial(fd, options) == -1) {
    164         SYSCALL(close(fd));
    165         free(dev);
    166         return -1;
    167     }
    168 
    169     SYSCALL(i = fcntl(fd, F_GETFL, 0));
    170     if (i == -1) {
    171         SYSCALL(close(fd));
    172         free(dev);
    173         return -1;
    174     }
    175     i &= ~O_NONBLOCK;
    176     SYSCALL(i = fcntl(fd, F_SETFL, i));
    177     if (i == -1) {
    178         SYSCALL(close(fd));
    179         free(dev);
    180         return -1;
    181     }
    182     free(dev);
    183     return fd;
    184 }
    185 
    186 int
    187 xf86SetSerial(int fd, XF86OptionPtr options)
    188 {
    189     struct termios t;
    190     int val;
    191     char *s;
    192     int baud, r;
    193 
    194     if (fd < 0)
    195         return -1;
    196 
    197     /* Don't try to set parameters for non-tty devices. */
    198     if (!isatty(fd))
    199         return 0;
    200 
    201     SYSCALL(tcgetattr(fd, &t));
    202 
    203     if ((val = xf86SetIntOption(options, "BaudRate", 0))) {
    204         if ((baud = GetBaud(val))) {
    205             cfsetispeed(&t, baud);
    206             cfsetospeed(&t, baud);
    207         }
    208         else {
    209             xf86Msg(X_ERROR, "Invalid Option BaudRate value: %d\n", val);
    210             return -1;
    211         }
    212     }
    213 
    214     if ((val = xf86SetIntOption(options, "StopBits", 0))) {
    215         switch (val) {
    216         case 1:
    217             t.c_cflag &= ~(CSTOPB);
    218             break;
    219         case 2:
    220             t.c_cflag |= CSTOPB;
    221             break;
    222         default:
    223             xf86Msg(X_ERROR, "Invalid Option StopBits value: %d\n", val);
    224             return -1;
    225             break;
    226         }
    227     }
    228 
    229     if ((val = xf86SetIntOption(options, "DataBits", 0))) {
    230         switch (val) {
    231         case 5:
    232             t.c_cflag &= ~(CSIZE);
    233             t.c_cflag |= CS5;
    234             break;
    235         case 6:
    236             t.c_cflag &= ~(CSIZE);
    237             t.c_cflag |= CS6;
    238             break;
    239         case 7:
    240             t.c_cflag &= ~(CSIZE);
    241             t.c_cflag |= CS7;
    242             break;
    243         case 8:
    244             t.c_cflag &= ~(CSIZE);
    245             t.c_cflag |= CS8;
    246             break;
    247         default:
    248             xf86Msg(X_ERROR, "Invalid Option DataBits value: %d\n", val);
    249             return -1;
    250             break;
    251         }
    252     }
    253 
    254     if ((s = xf86SetStrOption(options, "Parity", NULL))) {
    255         if (xf86NameCmp(s, "Odd") == 0) {
    256             t.c_cflag |= PARENB | PARODD;
    257         }
    258         else if (xf86NameCmp(s, "Even") == 0) {
    259             t.c_cflag |= PARENB;
    260             t.c_cflag &= ~(PARODD);
    261         }
    262         else if (xf86NameCmp(s, "None") == 0) {
    263             t.c_cflag &= ~(PARENB);
    264         }
    265         else {
    266             xf86Msg(X_ERROR, "Invalid Option Parity value: %s\n", s);
    267             free(s);
    268             return -1;
    269         }
    270         free(s);
    271     }
    272 
    273     if ((val = xf86SetIntOption(options, "Vmin", -1)) != -1) {
    274         t.c_cc[VMIN] = val;
    275     }
    276     if ((val = xf86SetIntOption(options, "Vtime", -1)) != -1) {
    277         t.c_cc[VTIME] = val;
    278     }
    279 
    280     if ((s = xf86SetStrOption(options, "FlowControl", NULL))) {
    281         xf86MarkOptionUsedByName(options, "FlowControl");
    282         if (xf86NameCmp(s, "Xoff") == 0) {
    283             t.c_iflag |= IXOFF;
    284         }
    285         else if (xf86NameCmp(s, "Xon") == 0) {
    286             t.c_iflag |= IXON;
    287         }
    288         else if (xf86NameCmp(s, "XonXoff") == 0) {
    289             t.c_iflag |= IXON | IXOFF;
    290         }
    291         else if (xf86NameCmp(s, "None") == 0) {
    292             t.c_iflag &= ~(IXON | IXOFF);
    293         }
    294         else {
    295             xf86Msg(X_ERROR, "Invalid Option FlowControl value: %s\n", s);
    296             free(s);
    297             return -1;
    298         }
    299         free(s);
    300     }
    301 
    302     if ((xf86SetBoolOption(options, "ClearDTR", FALSE))) {
    303 #ifdef CLEARDTR_SUPPORT
    304 #if defined(TIOCMBIC)
    305         val = TIOCM_DTR;
    306         SYSCALL(ioctl(fd, TIOCMBIC, &val));
    307 #else
    308         SYSCALL(ioctl(fd, TIOCCDTR, NULL));
    309 #endif
    310 #else
    311         xf86Msg(X_WARNING, "Option ClearDTR not supported on this OS\n");
    312         return -1;
    313 #endif
    314         xf86MarkOptionUsedByName(options, "ClearDTR");
    315     }
    316 
    317     if ((xf86SetBoolOption(options, "ClearRTS", FALSE))) {
    318         xf86Msg(X_WARNING, "Option ClearRTS not supported on this OS\n");
    319         return -1;
    320         xf86MarkOptionUsedByName(options, "ClearRTS");
    321     }
    322 
    323     SYSCALL(r = tcsetattr(fd, TCSANOW, &t));
    324     return r;
    325 }
    326 
    327 int
    328 xf86SetSerialSpeed(int fd, int speed)
    329 {
    330     struct termios t;
    331     int baud, r;
    332 
    333     if (fd < 0)
    334         return -1;
    335 
    336     /* Don't try to set parameters for non-tty devices. */
    337     if (!isatty(fd))
    338         return 0;
    339 
    340     SYSCALL(tcgetattr(fd, &t));
    341 
    342     if ((baud = GetBaud(speed))) {
    343         cfsetispeed(&t, baud);
    344         cfsetospeed(&t, baud);
    345     }
    346     else {
    347         xf86Msg(X_ERROR, "Invalid Option BaudRate value: %d\n", speed);
    348         return -1;
    349     }
    350 
    351     SYSCALL(r = tcsetattr(fd, TCSANOW, &t));
    352     return r;
    353 }
    354 
    355 int
    356 xf86ReadSerial(int fd, void *buf, int count)
    357 {
    358     int r;
    359     int i;
    360 
    361     SYSCALL(r = read(fd, buf, count));
    362     DebugF("ReadingSerial: 0x%x", (unsigned char) *(((unsigned char *) buf)));
    363     for (i = 1; i < r; i++)
    364         DebugF(", 0x%x", (unsigned char) *(((unsigned char *) buf) + i));
    365     DebugF("\n");
    366     return r;
    367 }
    368 
    369 int
    370 xf86WriteSerial(int fd, const void *buf, int count)
    371 {
    372     int r;
    373     int i;
    374 
    375     DebugF("WritingSerial: 0x%x", (unsigned char) *(((unsigned char *) buf)));
    376     for (i = 1; i < count; i++)
    377         DebugF(", 0x%x", (unsigned char) *(((unsigned char *) buf) + i));
    378     DebugF("\n");
    379     SYSCALL(r = write(fd, buf, count));
    380     return r;
    381 }
    382 
    383 int
    384 xf86CloseSerial(int fd)
    385 {
    386     int r;
    387 
    388     SYSCALL(r = close(fd));
    389     return r;
    390 }
    391 
    392 int
    393 xf86WaitForInput(int fd, int timeout)
    394 {
    395     int r;
    396     struct pollfd poll_fd;
    397 
    398     poll_fd.fd = fd;
    399     poll_fd.events = POLLIN;
    400 
    401     /* convert microseconds to milliseconds */
    402     timeout = (timeout + 999) / 1000;
    403 
    404     if (fd >= 0) {
    405         SYSCALL(r = xserver_poll(&poll_fd, 1, timeout));
    406     }
    407     else {
    408         SYSCALL(r = xserver_poll(&poll_fd, 0, timeout));
    409     }
    410     xf86ErrorFVerb(9, "poll returned %d\n", r);
    411     return r;
    412 }
    413 
    414 int
    415 xf86SerialSendBreak(int fd, int duration)
    416 {
    417     int r;
    418 
    419     SYSCALL(r = tcsendbreak(fd, duration));
    420     return r;
    421 
    422 }
    423 
    424 int
    425 xf86FlushInput(int fd)
    426 {
    427     struct pollfd poll_fd;
    428     /* this needs to be big enough to flush an evdev event. */
    429     char c[256];
    430 
    431     DebugF("FlushingSerial\n");
    432     if (tcflush(fd, TCIFLUSH) == 0)
    433         return 0;
    434 
    435     poll_fd.fd = fd;
    436     poll_fd.events = POLLIN;
    437     while (xserver_poll(&poll_fd, 1, 0) > 0) {
    438         if (read(fd, &c, sizeof(c)) < 1)
    439             return 0;
    440     }
    441     return 0;
    442 }
    443 
    444 static struct states {
    445     int xf;
    446     int os;
    447 } modemStates[] = {
    448 #ifdef TIOCM_LE
    449     {
    450     XF86_M_LE, TIOCM_LE},
    451 #endif
    452 #ifdef TIOCM_DTR
    453     {
    454     XF86_M_DTR, TIOCM_DTR},
    455 #endif
    456 #ifdef TIOCM_RTS
    457     {
    458     XF86_M_RTS, TIOCM_RTS},
    459 #endif
    460 #ifdef TIOCM_ST
    461     {
    462     XF86_M_ST, TIOCM_ST},
    463 #endif
    464 #ifdef TIOCM_SR
    465     {
    466     XF86_M_SR, TIOCM_SR},
    467 #endif
    468 #ifdef TIOCM_CTS
    469     {
    470     XF86_M_CTS, TIOCM_CTS},
    471 #endif
    472 #ifdef TIOCM_CAR
    473     {
    474     XF86_M_CAR, TIOCM_CAR},
    475 #elif defined(TIOCM_CD)
    476     {
    477     XF86_M_CAR, TIOCM_CD},
    478 #endif
    479 #ifdef TIOCM_RNG
    480     {
    481     XF86_M_RNG, TIOCM_RNG},
    482 #elif defined(TIOCM_RI)
    483     {
    484     XF86_M_CAR, TIOCM_RI},
    485 #endif
    486 #ifdef TIOCM_DSR
    487     {
    488     XF86_M_DSR, TIOCM_DSR},
    489 #endif
    490 };
    491 
    492 static int numStates = ARRAY_SIZE(modemStates);
    493 
    494 static int
    495 xf2osState(int state)
    496 {
    497     int i;
    498     int ret = 0;
    499 
    500     for (i = 0; i < numStates; i++)
    501         if (state & modemStates[i].xf)
    502             ret |= modemStates[i].os;
    503     return ret;
    504 }
    505 
    506 static int
    507 os2xfState(int state)
    508 {
    509     int i;
    510     int ret = 0;
    511 
    512     for (i = 0; i < numStates; i++)
    513         if (state & modemStates[i].os)
    514             ret |= modemStates[i].xf;
    515     return ret;
    516 }
    517 
    518 static int
    519 getOsStateMask(void)
    520 {
    521     int i;
    522     int ret = 0;
    523 
    524     for (i = 0; i < numStates; i++)
    525         ret |= modemStates[i].os;
    526     return ret;
    527 }
    528 
    529 static int osStateMask = 0;
    530 
    531 int
    532 xf86SetSerialModemState(int fd, int state)
    533 {
    534     int ret;
    535     int s;
    536 
    537     if (fd < 0)
    538         return -1;
    539 
    540     /* Don't try to set parameters for non-tty devices. */
    541     if (!isatty(fd))
    542         return 0;
    543 
    544 #ifndef TIOCMGET
    545     return -1;
    546 #else
    547     if (!osStateMask)
    548         osStateMask = getOsStateMask();
    549 
    550     state = xf2osState(state);
    551     SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
    552     if (ret < 0)
    553         return -1;
    554     s &= ~osStateMask;
    555     s |= state;
    556     SYSCALL((ret = ioctl(fd, TIOCMSET, &s)));
    557     if (ret < 0)
    558         return -1;
    559     else
    560         return 0;
    561 #endif
    562 }
    563 
    564 int
    565 xf86GetSerialModemState(int fd)
    566 {
    567     int ret;
    568     int s;
    569 
    570     if (fd < 0)
    571         return -1;
    572 
    573     /* Don't try to set parameters for non-tty devices. */
    574     if (!isatty(fd))
    575         return 0;
    576 
    577 #ifndef TIOCMGET
    578     return -1;
    579 #else
    580     SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
    581     if (ret < 0)
    582         return -1;
    583     return os2xfState(s);
    584 #endif
    585 }
    586 
    587 int
    588 xf86SerialModemSetBits(int fd, int bits)
    589 {
    590     int ret;
    591     int s;
    592 
    593     if (fd < 0)
    594         return -1;
    595 
    596     /* Don't try to set parameters for non-tty devices. */
    597     if (!isatty(fd))
    598         return 0;
    599 
    600 #ifndef TIOCMGET
    601     return -1;
    602 #else
    603     s = xf2osState(bits);
    604     SYSCALL((ret = ioctl(fd, TIOCMBIS, &s)));
    605     return ret;
    606 #endif
    607 }
    608 
    609 int
    610 xf86SerialModemClearBits(int fd, int bits)
    611 {
    612     int ret;
    613     int s;
    614 
    615     if (fd < 0)
    616         return -1;
    617 
    618     /* Don't try to set parameters for non-tty devices. */
    619     if (!isatty(fd))
    620         return 0;
    621 
    622 #ifndef TIOCMGET
    623     return -1;
    624 #else
    625     s = xf2osState(bits);
    626     SYSCALL((ret = ioctl(fd, TIOCMBIC, &s)));
    627     return ret;
    628 #endif
    629 }