xf86Option.c (24405B)
1 /* 2 * Copyright (c) 1998-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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the copyright holder(s) 23 * and author(s) shall not be used in advertising or otherwise to promote 24 * the sale, use or other dealings in this Software without prior written 25 * authorization from the copyright holder(s) and author(s). 26 */ 27 28 /* 29 * Author: David Dawes <dawes@xfree86.org> 30 * 31 * This file includes public option handling functions. 32 */ 33 34 #ifdef HAVE_XORG_CONFIG_H 35 #include <xorg-config.h> 36 #endif 37 38 #include <stdlib.h> 39 #include <ctype.h> 40 #include <X11/X.h> 41 #include "os.h" 42 #include "xf86.h" 43 #include "xf86Opt.h" 44 #include "xf86Xinput.h" 45 #include "xf86Optrec.h" 46 #include "xf86Parser.h" 47 #include "xf86platformBus.h" /* For OutputClass functions */ 48 #include "optionstr.h" 49 50 static Bool ParseOptionValue(int scrnIndex, XF86OptionPtr options, 51 OptionInfoPtr p, Bool markUsed); 52 53 /* 54 * xf86CollectOptions collects the options from each of the config file 55 * sections used by the screen and puts the combined list in pScrn->options. 56 * This function requires that the following have been initialised: 57 * 58 * pScrn->confScreen 59 * pScrn->Entities[i]->device 60 * pScrn->display 61 * pScrn->monitor 62 * 63 * The extraOpts parameter may optionally contain a list of additional options 64 * to include. 65 * 66 * The order of precedence for options is: 67 * 68 * extraOpts, display, confScreen, monitor, device, outputClassOptions 69 */ 70 71 void 72 xf86CollectOptions(ScrnInfoPtr pScrn, XF86OptionPtr extraOpts) 73 { 74 XF86OptionPtr tmp; 75 XF86OptionPtr extras = (XF86OptionPtr) extraOpts; 76 GDevPtr device; 77 78 int i; 79 80 pScrn->options = NULL; 81 82 for (i = pScrn->numEntities - 1; i >= 0; i--) { 83 xf86MergeOutputClassOptions(pScrn->entityList[i], &pScrn->options); 84 85 device = xf86GetDevFromEntity(pScrn->entityList[i], 86 pScrn->entityInstanceList[i]); 87 if (device && device->options) { 88 tmp = xf86optionListDup(device->options); 89 if (pScrn->options) 90 pScrn->options = xf86optionListMerge(pScrn->options, tmp); 91 else 92 pScrn->options = tmp; 93 } 94 } 95 if (pScrn->monitor->options) { 96 tmp = xf86optionListDup(pScrn->monitor->options); 97 if (pScrn->options) 98 pScrn->options = xf86optionListMerge(pScrn->options, tmp); 99 else 100 pScrn->options = tmp; 101 } 102 if (pScrn->confScreen->options) { 103 tmp = xf86optionListDup(pScrn->confScreen->options); 104 if (pScrn->options) 105 pScrn->options = xf86optionListMerge(pScrn->options, tmp); 106 else 107 pScrn->options = tmp; 108 } 109 if (pScrn->display->options) { 110 tmp = xf86optionListDup(pScrn->display->options); 111 if (pScrn->options) 112 pScrn->options = xf86optionListMerge(pScrn->options, tmp); 113 else 114 pScrn->options = tmp; 115 } 116 if (extras) { 117 tmp = xf86optionListDup(extras); 118 if (pScrn->options) 119 pScrn->options = xf86optionListMerge(pScrn->options, tmp); 120 else 121 pScrn->options = tmp; 122 } 123 } 124 125 /* 126 * xf86CollectInputOptions collects extra options for an InputDevice (other 127 * than those added by the config backend). 128 * The options are merged into the existing ones and thus take precedence 129 * over the others. 130 */ 131 132 void 133 xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts) 134 { 135 if (defaultOpts) { 136 XF86OptionPtr tmp = xf86optionListCreate(defaultOpts, -1, 0); 137 138 if (pInfo->options) 139 pInfo->options = xf86optionListMerge(tmp, pInfo->options); 140 else 141 pInfo->options = tmp; 142 } 143 } 144 145 /** 146 * Duplicate the option list passed in. The returned pointer will be a newly 147 * allocated option list and must be freed by the caller. 148 */ 149 XF86OptionPtr 150 xf86OptionListDuplicate(XF86OptionPtr options) 151 { 152 XF86OptionPtr o = NULL; 153 154 while (options) { 155 o = xf86AddNewOption(o, xf86OptionName(options), 156 xf86OptionValue(options)); 157 options = xf86nextOption(options); 158 } 159 160 return o; 161 } 162 163 /* Created for new XInput stuff -- essentially extensions to the parser */ 164 165 static int 166 LookupIntOption(XF86OptionPtr optlist, const char *name, int deflt, 167 Bool markUsed) 168 { 169 OptionInfoRec o; 170 171 o.name = name; 172 o.type = OPTV_INTEGER; 173 if (ParseOptionValue(-1, optlist, &o, markUsed)) 174 deflt = o.value.num; 175 return deflt; 176 } 177 178 static double 179 LookupRealOption(XF86OptionPtr optlist, const char *name, double deflt, 180 Bool markUsed) 181 { 182 OptionInfoRec o; 183 184 o.name = name; 185 o.type = OPTV_REAL; 186 if (ParseOptionValue(-1, optlist, &o, markUsed)) 187 deflt = o.value.realnum; 188 return deflt; 189 } 190 191 static char * 192 LookupStrOption(XF86OptionPtr optlist, const char *name, const char *deflt, 193 Bool markUsed) 194 { 195 OptionInfoRec o; 196 197 o.name = name; 198 o.type = OPTV_STRING; 199 if (ParseOptionValue(-1, optlist, &o, markUsed)) 200 deflt = o.value.str; 201 if (deflt) 202 return strdup(deflt); 203 else 204 return NULL; 205 } 206 207 static int 208 LookupBoolOption(XF86OptionPtr optlist, const char *name, int deflt, 209 Bool markUsed) 210 { 211 OptionInfoRec o; 212 213 o.name = name; 214 o.type = OPTV_BOOLEAN; 215 if (ParseOptionValue(-1, optlist, &o, markUsed)) 216 deflt = o.value.boolean; 217 return deflt; 218 } 219 220 static double 221 LookupPercentOption(XF86OptionPtr optlist, const char *name, double deflt, 222 Bool markUsed) 223 { 224 OptionInfoRec o; 225 226 o.name = name; 227 o.type = OPTV_PERCENT; 228 if (ParseOptionValue(-1, optlist, &o, markUsed)) 229 deflt = o.value.realnum; 230 return deflt; 231 } 232 233 /* These xf86Set* functions are intended for use by non-screen specific code */ 234 235 int 236 xf86SetIntOption(XF86OptionPtr optlist, const char *name, int deflt) 237 { 238 return LookupIntOption(optlist, name, deflt, TRUE); 239 } 240 241 double 242 xf86SetRealOption(XF86OptionPtr optlist, const char *name, double deflt) 243 { 244 return LookupRealOption(optlist, name, deflt, TRUE); 245 } 246 247 char * 248 xf86SetStrOption(XF86OptionPtr optlist, const char *name, const char *deflt) 249 { 250 return LookupStrOption(optlist, name, deflt, TRUE); 251 } 252 253 int 254 xf86SetBoolOption(XF86OptionPtr optlist, const char *name, int deflt) 255 { 256 return LookupBoolOption(optlist, name, deflt, TRUE); 257 } 258 259 double 260 xf86SetPercentOption(XF86OptionPtr optlist, const char *name, double deflt) 261 { 262 return LookupPercentOption(optlist, name, deflt, TRUE); 263 } 264 265 /* 266 * These are like the Set*Option functions, but they don't mark the options 267 * as used. 268 */ 269 int 270 xf86CheckIntOption(XF86OptionPtr optlist, const char *name, int deflt) 271 { 272 return LookupIntOption(optlist, name, deflt, FALSE); 273 } 274 275 double 276 xf86CheckRealOption(XF86OptionPtr optlist, const char *name, double deflt) 277 { 278 return LookupRealOption(optlist, name, deflt, FALSE); 279 } 280 281 char * 282 xf86CheckStrOption(XF86OptionPtr optlist, const char *name, const char *deflt) 283 { 284 return LookupStrOption(optlist, name, deflt, FALSE); 285 } 286 287 int 288 xf86CheckBoolOption(XF86OptionPtr optlist, const char *name, int deflt) 289 { 290 return LookupBoolOption(optlist, name, deflt, FALSE); 291 } 292 293 double 294 xf86CheckPercentOption(XF86OptionPtr optlist, const char *name, double deflt) 295 { 296 return LookupPercentOption(optlist, name, deflt, FALSE); 297 } 298 299 /* 300 * xf86AddNewOption() has the required property of replacing the option value 301 * if the option is already present. 302 */ 303 XF86OptionPtr 304 xf86ReplaceIntOption(XF86OptionPtr optlist, const char *name, const int val) 305 { 306 char tmp[16]; 307 308 snprintf(tmp, sizeof(tmp), "%i", val); 309 return xf86AddNewOption(optlist, name, tmp); 310 } 311 312 XF86OptionPtr 313 xf86ReplaceRealOption(XF86OptionPtr optlist, const char *name, const double val) 314 { 315 char tmp[32]; 316 317 snprintf(tmp, sizeof(tmp), "%f", val); 318 return xf86AddNewOption(optlist, name, tmp); 319 } 320 321 XF86OptionPtr 322 xf86ReplaceBoolOption(XF86OptionPtr optlist, const char *name, const Bool val) 323 { 324 return xf86AddNewOption(optlist, name, val ? "True" : "False"); 325 } 326 327 XF86OptionPtr 328 xf86ReplacePercentOption(XF86OptionPtr optlist, const char *name, 329 const double val) 330 { 331 char tmp[16]; 332 333 snprintf(tmp, sizeof(tmp), "%lf%%", val); 334 return xf86AddNewOption(optlist, name, tmp); 335 } 336 337 XF86OptionPtr 338 xf86ReplaceStrOption(XF86OptionPtr optlist, const char *name, const char *val) 339 { 340 return xf86AddNewOption(optlist, name, val); 341 } 342 343 XF86OptionPtr 344 xf86AddNewOption(XF86OptionPtr head, const char *name, const char *val) 345 { 346 /* XXX These should actually be allocated in the parser library. */ 347 char *tmp = val ? strdup(val) : NULL; 348 char *tmp_name = strdup(name); 349 350 return xf86addNewOption(head, tmp_name, tmp); 351 } 352 353 XF86OptionPtr 354 xf86NewOption(char *name, char *value) 355 { 356 return xf86newOption(name, value); 357 } 358 359 XF86OptionPtr 360 xf86NextOption(XF86OptionPtr list) 361 { 362 return xf86nextOption(list); 363 } 364 365 XF86OptionPtr 366 xf86OptionListCreate(const char **options, int count, int used) 367 { 368 return xf86optionListCreate(options, count, used); 369 } 370 371 XF86OptionPtr 372 xf86OptionListMerge(XF86OptionPtr head, XF86OptionPtr tail) 373 { 374 return xf86optionListMerge(head, tail); 375 } 376 377 void 378 xf86OptionListFree(XF86OptionPtr opt) 379 { 380 xf86optionListFree(opt); 381 } 382 383 char * 384 xf86OptionName(XF86OptionPtr opt) 385 { 386 return xf86optionName(opt); 387 } 388 389 char * 390 xf86OptionValue(XF86OptionPtr opt) 391 { 392 return xf86optionValue(opt); 393 } 394 395 void 396 xf86OptionListReport(XF86OptionPtr parm) 397 { 398 XF86OptionPtr opts = parm; 399 400 while (opts) { 401 if (xf86optionValue(opts)) 402 xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n", 403 xf86optionName(opts), xf86optionValue(opts)); 404 else 405 xf86ErrorFVerb(5, "\tOption \"%s\"\n", xf86optionName(opts)); 406 opts = xf86nextOption(opts); 407 } 408 } 409 410 /* End of XInput-caused section */ 411 412 XF86OptionPtr 413 xf86FindOption(XF86OptionPtr options, const char *name) 414 { 415 return xf86findOption(options, name); 416 } 417 418 const char * 419 xf86FindOptionValue(XF86OptionPtr options, const char *name) 420 { 421 return xf86findOptionValue(options, name); 422 } 423 424 void 425 xf86MarkOptionUsed(XF86OptionPtr option) 426 { 427 if (option != NULL) 428 option->opt_used = TRUE; 429 } 430 431 void 432 xf86MarkOptionUsedByName(XF86OptionPtr options, const char *name) 433 { 434 XF86OptionPtr opt; 435 436 opt = xf86findOption(options, name); 437 if (opt != NULL) 438 opt->opt_used = TRUE; 439 } 440 441 Bool 442 xf86CheckIfOptionUsed(XF86OptionPtr option) 443 { 444 if (option != NULL) 445 return option->opt_used; 446 else 447 return FALSE; 448 } 449 450 Bool 451 xf86CheckIfOptionUsedByName(XF86OptionPtr options, const char *name) 452 { 453 XF86OptionPtr opt; 454 455 opt = xf86findOption(options, name); 456 if (opt != NULL) 457 return opt->opt_used; 458 else 459 return FALSE; 460 } 461 462 void 463 xf86ShowUnusedOptions(int scrnIndex, XF86OptionPtr opt) 464 { 465 while (opt) { 466 if (opt->opt_name && !opt->opt_used) { 467 xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n", 468 opt->opt_name); 469 } 470 opt = opt->list.next; 471 } 472 } 473 474 static Bool 475 GetBoolValue(OptionInfoPtr p, const char *s) 476 { 477 return xf86getBoolValue(&p->value.boolean, s); 478 } 479 480 static Bool 481 ParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p, 482 Bool markUsed) 483 { 484 const char *s; 485 char *end; 486 Bool wasUsed = FALSE; 487 488 if ((s = xf86findOptionValue(options, p->name)) != NULL) { 489 if (markUsed) { 490 wasUsed = xf86CheckIfOptionUsedByName(options, p->name); 491 xf86MarkOptionUsedByName(options, p->name); 492 } 493 switch (p->type) { 494 case OPTV_INTEGER: 495 if (*s == '\0') { 496 if (markUsed) { 497 xf86DrvMsg(scrnIndex, X_WARNING, 498 "Option \"%s\" requires an integer value\n", 499 p->name); 500 } 501 p->found = FALSE; 502 } 503 else { 504 p->value.num = strtoul(s, &end, 0); 505 if (*end == '\0') { 506 p->found = TRUE; 507 } 508 else { 509 if (markUsed) { 510 xf86DrvMsg(scrnIndex, X_WARNING, 511 "Option \"%s\" requires an integer value\n", 512 p->name); 513 } 514 p->found = FALSE; 515 } 516 } 517 break; 518 case OPTV_STRING: 519 if (*s == '\0') { 520 if (markUsed) { 521 xf86DrvMsg(scrnIndex, X_WARNING, 522 "Option \"%s\" requires a string value\n", 523 p->name); 524 } 525 p->found = FALSE; 526 } 527 else { 528 p->value.str = s; 529 p->found = TRUE; 530 } 531 break; 532 case OPTV_ANYSTR: 533 p->value.str = s; 534 p->found = TRUE; 535 break; 536 case OPTV_REAL: 537 if (*s == '\0') { 538 if (markUsed) { 539 xf86DrvMsg(scrnIndex, X_WARNING, 540 "Option \"%s\" requires a floating point " 541 "value\n", p->name); 542 } 543 p->found = FALSE; 544 } 545 else { 546 p->value.realnum = strtod(s, &end); 547 if (*end == '\0') { 548 p->found = TRUE; 549 } 550 else { 551 if (markUsed) { 552 xf86DrvMsg(scrnIndex, X_WARNING, 553 "Option \"%s\" requires a floating point " 554 "value\n", p->name); 555 } 556 p->found = FALSE; 557 } 558 } 559 break; 560 case OPTV_BOOLEAN: 561 if (GetBoolValue(p, s)) { 562 p->found = TRUE; 563 } 564 else { 565 if (markUsed) { 566 xf86DrvMsg(scrnIndex, X_WARNING, 567 "Option \"%s\" requires a boolean value\n", 568 p->name); 569 } 570 p->found = FALSE; 571 } 572 break; 573 case OPTV_PERCENT: 574 { 575 char tmp = 0; 576 577 /* awkward match, but %% doesn't increase the match counter, 578 * hence 100 looks the same as 100% to the caller of sccanf 579 */ 580 if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') { 581 if (markUsed) { 582 xf86DrvMsg(scrnIndex, X_WARNING, 583 "Option \"%s\" requires a percent value\n", 584 p->name); 585 } 586 p->found = FALSE; 587 } 588 else { 589 p->found = TRUE; 590 } 591 } 592 break; 593 case OPTV_FREQ: 594 if (*s == '\0') { 595 if (markUsed) { 596 xf86DrvMsg(scrnIndex, X_WARNING, 597 "Option \"%s\" requires a frequency value\n", 598 p->name); 599 } 600 p->found = FALSE; 601 } 602 else { 603 double freq = strtod(s, &end); 604 int units = 0; 605 606 if (end != s) { 607 p->found = TRUE; 608 if (!xf86NameCmp(end, "Hz")) 609 units = 1; 610 else if (!xf86NameCmp(end, "kHz") || !xf86NameCmp(end, "k")) 611 units = 1000; 612 else if (!xf86NameCmp(end, "MHz") || !xf86NameCmp(end, "M")) 613 units = 1000000; 614 else { 615 if (markUsed) { 616 xf86DrvMsg(scrnIndex, X_WARNING, 617 "Option \"%s\" requires a frequency value\n", 618 p->name); 619 } 620 p->found = FALSE; 621 } 622 if (p->found) 623 freq *= (double) units; 624 } 625 else { 626 if (markUsed) { 627 xf86DrvMsg(scrnIndex, X_WARNING, 628 "Option \"%s\" requires a frequency value\n", 629 p->name); 630 } 631 p->found = FALSE; 632 } 633 if (p->found) { 634 p->value.freq.freq = freq; 635 p->value.freq.units = units; 636 } 637 } 638 break; 639 case OPTV_NONE: 640 /* Should never get here */ 641 p->found = FALSE; 642 break; 643 } 644 if (p->found && markUsed) { 645 int verb = 2; 646 647 if (wasUsed) 648 verb = 4; 649 xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name); 650 if (!(p->type == OPTV_BOOLEAN && *s == 0)) { 651 xf86ErrorFVerb(verb, " \"%s\"", s); 652 } 653 xf86ErrorFVerb(verb, "\n"); 654 } 655 } 656 else if (p->type == OPTV_BOOLEAN) { 657 /* Look for matches with options with or without a "No" prefix. */ 658 char *n, *newn; 659 OptionInfoRec opt; 660 661 n = xf86NormalizeName(p->name); 662 if (!n) { 663 p->found = FALSE; 664 return FALSE; 665 } 666 if (strncmp(n, "no", 2) == 0) { 667 newn = n + 2; 668 } 669 else { 670 free(n); 671 if (asprintf(&n, "No%s", p->name) == -1) { 672 p->found = FALSE; 673 return FALSE; 674 } 675 newn = n; 676 } 677 if ((s = xf86findOptionValue(options, newn)) != NULL) { 678 if (markUsed) 679 xf86MarkOptionUsedByName(options, newn); 680 if (GetBoolValue(&opt, s)) { 681 p->value.boolean = !opt.value.boolean; 682 p->found = TRUE; 683 } 684 else { 685 xf86DrvMsg(scrnIndex, X_WARNING, 686 "Option \"%s\" requires a boolean value\n", newn); 687 p->found = FALSE; 688 } 689 } 690 else { 691 p->found = FALSE; 692 } 693 if (p->found && markUsed) { 694 xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); 695 if (*s != 0) { 696 xf86ErrorFVerb(2, " \"%s\"", s); 697 } 698 xf86ErrorFVerb(2, "\n"); 699 } 700 free(n); 701 } 702 else { 703 p->found = FALSE; 704 } 705 return p->found; 706 } 707 708 void 709 xf86ProcessOptions(int scrnIndex, XF86OptionPtr options, OptionInfoPtr optinfo) 710 { 711 OptionInfoPtr p; 712 713 for (p = optinfo; p->name != NULL; p++) { 714 ParseOptionValue(scrnIndex, options, p, TRUE); 715 } 716 } 717 718 OptionInfoPtr 719 xf86TokenToOptinfo(const OptionInfoRec * table, int token) 720 { 721 const OptionInfoRec *p, *match = NULL, *set = NULL; 722 723 if (!table) { 724 ErrorF("xf86TokenToOptinfo: table is NULL\n"); 725 return NULL; 726 } 727 728 for (p = table; p->token >= 0; p++) { 729 if (p->token == token) { 730 match = p; 731 if (p->found) 732 set = p; 733 } 734 } 735 736 if (set) 737 return (OptionInfoPtr) set; 738 else if (match) 739 return (OptionInfoPtr) match; 740 else 741 return NULL; 742 } 743 744 const char * 745 xf86TokenToOptName(const OptionInfoRec * table, int token) 746 { 747 const OptionInfoRec *p; 748 749 p = xf86TokenToOptinfo(table, token); 750 return p ? p->name : NULL; 751 } 752 753 Bool 754 xf86IsOptionSet(const OptionInfoRec * table, int token) 755 { 756 OptionInfoPtr p; 757 758 p = xf86TokenToOptinfo(table, token); 759 return p && p->found; 760 } 761 762 const char * 763 xf86GetOptValString(const OptionInfoRec * table, int token) 764 { 765 OptionInfoPtr p; 766 767 p = xf86TokenToOptinfo(table, token); 768 if (p && p->found) 769 return p->value.str; 770 else 771 return NULL; 772 } 773 774 Bool 775 xf86GetOptValInteger(const OptionInfoRec * table, int token, int *value) 776 { 777 OptionInfoPtr p; 778 779 p = xf86TokenToOptinfo(table, token); 780 if (p && p->found) { 781 *value = p->value.num; 782 return TRUE; 783 } 784 else 785 return FALSE; 786 } 787 788 Bool 789 xf86GetOptValULong(const OptionInfoRec * table, int token, unsigned long *value) 790 { 791 OptionInfoPtr p; 792 793 p = xf86TokenToOptinfo(table, token); 794 if (p && p->found) { 795 *value = p->value.num; 796 return TRUE; 797 } 798 else 799 return FALSE; 800 } 801 802 Bool 803 xf86GetOptValReal(const OptionInfoRec * table, int token, double *value) 804 { 805 OptionInfoPtr p; 806 807 p = xf86TokenToOptinfo(table, token); 808 if (p && p->found) { 809 *value = p->value.realnum; 810 return TRUE; 811 } 812 else 813 return FALSE; 814 } 815 816 Bool 817 xf86GetOptValFreq(const OptionInfoRec * table, int token, 818 OptFreqUnits expectedUnits, double *value) 819 { 820 OptionInfoPtr p; 821 822 p = xf86TokenToOptinfo(table, token); 823 if (p && p->found) { 824 if (p->value.freq.units > 0) { 825 /* Units give, so the scaling is known. */ 826 switch (expectedUnits) { 827 case OPTUNITS_HZ: 828 *value = p->value.freq.freq; 829 break; 830 case OPTUNITS_KHZ: 831 *value = p->value.freq.freq / 1000.0; 832 break; 833 case OPTUNITS_MHZ: 834 *value = p->value.freq.freq / 1000000.0; 835 break; 836 } 837 } 838 else { 839 /* No units given, so try to guess the scaling. */ 840 switch (expectedUnits) { 841 case OPTUNITS_HZ: 842 *value = p->value.freq.freq; 843 break; 844 case OPTUNITS_KHZ: 845 if (p->value.freq.freq > 1000.0) 846 *value = p->value.freq.freq / 1000.0; 847 else 848 *value = p->value.freq.freq; 849 break; 850 case OPTUNITS_MHZ: 851 if (p->value.freq.freq > 1000000.0) 852 *value = p->value.freq.freq / 1000000.0; 853 else if (p->value.freq.freq > 1000.0) 854 *value = p->value.freq.freq / 1000.0; 855 else 856 *value = p->value.freq.freq; 857 } 858 } 859 return TRUE; 860 } 861 else 862 return FALSE; 863 } 864 865 Bool 866 xf86GetOptValBool(const OptionInfoRec * table, int token, Bool *value) 867 { 868 OptionInfoPtr p; 869 870 p = xf86TokenToOptinfo(table, token); 871 if (p && p->found) { 872 *value = p->value.boolean; 873 return TRUE; 874 } 875 else 876 return FALSE; 877 } 878 879 Bool 880 xf86ReturnOptValBool(const OptionInfoRec * table, int token, Bool def) 881 { 882 OptionInfoPtr p; 883 884 p = xf86TokenToOptinfo(table, token); 885 if (p && p->found) { 886 return p->value.boolean; 887 } 888 else 889 return def; 890 } 891 892 int 893 xf86NameCmp(const char *s1, const char *s2) 894 { 895 return xf86nameCompare(s1, s2); 896 } 897 898 char * 899 xf86NormalizeName(const char *s) 900 { 901 char *ret, *q; 902 const char *p; 903 904 if (s == NULL) 905 return NULL; 906 907 ret = malloc(strlen(s) + 1); 908 for (p = s, q = ret; *p != 0; p++) { 909 switch (*p) { 910 case '_': 911 case ' ': 912 case '\t': 913 continue; 914 default: 915 if (isupper(*p)) 916 *q++ = tolower(*p); 917 else 918 *q++ = *p; 919 } 920 } 921 *q = '\0'; 922 return ret; 923 }