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