xserver

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

Layout.c (18181B)


      1 /*
      2  *
      3  * Copyright (c) 1997  Metro Link Incorporated
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be included in
     13  * all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     20  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     21  * SOFTWARE.
     22  *
     23  * Except as contained in this notice, the name of the Metro Link shall not be
     24  * used in advertising or otherwise to promote the sale, use or other dealings
     25  * in this Software without prior written authorization from Metro Link.
     26  *
     27  */
     28 /*
     29  * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
     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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     45  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     46  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     47  * OTHER DEALINGS IN THE SOFTWARE.
     48  *
     49  * Except as contained in this notice, the name of the copyright holder(s)
     50  * and author(s) shall not be used in advertising or otherwise to promote
     51  * the sale, use or other dealings in this Software without prior written
     52  * authorization from the copyright holder(s) and author(s).
     53  */
     54 
     55 #ifdef HAVE_XORG_CONFIG_H
     56 #include <xorg-config.h>
     57 #endif
     58 
     59 #include "xf86Parser.h"
     60 #include "xf86tokens.h"
     61 #include "Configint.h"
     62 #include <string.h>
     63 #include "optionstr.h"
     64 
     65 /* Needed for auto server layout */
     66 extern int xf86CheckBoolOption(void *optlist, const char *name, int deflt);
     67 
     68 
     69 static const xf86ConfigSymTabRec LayoutTab[] = {
     70     {ENDSECTION, "endsection"},
     71     {SCREEN, "screen"},
     72     {IDENTIFIER, "identifier"},
     73     {MATCHSEAT, "matchseat"},
     74     {INACTIVE, "inactive"},
     75     {INPUTDEVICE, "inputdevice"},
     76     {OPTION, "option"},
     77     {-1, ""},
     78 };
     79 
     80 static const xf86ConfigSymTabRec AdjTab[] = {
     81     {RIGHTOF, "rightof"},
     82     {LEFTOF, "leftof"},
     83     {ABOVE, "above"},
     84     {BELOW, "below"},
     85     {RELATIVE, "relative"},
     86     {ABSOLUTE, "absolute"},
     87     {-1, ""},
     88 };
     89 
     90 #define CLEANUP xf86freeLayoutList
     91 
     92 XF86ConfLayoutPtr
     93 xf86parseLayoutSection(void)
     94 {
     95     int has_ident = FALSE;
     96     int token;
     97 
     98     parsePrologue(XF86ConfLayoutPtr, XF86ConfLayoutRec)
     99 
    100         while ((token = xf86getToken(LayoutTab)) != ENDSECTION) {
    101         switch (token) {
    102         case COMMENT:
    103             ptr->lay_comment = xf86addComment(ptr->lay_comment, xf86_lex_val.str);
    104             break;
    105         case IDENTIFIER:
    106             if (xf86getSubToken(&(ptr->lay_comment)) != STRING)
    107                 Error(QUOTE_MSG, "Identifier");
    108             if (has_ident == TRUE)
    109                 Error(MULTIPLE_MSG, "Identifier");
    110             ptr->lay_identifier = xf86_lex_val.str;
    111             has_ident = TRUE;
    112             break;
    113         case MATCHSEAT:
    114             if (xf86getSubToken(&(ptr->lay_comment)) != STRING)
    115                 Error(QUOTE_MSG, "MatchSeat");
    116             ptr->match_seat = xf86_lex_val.str;
    117             break;
    118         case INACTIVE:
    119         {
    120             XF86ConfInactivePtr iptr;
    121 
    122             iptr = calloc(1, sizeof(XF86ConfInactiveRec));
    123             iptr->list.next = NULL;
    124             if (xf86getSubToken(&(ptr->lay_comment)) != STRING) {
    125                 free(iptr);
    126                 Error(INACTIVE_MSG);
    127             }
    128             iptr->inactive_device_str = xf86_lex_val.str;
    129             ptr->lay_inactive_lst = (XF86ConfInactivePtr)
    130                 xf86addListItem((glp) ptr->lay_inactive_lst, (glp) iptr);
    131         }
    132             break;
    133         case SCREEN:
    134         {
    135             XF86ConfAdjacencyPtr aptr;
    136             int absKeyword = 0;
    137 
    138             aptr = calloc(1, sizeof(XF86ConfAdjacencyRec));
    139             aptr->list.next = NULL;
    140             aptr->adj_scrnum = -1;
    141             aptr->adj_where = CONF_ADJ_OBSOLETE;
    142             aptr->adj_x = 0;
    143             aptr->adj_y = 0;
    144             aptr->adj_refscreen = NULL;
    145             if ((token = xf86getSubToken(&(ptr->lay_comment))) == NUMBER)
    146                 aptr->adj_scrnum = xf86_lex_val.num;
    147             else
    148                 xf86unGetToken(token);
    149             token = xf86getSubToken(&(ptr->lay_comment));
    150             if (token != STRING) {
    151                 free(aptr);
    152                 Error(SCREEN_MSG);
    153             }
    154             aptr->adj_screen_str = xf86_lex_val.str;
    155 
    156             token = xf86getSubTokenWithTab(&(ptr->lay_comment), AdjTab);
    157             switch (token) {
    158             case RIGHTOF:
    159                 aptr->adj_where = CONF_ADJ_RIGHTOF;
    160                 break;
    161             case LEFTOF:
    162                 aptr->adj_where = CONF_ADJ_LEFTOF;
    163                 break;
    164             case ABOVE:
    165                 aptr->adj_where = CONF_ADJ_ABOVE;
    166                 break;
    167             case BELOW:
    168                 aptr->adj_where = CONF_ADJ_BELOW;
    169                 break;
    170             case RELATIVE:
    171                 aptr->adj_where = CONF_ADJ_RELATIVE;
    172                 break;
    173             case ABSOLUTE:
    174                 aptr->adj_where = CONF_ADJ_ABSOLUTE;
    175                 absKeyword = 1;
    176                 break;
    177             case EOF_TOKEN:
    178                 free(aptr);
    179                 Error(UNEXPECTED_EOF_MSG);
    180                 break;
    181             default:
    182                 xf86unGetToken(token);
    183                 token = xf86getSubToken(&(ptr->lay_comment));
    184                 if (token == STRING)
    185                     aptr->adj_where = CONF_ADJ_OBSOLETE;
    186                 else
    187                     aptr->adj_where = CONF_ADJ_ABSOLUTE;
    188             }
    189             switch (aptr->adj_where) {
    190             case CONF_ADJ_ABSOLUTE:
    191                 if (absKeyword)
    192                     token = xf86getSubToken(&(ptr->lay_comment));
    193                 if (token == NUMBER) {
    194                     aptr->adj_x = xf86_lex_val.num;
    195                     token = xf86getSubToken(&(ptr->lay_comment));
    196                     if (token != NUMBER) {
    197                         free(aptr);
    198                         Error(INVALID_SCR_MSG);
    199                     }
    200                     aptr->adj_y = xf86_lex_val.num;
    201                 }
    202                 else {
    203                     if (absKeyword) {
    204                         free(aptr);
    205                         Error(INVALID_SCR_MSG);
    206                     }
    207                     else
    208                         xf86unGetToken(token);
    209                 }
    210                 break;
    211             case CONF_ADJ_RIGHTOF:
    212             case CONF_ADJ_LEFTOF:
    213             case CONF_ADJ_ABOVE:
    214             case CONF_ADJ_BELOW:
    215             case CONF_ADJ_RELATIVE:
    216                 token = xf86getSubToken(&(ptr->lay_comment));
    217                 if (token != STRING) {
    218                     free(aptr);
    219                     Error(INVALID_SCR_MSG);
    220                 }
    221                 aptr->adj_refscreen = xf86_lex_val.str;
    222                 if (aptr->adj_where == CONF_ADJ_RELATIVE) {
    223                     token = xf86getSubToken(&(ptr->lay_comment));
    224                     if (token != NUMBER) {
    225                         free(aptr);
    226                         Error(INVALID_SCR_MSG);
    227                     }
    228                     aptr->adj_x = xf86_lex_val.num;
    229                     token = xf86getSubToken(&(ptr->lay_comment));
    230                     if (token != NUMBER) {
    231                         free(aptr);
    232                         Error(INVALID_SCR_MSG);
    233                     }
    234                     aptr->adj_y = xf86_lex_val.num;
    235                 }
    236                 break;
    237             case CONF_ADJ_OBSOLETE:
    238                 /* top */
    239                 aptr->adj_top_str = xf86_lex_val.str;
    240 
    241                 /* bottom */
    242                 if (xf86getSubToken(&(ptr->lay_comment)) != STRING) {
    243                     free(aptr);
    244                     Error(SCREEN_MSG);
    245                 }
    246                 aptr->adj_bottom_str = xf86_lex_val.str;
    247 
    248                 /* left */
    249                 if (xf86getSubToken(&(ptr->lay_comment)) != STRING) {
    250                     free(aptr);
    251                     Error(SCREEN_MSG);
    252                 }
    253                 aptr->adj_left_str = xf86_lex_val.str;
    254 
    255                 /* right */
    256                 if (xf86getSubToken(&(ptr->lay_comment)) != STRING) {
    257                     free(aptr);
    258                     Error(SCREEN_MSG);
    259                 }
    260                 aptr->adj_right_str = xf86_lex_val.str;
    261 
    262             }
    263             ptr->lay_adjacency_lst = (XF86ConfAdjacencyPtr)
    264                 xf86addListItem((glp) ptr->lay_adjacency_lst, (glp) aptr);
    265         }
    266             break;
    267         case INPUTDEVICE:
    268         {
    269             XF86ConfInputrefPtr iptr;
    270 
    271             iptr = calloc(1, sizeof(XF86ConfInputrefRec));
    272             iptr->list.next = NULL;
    273             iptr->iref_option_lst = NULL;
    274             if (xf86getSubToken(&(ptr->lay_comment)) != STRING) {
    275                 free(iptr);
    276                 Error(INPUTDEV_MSG);
    277             }
    278             iptr->iref_inputdev_str = xf86_lex_val.str;
    279             while ((token = xf86getSubToken(&(ptr->lay_comment))) == STRING) {
    280                 iptr->iref_option_lst =
    281                     xf86addNewOption(iptr->iref_option_lst, xf86_lex_val.str, NULL);
    282             }
    283             xf86unGetToken(token);
    284             ptr->lay_input_lst = (XF86ConfInputrefPtr)
    285                 xf86addListItem((glp) ptr->lay_input_lst, (glp) iptr);
    286         }
    287             break;
    288         case OPTION:
    289             ptr->lay_option_lst = xf86parseOption(ptr->lay_option_lst);
    290             break;
    291         case EOF_TOKEN:
    292             Error(UNEXPECTED_EOF_MSG);
    293             break;
    294         default:
    295             Error(INVALID_KEYWORD_MSG, xf86tokenString());
    296             break;
    297         }
    298     }
    299 
    300     if (!has_ident)
    301         Error(NO_IDENT_MSG);
    302 
    303 #ifdef DEBUG
    304     printf("Layout section parsed\n");
    305 #endif
    306 
    307     return ptr;
    308 }
    309 
    310 #undef CLEANUP
    311 
    312 void
    313 xf86printLayoutSection(FILE * cf, XF86ConfLayoutPtr ptr)
    314 {
    315     XF86ConfAdjacencyPtr aptr;
    316     XF86ConfInactivePtr iptr;
    317     XF86ConfInputrefPtr inptr;
    318     XF86OptionPtr optr;
    319 
    320     while (ptr) {
    321         fprintf(cf, "Section \"ServerLayout\"\n");
    322         if (ptr->lay_comment)
    323             fprintf(cf, "%s", ptr->lay_comment);
    324         if (ptr->lay_identifier)
    325             fprintf(cf, "\tIdentifier     \"%s\"\n", ptr->lay_identifier);
    326 
    327         for (aptr = ptr->lay_adjacency_lst; aptr; aptr = aptr->list.next) {
    328             fprintf(cf, "\tScreen     ");
    329             if (aptr->adj_scrnum >= 0)
    330                 fprintf(cf, "%2d", aptr->adj_scrnum);
    331             else
    332                 fprintf(cf, "  ");
    333             fprintf(cf, "  \"%s\"", aptr->adj_screen_str);
    334             switch (aptr->adj_where) {
    335             case CONF_ADJ_OBSOLETE:
    336                 fprintf(cf, " \"%s\"", aptr->adj_top_str);
    337                 fprintf(cf, " \"%s\"", aptr->adj_bottom_str);
    338                 fprintf(cf, " \"%s\"", aptr->adj_right_str);
    339                 fprintf(cf, " \"%s\"\n", aptr->adj_left_str);
    340                 break;
    341             case CONF_ADJ_ABSOLUTE:
    342                 if (aptr->adj_x != -1)
    343                     fprintf(cf, " %d %d\n", aptr->adj_x, aptr->adj_y);
    344                 else
    345                     fprintf(cf, "\n");
    346                 break;
    347             case CONF_ADJ_RIGHTOF:
    348                 fprintf(cf, " RightOf \"%s\"\n", aptr->adj_refscreen);
    349                 break;
    350             case CONF_ADJ_LEFTOF:
    351                 fprintf(cf, " LeftOf \"%s\"\n", aptr->adj_refscreen);
    352                 break;
    353             case CONF_ADJ_ABOVE:
    354                 fprintf(cf, " Above \"%s\"\n", aptr->adj_refscreen);
    355                 break;
    356             case CONF_ADJ_BELOW:
    357                 fprintf(cf, " Below \"%s\"\n", aptr->adj_refscreen);
    358                 break;
    359             case CONF_ADJ_RELATIVE:
    360                 fprintf(cf, " Relative \"%s\" %d %d\n", aptr->adj_refscreen,
    361                         aptr->adj_x, aptr->adj_y);
    362                 break;
    363             }
    364         }
    365         for (iptr = ptr->lay_inactive_lst; iptr; iptr = iptr->list.next)
    366             fprintf(cf, "\tInactive       \"%s\"\n", iptr->inactive_device_str);
    367         for (inptr = ptr->lay_input_lst; inptr; inptr = inptr->list.next) {
    368             fprintf(cf, "\tInputDevice    \"%s\"", inptr->iref_inputdev_str);
    369             for (optr = inptr->iref_option_lst; optr; optr = optr->list.next) {
    370                 fprintf(cf, " \"%s\"", optr->opt_name);
    371             }
    372             fprintf(cf, "\n");
    373         }
    374         xf86printOptionList(cf, ptr->lay_option_lst, 1);
    375         fprintf(cf, "EndSection\n\n");
    376         ptr = ptr->list.next;
    377     }
    378 }
    379 
    380 static void
    381 xf86freeAdjacencyList(XF86ConfAdjacencyPtr ptr)
    382 {
    383     XF86ConfAdjacencyPtr prev;
    384 
    385     while (ptr) {
    386         TestFree(ptr->adj_screen_str);
    387         TestFree(ptr->adj_top_str);
    388         TestFree(ptr->adj_bottom_str);
    389         TestFree(ptr->adj_left_str);
    390         TestFree(ptr->adj_right_str);
    391 
    392         prev = ptr;
    393         ptr = ptr->list.next;
    394         free(prev);
    395     }
    396 
    397 }
    398 
    399 static void
    400 xf86freeInputrefList(XF86ConfInputrefPtr ptr)
    401 {
    402     XF86ConfInputrefPtr prev;
    403 
    404     while (ptr) {
    405         TestFree(ptr->iref_inputdev_str);
    406         xf86optionListFree(ptr->iref_option_lst);
    407         prev = ptr;
    408         ptr = ptr->list.next;
    409         free(prev);
    410     }
    411 
    412 }
    413 
    414 void
    415 xf86freeLayoutList(XF86ConfLayoutPtr ptr)
    416 {
    417     XF86ConfLayoutPtr prev;
    418 
    419     while (ptr) {
    420         TestFree(ptr->lay_identifier);
    421         TestFree(ptr->lay_comment);
    422         xf86freeAdjacencyList(ptr->lay_adjacency_lst);
    423         xf86freeInputrefList(ptr->lay_input_lst);
    424         prev = ptr;
    425         ptr = ptr->list.next;
    426         free(prev);
    427     }
    428 }
    429 
    430 int
    431 xf86layoutAddInputDevices(XF86ConfigPtr config, XF86ConfLayoutPtr layout)
    432 {
    433     int count = 0;
    434     XF86ConfInputPtr input = config->conf_input_lst;
    435     XF86ConfInputrefPtr inptr;
    436 
    437     /* add all AutoServerLayout devices to the server layout */
    438     while (input) {
    439         if (xf86CheckBoolOption
    440             (input->inp_option_lst, "AutoServerLayout", FALSE)) {
    441             XF86ConfInputrefPtr iref = layout->lay_input_lst;
    442 
    443             /* avoid duplicates if referenced but lists AutoServerLayout too */
    444             while (iref) {
    445                 if (strcmp(iref->iref_inputdev_str, input->inp_identifier) == 0)
    446                     break;
    447                 iref = iref->list.next;
    448             }
    449 
    450             if (!iref) {
    451                 XF86ConfInputrefPtr iptr;
    452 
    453                 iptr = calloc(1, sizeof(XF86ConfInputrefRec));
    454                 iptr->iref_inputdev_str = input->inp_identifier;
    455                 layout->lay_input_lst = (XF86ConfInputrefPtr)
    456                     xf86addListItem((glp) layout->lay_input_lst, (glp) iptr);
    457                 count++;
    458             }
    459         }
    460         input = input->list.next;
    461     }
    462 
    463     inptr = layout->lay_input_lst;
    464     while (inptr) {
    465         input = xf86findInput(inptr->iref_inputdev_str, config->conf_input_lst);
    466         if (!input) {
    467             xf86validationError(UNDEFINED_INPUT_MSG,
    468                                 inptr->iref_inputdev_str,
    469                                 layout->lay_identifier);
    470             return -1;
    471         }
    472         else
    473             inptr->iref_inputdev = input;
    474         inptr = inptr->list.next;
    475     }
    476 
    477     return count;
    478 }
    479 
    480 int
    481 xf86validateLayout(XF86ConfigPtr p)
    482 {
    483     XF86ConfLayoutPtr layout = p->conf_layout_lst;
    484     XF86ConfAdjacencyPtr adj;
    485     XF86ConfInactivePtr iptr;
    486     XF86ConfScreenPtr screen;
    487     XF86ConfDevicePtr device;
    488 
    489     while (layout) {
    490         adj = layout->lay_adjacency_lst;
    491         while (adj) {
    492             /* the first one can't be "" but all others can */
    493             screen = xf86findScreen(adj->adj_screen_str, p->conf_screen_lst);
    494             if (!screen) {
    495                 xf86validationError(UNDEFINED_SCREEN_MSG,
    496                                     adj->adj_screen_str,
    497                                     layout->lay_identifier);
    498                 return FALSE;
    499             }
    500             else
    501                 adj->adj_screen = screen;
    502 
    503             adj = adj->list.next;
    504         }
    505         iptr = layout->lay_inactive_lst;
    506         while (iptr) {
    507             device = xf86findDevice(iptr->inactive_device_str,
    508                                     p->conf_device_lst);
    509             if (!device) {
    510                 xf86validationError(UNDEFINED_DEVICE_LAY_MSG,
    511                                     iptr->inactive_device_str,
    512                                     layout->lay_identifier);
    513                 return FALSE;
    514             }
    515             else
    516                 iptr->inactive_device = device;
    517             iptr = iptr->list.next;
    518         }
    519 
    520         if (xf86layoutAddInputDevices(p, layout) == -1)
    521             return FALSE;
    522 
    523         layout = layout->list.next;
    524     }
    525     return TRUE;
    526 }
    527 
    528 XF86ConfLayoutPtr
    529 xf86findLayout(const char *name, XF86ConfLayoutPtr list)
    530 {
    531     while (list) {
    532         if (xf86nameCompare(list->lay_identifier, name) == 0)
    533             return list;
    534         list = list->list.next;
    535     }
    536     return NULL;
    537 }