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 }