xserver

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

Monitor.c (29784B)


      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 
     63 
     64 static const xf86ConfigSymTabRec MonitorTab[] = {
     65     {ENDSECTION, "endsection"},
     66     {IDENTIFIER, "identifier"},
     67     {VENDOR, "vendorname"},
     68     {MODEL, "modelname"},
     69     {USEMODES, "usemodes"},
     70     {MODELINE, "modeline"},
     71     {DISPLAYSIZE, "displaysize"},
     72     {HORIZSYNC, "horizsync"},
     73     {VERTREFRESH, "vertrefresh"},
     74     {MODE, "mode"},
     75     {GAMMA, "gamma"},
     76     {OPTION, "option"},
     77     {-1, ""},
     78 };
     79 
     80 static const xf86ConfigSymTabRec ModesTab[] = {
     81     {ENDSECTION, "endsection"},
     82     {IDENTIFIER, "identifier"},
     83     {MODELINE, "modeline"},
     84     {MODE, "mode"},
     85     {-1, ""},
     86 };
     87 
     88 static const xf86ConfigSymTabRec TimingTab[] = {
     89     {TT_INTERLACE, "interlace"},
     90     {TT_PHSYNC, "+hsync"},
     91     {TT_NHSYNC, "-hsync"},
     92     {TT_PVSYNC, "+vsync"},
     93     {TT_NVSYNC, "-vsync"},
     94     {TT_CSYNC, "composite"},
     95     {TT_PCSYNC, "+csync"},
     96     {TT_NCSYNC, "-csync"},
     97     {TT_DBLSCAN, "doublescan"},
     98     {TT_HSKEW, "hskew"},
     99     {TT_BCAST, "bcast"},
    100     {TT_VSCAN, "vscan"},
    101     {-1, ""},
    102 };
    103 
    104 static const xf86ConfigSymTabRec ModeTab[] = {
    105     {DOTCLOCK, "dotclock"},
    106     {HTIMINGS, "htimings"},
    107     {VTIMINGS, "vtimings"},
    108     {FLAGS, "flags"},
    109     {HSKEW, "hskew"},
    110     {BCAST, "bcast"},
    111     {VSCAN, "vscan"},
    112     {ENDMODE, "endmode"},
    113     {-1, ""},
    114 };
    115 
    116 #define CLEANUP xf86freeModeLineList
    117 
    118 static void
    119 xf86freeModeLineList(XF86ConfModeLinePtr ptr)
    120 {
    121     XF86ConfModeLinePtr prev;
    122 
    123     while (ptr) {
    124         TestFree(ptr->ml_identifier);
    125         TestFree(ptr->ml_comment);
    126         prev = ptr;
    127         ptr = ptr->list.next;
    128         free(prev);
    129     }
    130 }
    131 
    132 static XF86ConfModeLinePtr
    133 xf86parseModeLine(void)
    134 {
    135     int token;
    136 
    137     parsePrologue(XF86ConfModeLinePtr, XF86ConfModeLineRec)
    138 
    139         /* Identifier */
    140         if (xf86getSubToken(&(ptr->ml_comment)) != STRING)
    141         Error("ModeLine identifier expected");
    142     ptr->ml_identifier = xf86_lex_val.str;
    143 
    144     /* DotClock */
    145     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    146         Error("ModeLine dotclock expected");
    147     ptr->ml_clock = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
    148 
    149     /* HDisplay */
    150     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    151         Error("ModeLine Hdisplay expected");
    152     ptr->ml_hdisplay = xf86_lex_val.num;
    153 
    154     /* HSyncStart */
    155     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    156         Error("ModeLine HSyncStart expected");
    157     ptr->ml_hsyncstart = xf86_lex_val.num;
    158 
    159     /* HSyncEnd */
    160     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    161         Error("ModeLine HSyncEnd expected");
    162     ptr->ml_hsyncend = xf86_lex_val.num;
    163 
    164     /* HTotal */
    165     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    166         Error("ModeLine HTotal expected");
    167     ptr->ml_htotal = xf86_lex_val.num;
    168 
    169     /* VDisplay */
    170     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    171         Error("ModeLine Vdisplay expected");
    172     ptr->ml_vdisplay = xf86_lex_val.num;
    173 
    174     /* VSyncStart */
    175     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    176         Error("ModeLine VSyncStart expected");
    177     ptr->ml_vsyncstart = xf86_lex_val.num;
    178 
    179     /* VSyncEnd */
    180     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    181         Error("ModeLine VSyncEnd expected");
    182     ptr->ml_vsyncend = xf86_lex_val.num;
    183 
    184     /* VTotal */
    185     if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    186         Error("ModeLine VTotal expected");
    187     ptr->ml_vtotal = xf86_lex_val.num;
    188 
    189     token = xf86getSubTokenWithTab(&(ptr->ml_comment), TimingTab);
    190     while ((token == TT_INTERLACE) || (token == TT_PHSYNC) ||
    191            (token == TT_NHSYNC) || (token == TT_PVSYNC) ||
    192            (token == TT_NVSYNC) || (token == TT_CSYNC) ||
    193            (token == TT_PCSYNC) || (token == TT_NCSYNC) ||
    194            (token == TT_DBLSCAN) || (token == TT_HSKEW) ||
    195            (token == TT_VSCAN) || (token == TT_BCAST)) {
    196         switch (token) {
    197 
    198         case TT_INTERLACE:
    199             ptr->ml_flags |= XF86CONF_INTERLACE;
    200             break;
    201         case TT_PHSYNC:
    202             ptr->ml_flags |= XF86CONF_PHSYNC;
    203             break;
    204         case TT_NHSYNC:
    205             ptr->ml_flags |= XF86CONF_NHSYNC;
    206             break;
    207         case TT_PVSYNC:
    208             ptr->ml_flags |= XF86CONF_PVSYNC;
    209             break;
    210         case TT_NVSYNC:
    211             ptr->ml_flags |= XF86CONF_NVSYNC;
    212             break;
    213         case TT_CSYNC:
    214             ptr->ml_flags |= XF86CONF_CSYNC;
    215             break;
    216         case TT_PCSYNC:
    217             ptr->ml_flags |= XF86CONF_PCSYNC;
    218             break;
    219         case TT_NCSYNC:
    220             ptr->ml_flags |= XF86CONF_NCSYNC;
    221             break;
    222         case TT_DBLSCAN:
    223             ptr->ml_flags |= XF86CONF_DBLSCAN;
    224             break;
    225         case TT_HSKEW:
    226             if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    227                 Error(NUMBER_MSG, "Hskew");
    228             ptr->ml_hskew = xf86_lex_val.num;
    229             ptr->ml_flags |= XF86CONF_HSKEW;
    230             break;
    231         case TT_BCAST:
    232             ptr->ml_flags |= XF86CONF_BCAST;
    233             break;
    234         case TT_VSCAN:
    235             if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    236                 Error(NUMBER_MSG, "Vscan");
    237             ptr->ml_vscan = xf86_lex_val.num;
    238             ptr->ml_flags |= XF86CONF_VSCAN;
    239             break;
    240         case EOF_TOKEN:
    241             Error(UNEXPECTED_EOF_MSG);
    242             break;
    243         default:
    244             Error(INVALID_KEYWORD_MSG, xf86tokenString());
    245             break;
    246         }
    247         token = xf86getSubTokenWithTab(&(ptr->ml_comment), TimingTab);
    248     }
    249     xf86unGetToken(token);
    250 
    251 #ifdef DEBUG
    252     printf("ModeLine parsed\n");
    253 #endif
    254     return ptr;
    255 }
    256 
    257 static XF86ConfModeLinePtr
    258 xf86parseVerboseMode(void)
    259 {
    260     int token, token2;
    261     int had_dotclock = 0, had_htimings = 0, had_vtimings = 0;
    262 
    263     parsePrologue(XF86ConfModeLinePtr, XF86ConfModeLineRec)
    264 
    265         if (xf86getSubToken(&(ptr->ml_comment)) != STRING)
    266         Error("Mode name expected");
    267     ptr->ml_identifier = xf86_lex_val.str;
    268     while ((token = xf86getToken(ModeTab)) != ENDMODE) {
    269         switch (token) {
    270         case COMMENT:
    271             ptr->ml_comment = xf86addComment(ptr->ml_comment, xf86_lex_val.str);
    272             break;
    273         case DOTCLOCK:
    274             if ((token = xf86getSubToken(&(ptr->ml_comment))) != NUMBER)
    275                 Error(NUMBER_MSG, "DotClock");
    276             ptr->ml_clock = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
    277             had_dotclock = 1;
    278             break;
    279         case HTIMINGS:
    280             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
    281                 ptr->ml_hdisplay = xf86_lex_val.num;
    282             else
    283                 Error("Horizontal display expected");
    284 
    285             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
    286                 ptr->ml_hsyncstart = xf86_lex_val.num;
    287             else
    288                 Error("Horizontal sync start expected");
    289 
    290             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
    291                 ptr->ml_hsyncend = xf86_lex_val.num;
    292             else
    293                 Error("Horizontal sync end expected");
    294 
    295             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
    296                 ptr->ml_htotal = xf86_lex_val.num;
    297             else
    298                 Error("Horizontal total expected");
    299             had_htimings = 1;
    300             break;
    301         case VTIMINGS:
    302             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
    303                 ptr->ml_vdisplay = xf86_lex_val.num;
    304             else
    305                 Error("Vertical display expected");
    306 
    307             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
    308                 ptr->ml_vsyncstart = xf86_lex_val.num;
    309             else
    310                 Error("Vertical sync start expected");
    311 
    312             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
    313                 ptr->ml_vsyncend = xf86_lex_val.num;
    314             else
    315                 Error("Vertical sync end expected");
    316 
    317             if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
    318                 ptr->ml_vtotal = xf86_lex_val.num;
    319             else
    320                 Error("Vertical total expected");
    321             had_vtimings = 1;
    322             break;
    323         case FLAGS:
    324             token = xf86getSubToken(&(ptr->ml_comment));
    325             if (token != STRING)
    326                 Error(QUOTE_MSG, "Flags");
    327             while (token == STRING) {
    328                 token2 = xf86getStringToken(TimingTab);
    329                 switch (token2) {
    330                 case TT_INTERLACE:
    331                     ptr->ml_flags |= XF86CONF_INTERLACE;
    332                     break;
    333                 case TT_PHSYNC:
    334                     ptr->ml_flags |= XF86CONF_PHSYNC;
    335                     break;
    336                 case TT_NHSYNC:
    337                     ptr->ml_flags |= XF86CONF_NHSYNC;
    338                     break;
    339                 case TT_PVSYNC:
    340                     ptr->ml_flags |= XF86CONF_PVSYNC;
    341                     break;
    342                 case TT_NVSYNC:
    343                     ptr->ml_flags |= XF86CONF_NVSYNC;
    344                     break;
    345                 case TT_CSYNC:
    346                     ptr->ml_flags |= XF86CONF_CSYNC;
    347                     break;
    348                 case TT_PCSYNC:
    349                     ptr->ml_flags |= XF86CONF_PCSYNC;
    350                     break;
    351                 case TT_NCSYNC:
    352                     ptr->ml_flags |= XF86CONF_NCSYNC;
    353                     break;
    354                 case TT_DBLSCAN:
    355                     ptr->ml_flags |= XF86CONF_DBLSCAN;
    356                     break;
    357                 case EOF_TOKEN:
    358                     Error(UNEXPECTED_EOF_MSG);
    359                     break;
    360                 default:
    361                     Error("Unknown flag string");
    362                     break;
    363                 }
    364                 token = xf86getSubToken(&(ptr->ml_comment));
    365             }
    366             xf86unGetToken(token);
    367             break;
    368         case HSKEW:
    369             if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    370                 Error("Horizontal skew expected");
    371             ptr->ml_flags |= XF86CONF_HSKEW;
    372             ptr->ml_hskew = xf86_lex_val.num;
    373             break;
    374         case VSCAN:
    375             if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
    376                 Error("Vertical scan count expected");
    377             ptr->ml_flags |= XF86CONF_VSCAN;
    378             ptr->ml_vscan = xf86_lex_val.num;
    379             break;
    380         case EOF_TOKEN:
    381             Error(UNEXPECTED_EOF_MSG);
    382             break;
    383         default:
    384             Error("Unexpected token in verbose \"Mode\" entry\n");
    385         }
    386     }
    387     if (!had_dotclock)
    388         Error("the dotclock is missing");
    389     if (!had_htimings)
    390         Error("the horizontal timings are missing");
    391     if (!had_vtimings)
    392         Error("the vertical timings are missing");
    393 
    394 #ifdef DEBUG
    395     printf("Verbose Mode parsed\n");
    396 #endif
    397     return ptr;
    398 }
    399 
    400 #undef CLEANUP
    401 
    402 #define CLEANUP xf86freeMonitorList
    403 
    404 XF86ConfMonitorPtr
    405 xf86parseMonitorSection(void)
    406 {
    407     int has_ident = FALSE;
    408     int token;
    409 
    410     parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec)
    411 
    412         while ((token = xf86getToken(MonitorTab)) != ENDSECTION) {
    413         switch (token) {
    414         case COMMENT:
    415             ptr->mon_comment = xf86addComment(ptr->mon_comment, xf86_lex_val.str);
    416             break;
    417         case IDENTIFIER:
    418             if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
    419                 Error(QUOTE_MSG, "Identifier");
    420             if (has_ident == TRUE)
    421                 Error(MULTIPLE_MSG, "Identifier");
    422             ptr->mon_identifier = xf86_lex_val.str;
    423             has_ident = TRUE;
    424             break;
    425         case VENDOR:
    426             if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
    427                 Error(QUOTE_MSG, "Vendor");
    428             ptr->mon_vendor = xf86_lex_val.str;
    429             break;
    430         case MODEL:
    431             if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
    432                 Error(QUOTE_MSG, "ModelName");
    433             ptr->mon_modelname = xf86_lex_val.str;
    434             break;
    435         case MODE:
    436             HANDLE_LIST(mon_modeline_lst, xf86parseVerboseMode,
    437                         XF86ConfModeLinePtr);
    438             break;
    439         case MODELINE:
    440             HANDLE_LIST(mon_modeline_lst, xf86parseModeLine,
    441                         XF86ConfModeLinePtr);
    442             break;
    443         case DISPLAYSIZE:
    444             if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
    445                 Error(DISPLAYSIZE_MSG);
    446             ptr->mon_width = xf86_lex_val.realnum;
    447             if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
    448                 Error(DISPLAYSIZE_MSG);
    449             ptr->mon_height = xf86_lex_val.realnum;
    450             break;
    451 
    452         case HORIZSYNC:
    453             if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
    454                 Error(HORIZSYNC_MSG);
    455             do {
    456                 if (ptr->mon_n_hsync >= CONF_MAX_HSYNC)
    457                     Error("Sorry. Too many horizontal sync intervals.");
    458                 ptr->mon_hsync[ptr->mon_n_hsync].lo = xf86_lex_val.realnum;
    459                 switch (token = xf86getSubToken(&(ptr->mon_comment))) {
    460                 case COMMA:
    461                     ptr->mon_hsync[ptr->mon_n_hsync].hi =
    462                         ptr->mon_hsync[ptr->mon_n_hsync].lo;
    463                     break;
    464                 case DASH:
    465                     if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER ||
    466                         (float) xf86_lex_val.realnum <
    467                         ptr->mon_hsync[ptr->mon_n_hsync].lo)
    468                         Error(HORIZSYNC_MSG);
    469                     ptr->mon_hsync[ptr->mon_n_hsync].hi = xf86_lex_val.realnum;
    470                     if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA)
    471                         break;
    472                     ptr->mon_n_hsync++;
    473                     goto HorizDone;
    474                 default:
    475                     /* We cannot currently know if a '\n' was found,
    476                      * or this is a real error
    477                      */
    478                     ptr->mon_hsync[ptr->mon_n_hsync].hi =
    479                         ptr->mon_hsync[ptr->mon_n_hsync].lo;
    480                     ptr->mon_n_hsync++;
    481                     goto HorizDone;
    482                 }
    483                 ptr->mon_n_hsync++;
    484             } while ((token = xf86getSubToken(&(ptr->mon_comment))) == NUMBER);
    485  HorizDone:
    486             xf86unGetToken(token);
    487             break;
    488 
    489         case VERTREFRESH:
    490             if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
    491                 Error(VERTREFRESH_MSG);
    492             do {
    493                 ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo = xf86_lex_val.realnum;
    494                 switch (token = xf86getSubToken(&(ptr->mon_comment))) {
    495                 case COMMA:
    496                     ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
    497                         ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
    498                     break;
    499                 case DASH:
    500                     if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER ||
    501                         (float) xf86_lex_val.realnum <
    502                         ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo)
    503                         Error(VERTREFRESH_MSG);
    504                     ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = xf86_lex_val.realnum;
    505                     if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA)
    506                         break;
    507                     ptr->mon_n_vrefresh++;
    508                     goto VertDone;
    509                 default:
    510                     /* We cannot currently know if a '\n' was found,
    511                      * or this is a real error
    512                      */
    513                     ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
    514                         ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
    515                     ptr->mon_n_vrefresh++;
    516                     goto VertDone;
    517                 }
    518                 if (ptr->mon_n_vrefresh >= CONF_MAX_VREFRESH)
    519                     Error("Sorry. Too many vertical refresh intervals.");
    520                 ptr->mon_n_vrefresh++;
    521             } while ((token = xf86getSubToken(&(ptr->mon_comment))) == NUMBER);
    522  VertDone:
    523             xf86unGetToken(token);
    524             break;
    525 
    526         case GAMMA:
    527             if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER) {
    528                 Error(INVALID_GAMMA_MSG);
    529             }
    530             else {
    531                 ptr->mon_gamma_red = ptr->mon_gamma_green =
    532                     ptr->mon_gamma_blue = xf86_lex_val.realnum;
    533                 if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) {
    534                     ptr->mon_gamma_green = xf86_lex_val.realnum;
    535                     if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) {
    536                         ptr->mon_gamma_blue = xf86_lex_val.realnum;
    537                     }
    538                     else {
    539                         Error(INVALID_GAMMA_MSG);
    540                     }
    541                 }
    542                 else
    543                     xf86unGetToken(token);
    544             }
    545             break;
    546         case OPTION:
    547             ptr->mon_option_lst = xf86parseOption(ptr->mon_option_lst);
    548             break;
    549         case USEMODES:
    550         {
    551             XF86ConfModesLinkPtr mptr;
    552 
    553             if ((token = xf86getSubToken(&(ptr->mon_comment))) != STRING)
    554                 Error(QUOTE_MSG, "UseModes");
    555 
    556             /* add to the end of the list of modes sections
    557                referenced here */
    558             mptr = calloc(1, sizeof(XF86ConfModesLinkRec));
    559             mptr->list.next = NULL;
    560             mptr->ml_modes_str = xf86_lex_val.str;
    561             mptr->ml_modes = NULL;
    562             ptr->mon_modes_sect_lst = (XF86ConfModesLinkPtr)
    563                 xf86addListItem((GenericListPtr) ptr->mon_modes_sect_lst,
    564                                 (GenericListPtr) mptr);
    565         }
    566             break;
    567         case EOF_TOKEN:
    568             Error(UNEXPECTED_EOF_MSG);
    569             break;
    570         default:
    571             xf86parseError(INVALID_KEYWORD_MSG, xf86tokenString());
    572             CLEANUP(ptr);
    573             return NULL;
    574             break;
    575         }
    576     }
    577 
    578     if (!has_ident)
    579         Error(NO_IDENT_MSG);
    580 
    581 #ifdef DEBUG
    582     printf("Monitor section parsed\n");
    583 #endif
    584     return ptr;
    585 }
    586 
    587 #undef CLEANUP
    588 #define CLEANUP xf86freeModesList
    589 
    590 XF86ConfModesPtr
    591 xf86parseModesSection(void)
    592 {
    593     int has_ident = FALSE;
    594     int token;
    595 
    596     parsePrologue(XF86ConfModesPtr, XF86ConfModesRec)
    597 
    598         while ((token = xf86getToken(ModesTab)) != ENDSECTION) {
    599         switch (token) {
    600         case COMMENT:
    601             ptr->modes_comment = xf86addComment(ptr->modes_comment, xf86_lex_val.str);
    602             break;
    603         case IDENTIFIER:
    604             if (xf86getSubToken(&(ptr->modes_comment)) != STRING)
    605                 Error(QUOTE_MSG, "Identifier");
    606             if (has_ident == TRUE)
    607                 Error(MULTIPLE_MSG, "Identifier");
    608             ptr->modes_identifier = xf86_lex_val.str;
    609             has_ident = TRUE;
    610             break;
    611         case MODE:
    612             HANDLE_LIST(mon_modeline_lst, xf86parseVerboseMode,
    613                         XF86ConfModeLinePtr);
    614             break;
    615         case MODELINE:
    616             HANDLE_LIST(mon_modeline_lst, xf86parseModeLine,
    617                         XF86ConfModeLinePtr);
    618             break;
    619         default:
    620             xf86parseError(INVALID_KEYWORD_MSG, xf86tokenString());
    621             CLEANUP(ptr);
    622             return NULL;
    623             break;
    624         }
    625     }
    626 
    627     if (!has_ident)
    628         Error(NO_IDENT_MSG);
    629 
    630 #ifdef DEBUG
    631     printf("Modes section parsed\n");
    632 #endif
    633     return ptr;
    634 }
    635 
    636 #undef CLEANUP
    637 
    638 void
    639 xf86printMonitorSection(FILE * cf, XF86ConfMonitorPtr ptr)
    640 {
    641     int i;
    642     XF86ConfModeLinePtr mlptr;
    643     XF86ConfModesLinkPtr mptr;
    644 
    645     while (ptr) {
    646         mptr = ptr->mon_modes_sect_lst;
    647         fprintf(cf, "Section \"Monitor\"\n");
    648         if (ptr->mon_comment)
    649             fprintf(cf, "%s", ptr->mon_comment);
    650         if (ptr->mon_identifier)
    651             fprintf(cf, "\tIdentifier   \"%s\"\n", ptr->mon_identifier);
    652         if (ptr->mon_vendor)
    653             fprintf(cf, "\tVendorName   \"%s\"\n", ptr->mon_vendor);
    654         if (ptr->mon_modelname)
    655             fprintf(cf, "\tModelName    \"%s\"\n", ptr->mon_modelname);
    656         while (mptr) {
    657             fprintf(cf, "\tUseModes     \"%s\"\n", mptr->ml_modes_str);
    658             mptr = mptr->list.next;
    659         }
    660         if (ptr->mon_width)
    661             fprintf(cf, "\tDisplaySize  %d\t%d\n",
    662                     ptr->mon_width, ptr->mon_height);
    663         for (i = 0; i < ptr->mon_n_hsync; i++) {
    664             fprintf(cf, "\tHorizSync    %2.1f - %2.1f\n",
    665                     ptr->mon_hsync[i].lo, ptr->mon_hsync[i].hi);
    666         }
    667         for (i = 0; i < ptr->mon_n_vrefresh; i++) {
    668             fprintf(cf, "\tVertRefresh  %2.1f - %2.1f\n",
    669                     ptr->mon_vrefresh[i].lo, ptr->mon_vrefresh[i].hi);
    670         }
    671         if (ptr->mon_gamma_red) {
    672             if (ptr->mon_gamma_red == ptr->mon_gamma_green
    673                 && ptr->mon_gamma_red == ptr->mon_gamma_blue) {
    674                 fprintf(cf, "\tGamma        %.4g\n", ptr->mon_gamma_red);
    675             }
    676             else {
    677                 fprintf(cf, "\tGamma        %.4g %.4g %.4g\n",
    678                         ptr->mon_gamma_red,
    679                         ptr->mon_gamma_green, ptr->mon_gamma_blue);
    680             }
    681         }
    682         for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next) {
    683             fprintf(cf, "\tModeLine     \"%s\" %2.1f ",
    684                     mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
    685             fprintf(cf, "%d %d %d %d %d %d %d %d",
    686                     mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
    687                     mlptr->ml_hsyncend, mlptr->ml_htotal,
    688                     mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
    689                     mlptr->ml_vsyncend, mlptr->ml_vtotal);
    690             if (mlptr->ml_flags & XF86CONF_PHSYNC)
    691                 fprintf(cf, " +hsync");
    692             if (mlptr->ml_flags & XF86CONF_NHSYNC)
    693                 fprintf(cf, " -hsync");
    694             if (mlptr->ml_flags & XF86CONF_PVSYNC)
    695                 fprintf(cf, " +vsync");
    696             if (mlptr->ml_flags & XF86CONF_NVSYNC)
    697                 fprintf(cf, " -vsync");
    698             if (mlptr->ml_flags & XF86CONF_INTERLACE)
    699                 fprintf(cf, " interlace");
    700             if (mlptr->ml_flags & XF86CONF_CSYNC)
    701                 fprintf(cf, " composite");
    702             if (mlptr->ml_flags & XF86CONF_PCSYNC)
    703                 fprintf(cf, " +csync");
    704             if (mlptr->ml_flags & XF86CONF_NCSYNC)
    705                 fprintf(cf, " -csync");
    706             if (mlptr->ml_flags & XF86CONF_DBLSCAN)
    707                 fprintf(cf, " doublescan");
    708             if (mlptr->ml_flags & XF86CONF_HSKEW)
    709                 fprintf(cf, " hskew %d", mlptr->ml_hskew);
    710             if (mlptr->ml_flags & XF86CONF_BCAST)
    711                 fprintf(cf, " bcast");
    712             fprintf(cf, "\n");
    713         }
    714         xf86printOptionList(cf, ptr->mon_option_lst, 1);
    715         fprintf(cf, "EndSection\n\n");
    716         ptr = ptr->list.next;
    717     }
    718 }
    719 
    720 void
    721 xf86printModesSection(FILE * cf, XF86ConfModesPtr ptr)
    722 {
    723     XF86ConfModeLinePtr mlptr;
    724 
    725     while (ptr) {
    726         fprintf(cf, "Section \"Modes\"\n");
    727         if (ptr->modes_comment)
    728             fprintf(cf, "%s", ptr->modes_comment);
    729         if (ptr->modes_identifier)
    730             fprintf(cf, "\tIdentifier     \"%s\"\n", ptr->modes_identifier);
    731         for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next) {
    732             fprintf(cf, "\tModeLine     \"%s\" %2.1f ",
    733                     mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
    734             fprintf(cf, "%d %d %d %d %d %d %d %d",
    735                     mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
    736                     mlptr->ml_hsyncend, mlptr->ml_htotal,
    737                     mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
    738                     mlptr->ml_vsyncend, mlptr->ml_vtotal);
    739             if (mlptr->ml_flags & XF86CONF_PHSYNC)
    740                 fprintf(cf, " +hsync");
    741             if (mlptr->ml_flags & XF86CONF_NHSYNC)
    742                 fprintf(cf, " -hsync");
    743             if (mlptr->ml_flags & XF86CONF_PVSYNC)
    744                 fprintf(cf, " +vsync");
    745             if (mlptr->ml_flags & XF86CONF_NVSYNC)
    746                 fprintf(cf, " -vsync");
    747             if (mlptr->ml_flags & XF86CONF_INTERLACE)
    748                 fprintf(cf, " interlace");
    749             if (mlptr->ml_flags & XF86CONF_CSYNC)
    750                 fprintf(cf, " composite");
    751             if (mlptr->ml_flags & XF86CONF_PCSYNC)
    752                 fprintf(cf, " +csync");
    753             if (mlptr->ml_flags & XF86CONF_NCSYNC)
    754                 fprintf(cf, " -csync");
    755             if (mlptr->ml_flags & XF86CONF_DBLSCAN)
    756                 fprintf(cf, " doublescan");
    757             if (mlptr->ml_flags & XF86CONF_HSKEW)
    758                 fprintf(cf, " hskew %d", mlptr->ml_hskew);
    759             if (mlptr->ml_flags & XF86CONF_VSCAN)
    760                 fprintf(cf, " vscan %d", mlptr->ml_vscan);
    761             if (mlptr->ml_flags & XF86CONF_BCAST)
    762                 fprintf(cf, " bcast");
    763             if (mlptr->ml_comment)
    764                 fprintf(cf, "%s", mlptr->ml_comment);
    765             else
    766                 fprintf(cf, "\n");
    767         }
    768         fprintf(cf, "EndSection\n\n");
    769         ptr = ptr->list.next;
    770     }
    771 }
    772 
    773 void
    774 xf86freeMonitorList(XF86ConfMonitorPtr ptr)
    775 {
    776     XF86ConfMonitorPtr prev;
    777 
    778     while (ptr) {
    779         TestFree(ptr->mon_identifier);
    780         TestFree(ptr->mon_vendor);
    781         TestFree(ptr->mon_modelname);
    782         TestFree(ptr->mon_comment);
    783         xf86optionListFree(ptr->mon_option_lst);
    784         xf86freeModeLineList(ptr->mon_modeline_lst);
    785         prev = ptr;
    786         ptr = ptr->list.next;
    787         free(prev);
    788     }
    789 }
    790 
    791 void
    792 xf86freeModesList(XF86ConfModesPtr ptr)
    793 {
    794     XF86ConfModesPtr prev;
    795 
    796     while (ptr) {
    797         TestFree(ptr->modes_identifier);
    798         TestFree(ptr->modes_comment);
    799         xf86freeModeLineList(ptr->mon_modeline_lst);
    800         prev = ptr;
    801         ptr = ptr->list.next;
    802         free(prev);
    803     }
    804 }
    805 
    806 XF86ConfMonitorPtr
    807 xf86findMonitor(const char *ident, XF86ConfMonitorPtr p)
    808 {
    809     while (p) {
    810         if (xf86nameCompare(ident, p->mon_identifier) == 0)
    811             return p;
    812 
    813         p = p->list.next;
    814     }
    815     return NULL;
    816 }
    817 
    818 XF86ConfModesPtr
    819 xf86findModes(const char *ident, XF86ConfModesPtr p)
    820 {
    821     while (p) {
    822         if (xf86nameCompare(ident, p->modes_identifier) == 0)
    823             return p;
    824 
    825         p = p->list.next;
    826     }
    827     return NULL;
    828 }
    829 
    830 XF86ConfModeLinePtr
    831 xf86findModeLine(const char *ident, XF86ConfModeLinePtr p)
    832 {
    833     while (p) {
    834         if (xf86nameCompare(ident, p->ml_identifier) == 0)
    835             return p;
    836 
    837         p = p->list.next;
    838     }
    839     return NULL;
    840 }
    841 
    842 int
    843 xf86validateMonitor(XF86ConfigPtr p, XF86ConfScreenPtr screen)
    844 {
    845     XF86ConfMonitorPtr monitor = screen->scrn_monitor;
    846     XF86ConfModesLinkPtr modeslnk = monitor->mon_modes_sect_lst;
    847     XF86ConfModesPtr modes;
    848 
    849     while (modeslnk) {
    850         modes = xf86findModes(modeslnk->ml_modes_str, p->conf_modes_lst);
    851         if (!modes) {
    852             xf86validationError(UNDEFINED_MODES_MSG,
    853                                 modeslnk->ml_modes_str,
    854                                 screen->scrn_identifier);
    855             return FALSE;
    856         }
    857         modeslnk->ml_modes = modes;
    858         modeslnk = modeslnk->list.next;
    859     }
    860     return TRUE;
    861 }