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