/* *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. * *Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the *"Software"), to deal in the Software without restriction, including *without limitation the rights to use, copy, modify, merge, publish, *distribute, sublicense, and/or sell copies of the Software, and to *permit persons to whom the Software is furnished to do so, subject to *the following conditions: * *The above copyright notice and this permission notice shall be *included in all copies or substantial portions of the Software. * *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * *Except as contained in this notice, the name of the XFree86 Project *shall not be used in advertising or otherwise to promote the sale, use *or other dealings in this Software without prior written authorization *from the XFree86 Project. * * Authors: Alexander Gottwald */ #ifdef HAVE_XWIN_CONFIG_H #include #endif #include "win.h" #include "winconfig.h" #include "winmsg.h" #include "globals.h" #include "xkbsrv.h" #ifdef XWIN_XF86CONFIG #ifndef CONFIGPATH #define CONFIGPATH "%A," "%R," \ "/etc/X11/%R," "%P/etc/X11/%R," \ "%E," "%F," \ "/etc/X11/%F," "%P/etc/X11/%F," \ "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ "%P/etc/X11/%X," \ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ "%P/lib/X11/%X" #endif #ifndef CONFIGDIRPATH #define CONFIGDIRPATH "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ "%P/etc/X11/%X," \ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ "%P/lib/X11/%X" #endif XF86ConfigPtr g_xf86configptr = NULL; #endif WinCmdlineRec g_cmdline = { #ifdef XWIN_XF86CONFIG NULL, /* configFile */ NULL, /* configDir */ #endif NULL, /* fontPath */ #ifdef XWIN_XF86CONFIG NULL, /* keyboard */ #endif NULL, /* xkbRules */ NULL, /* xkbModel */ NULL, /* xkbLayout */ NULL, /* xkbVariant */ NULL, /* xkbOptions */ NULL, /* screenname */ NULL, /* mousename */ FALSE, /* emulate3Buttons */ 0 /* emulate3Timeout */ }; winInfoRec g_winInfo = { { /* keyboard */ 0, /* leds */ 500, /* delay */ 30 /* rate */ } , { /* xkb */ NULL, /* rules */ NULL, /* model */ NULL, /* layout */ NULL, /* variant */ NULL, /* options */ } , { FALSE, 50} }; #define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL) #ifdef XWIN_XF86CONFIG serverLayoutRec g_winConfigLayout; static Bool ParseOptionValue(int scrnIndex, void *options, OptionInfoPtr p); static Bool configLayout(serverLayoutPtr, XF86ConfLayoutPtr, char *); static Bool configImpliedLayout(serverLayoutPtr, XF86ConfScreenPtr); static Bool GetBoolValue(OptionInfoPtr p, const char *s); Bool winReadConfigfile() { Bool retval = TRUE; char *filename, *dirname; MessageType filefrom = X_DEFAULT; MessageType dirfrom = X_DEFAULT; char *xf86ConfigFile = NULL; char *xf86ConfigDir = NULL; if (g_cmdline.configFile) { filefrom = X_CMDLINE; xf86ConfigFile = g_cmdline.configFile; } if (g_cmdline.configDir) { dirfrom = X_CMDLINE; xf86ConfigDir = g_cmdline.configDir; } /* Parse config file into data structure */ xf86initConfigFiles(); dirname = xf86openConfigDirFiles(CONFIGDIRPATH, xf86ConfigDir, PROJECTROOT); filename = xf86openConfigFile(CONFIGPATH, xf86ConfigFile, PROJECTROOT); /* Hack for backward compatibility */ if (!filename && from == X_DEFAULT) filename = xf86openConfigFile(CONFIGPATH, "XF86Config", PROJECTROOT); if (filename) { winMsg(from, "Using config file: \"%s\"\n", filename); } else { winMsg(X_ERROR, "Unable to locate/open config file"); if (xf86ConfigFile) ErrorF(": \"%s\"", xf86ConfigFile); ErrorF("\n"); } if (dirname) { winMsg(from, "Using config directory: \"%s\"\n", dirname); } else { winMsg(X_ERROR, "Unable to locate/open config directory"); if (xf86ConfigDir) ErrorF(": \"%s\"", xf86ConfigDir); ErrorF("\n"); } if (!filename && !dirname) { return FALSE; } free(filename); free(dirname); if ((g_xf86configptr = xf86readConfigFile()) == NULL) { winMsg(X_ERROR, "Problem parsing the config file\n"); return FALSE; } xf86closeConfigFile(); LogPrintMarkers(); /* set options from data structure */ if (g_xf86configptr->conf_layout_lst == NULL || g_cmdline.screenname != NULL) { if (g_cmdline.screenname == NULL) { winMsg(X_WARNING, "No Layout section. Using the first Screen section.\n"); } if (!configImpliedLayout(&g_winConfigLayout, g_xf86configptr->conf_screen_lst)) { winMsg(X_ERROR, "Unable to determine the screen layout\n"); return FALSE; } } else { /* Check if layout is given in the config file */ if (g_xf86configptr->conf_flags != NULL) { char *dfltlayout = NULL; void *optlist = g_xf86configptr->conf_flags->flg_option_lst; if (optlist && winFindOption(optlist, "defaultserverlayout")) dfltlayout = winSetStrOption(optlist, "defaultserverlayout", NULL); if (!configLayout(&g_winConfigLayout, g_xf86configptr->conf_layout_lst, dfltlayout)) { winMsg(X_ERROR, "Unable to determine the screen layout\n"); return FALSE; } } else { if (!configLayout(&g_winConfigLayout, g_xf86configptr->conf_layout_lst, NULL)) { winMsg(X_ERROR, "Unable to determine the screen layout\n"); return FALSE; } } } /* setup special config files */ winConfigFiles(); return retval; } #endif /* load layout definitions */ #include "winlayouts.h" /* Set the keyboard configuration */ Bool winConfigKeyboard(DeviceIntPtr pDevice) { char layoutName[KL_NAMELENGTH]; unsigned char layoutFriendlyName[256]; unsigned int layoutNum = 0; unsigned int deviceIdentifier = 0; int keyboardType; #ifdef XWIN_XF86CONFIG XF86ConfInputPtr kbd = NULL; XF86ConfInputPtr input_list = NULL; MessageType kbdfrom = X_CONFIG; #endif MessageType from = X_DEFAULT; char *s = NULL; /* Setup defaults */ XkbGetRulesDflts(&g_winInfo.xkb); /* * Query the windows autorepeat settings and change the xserver defaults. */ { int kbd_delay; DWORD kbd_speed; if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) && SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0)) { switch (kbd_delay) { case 0: g_winInfo.keyboard.delay = 250; break; case 1: g_winInfo.keyboard.delay = 500; break; case 2: g_winInfo.keyboard.delay = 750; break; default: case 3: g_winInfo.keyboard.delay = 1000; break; } g_winInfo.keyboard.rate = (kbd_speed > 0) ? kbd_speed : 1; winMsg(X_PROBED, "Setting autorepeat to delay=%ld, rate=%ld\n", g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); } } keyboardType = GetKeyboardType(0); if (keyboardType > 0 && GetKeyboardLayoutName(layoutName)) { WinKBLayoutPtr pLayout; Bool bfound = FALSE; int pass; layoutNum = strtoul(layoutName, (char **) NULL, 16); if ((layoutNum & 0xffff) == 0x411) { if (keyboardType == 7) { /* Japanese layouts have problems with key event messages such as the lack of WM_KEYUP for Caps Lock key. Loading US layout fixes this problem. */ if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL) winMsg(X_INFO, "Loading US keyboard layout.\n"); else winMsg(X_ERROR, "LoadKeyboardLayout failed.\n"); } } /* Discover the friendly name of the current layout */ { HKEY regkey = NULL; const char regtempl[] = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"; char *regpath; DWORD namesize = sizeof(layoutFriendlyName); regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1); strcpy(regpath, regtempl); strcat(regpath, layoutName); if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key)) RegQueryValueEx(regkey, "Layout Text", 0, NULL, layoutFriendlyName, &namesize); /* Close registry key */ if (regkey) RegCloseKey(regkey); free(regpath); } winMsg(X_PROBED, "Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n", layoutName, layoutNum, layoutFriendlyName, keyboardType); deviceIdentifier = layoutNum >> 16; for (pass = 0; pass < 2; pass++) { /* If we didn't find an exact match for the input locale identifier, try to find an match on the language identifier part only */ if (pass == 1) layoutNum = (layoutNum & 0xffff); for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) { if (pLayout->winlayout != layoutNum) continue; if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType) continue; bfound = TRUE; winMsg(X_PROBED, "Found matching XKB configuration \"%s\"\n", pLayout->layoutname); winMsg(X_PROBED, "Model = \"%s\" Layout = \"%s\"" " Variant = \"%s\" Options = \"%s\"\n", pLayout->xkbmodel ? pLayout->xkbmodel : "none", pLayout->xkblayout ? pLayout->xkblayout : "none", pLayout->xkbvariant ? pLayout->xkbvariant : "none", pLayout->xkboptions ? pLayout->xkboptions : "none"); g_winInfo.xkb.model = pLayout->xkbmodel; g_winInfo.xkb.layout = pLayout->xkblayout; g_winInfo.xkb.variant = pLayout->xkbvariant; g_winInfo.xkb.options = pLayout->xkboptions; if (deviceIdentifier == 0xa000) { winMsg(X_PROBED, "Windows keyboard layout device identifier indicates Macintosh, setting Model = \"macintosh\""); g_winInfo.xkb.model = "macintosh"; } break; } if (bfound) break; } if (!bfound) { winMsg(X_ERROR, "Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n", layoutFriendlyName, layoutName); } } /* parse the configuration */ #ifdef XWIN_XF86CONFIG if (g_cmdline.keyboard) kbdfrom = X_CMDLINE; /* * Until the layout code is finished, I search for the keyboard * device and configure the server with it. */ if (g_xf86configptr != NULL) input_list = g_xf86configptr->conf_input_lst; while (input_list != NULL) { if (winNameCompare(input_list->inp_driver, "keyboard") == 0) { /* Check if device name matches requested name */ if (g_cmdline.keyboard && winNameCompare(input_list->inp_identifier, g_cmdline.keyboard)) continue; kbd = input_list; } input_list = input_list->list.next; } if (kbd != NULL) { if (kbd->inp_identifier) winMsg(kbdfrom, "Using keyboard \"%s\" as primary keyboard\n", kbd->inp_identifier); if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL))) { if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay, &g_winInfo.keyboard.rate) != 2) || (g_winInfo.keyboard.delay < 1) || (g_winInfo.keyboard.rate == 0) || (1000 / g_winInfo.keyboard.rate) < 1) { winErrorFVerb(2, "\"%s\" is not a valid AutoRepeat value", s); free(s); return FALSE; } free(s); winMsg(X_CONFIG, "AutoRepeat: %ld %ld\n", g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); } #endif s = NULL; if (g_cmdline.xkbRules) { s = g_cmdline.xkbRules; from = X_CMDLINE; } #ifdef XWIN_XF86CONFIG else { s = winSetStrOption(kbd->inp_option_lst, "XkbRules", NULL); from = X_CONFIG; } #endif if (s) { g_winInfo.xkb.rules = NULL_IF_EMPTY(s); winMsg(from, "XKB: rules: \"%s\"\n", s); } s = NULL; if (g_cmdline.xkbModel) { s = g_cmdline.xkbModel; from = X_CMDLINE; } #ifdef XWIN_XF86CONFIG else { s = winSetStrOption(kbd->inp_option_lst, "XkbModel", NULL); from = X_CONFIG; } #endif if (s) { g_winInfo.xkb.model = NULL_IF_EMPTY(s); winMsg(from, "XKB: model: \"%s\"\n", s); } s = NULL; if (g_cmdline.xkbLayout) { s = g_cmdline.xkbLayout; from = X_CMDLINE; } #ifdef XWIN_XF86CONFIG else { s = winSetStrOption(kbd->inp_option_lst, "XkbLayout", NULL); from = X_CONFIG; } #endif if (s) { g_winInfo.xkb.layout = NULL_IF_EMPTY(s); winMsg(from, "XKB: layout: \"%s\"\n", s); } s = NULL; if (g_cmdline.xkbVariant) { s = g_cmdline.xkbVariant; from = X_CMDLINE; } #ifdef XWIN_XF86CONFIG else { s = winSetStrOption(kbd->inp_option_lst, "XkbVariant", NULL); from = X_CONFIG; } #endif if (s) { g_winInfo.xkb.variant = NULL_IF_EMPTY(s); winMsg(from, "XKB: variant: \"%s\"\n", s); } s = NULL; if (g_cmdline.xkbOptions) { s = g_cmdline.xkbOptions; from = X_CMDLINE; } #ifdef XWIN_XF86CONFIG else { s = winSetStrOption(kbd->inp_option_lst, "XkbOptions", NULL); from = X_CONFIG; } #endif if (s) { g_winInfo.xkb.options = NULL_IF_EMPTY(s); winMsg(from, "XKB: options: \"%s\"\n", s); } #ifdef XWIN_XF86CONFIG } #endif return TRUE; } #ifdef XWIN_XF86CONFIG Bool winConfigMouse(DeviceIntPtr pDevice) { MessageType mousefrom = X_CONFIG; XF86ConfInputPtr mouse = NULL; XF86ConfInputPtr input_list = NULL; if (g_cmdline.mouse) mousefrom = X_CMDLINE; if (g_xf86configptr != NULL) input_list = g_xf86configptr->conf_input_lst; while (input_list != NULL) { if (winNameCompare(input_list->inp_driver, "mouse") == 0) { /* Check if device name matches requested name */ if (g_cmdline.mouse && winNameCompare(input_list->inp_identifier, g_cmdline.mouse)) continue; mouse = input_list; } input_list = input_list->list.next; } if (mouse != NULL) { if (mouse->inp_identifier) winMsg(mousefrom, "Using pointer \"%s\" as primary pointer\n", mouse->inp_identifier); g_winInfo.pointer.emulate3Buttons = winSetBoolOption(mouse->inp_option_lst, "Emulate3Buttons", FALSE); if (g_cmdline.emulate3buttons) g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons; g_winInfo.pointer.emulate3Timeout = winSetIntOption(mouse->inp_option_lst, "Emulate3Timeout", 50); if (g_cmdline.emulate3timeout) g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout; } else { winMsg(X_ERROR, "No primary pointer configured\n"); winMsg(X_DEFAULT, "Using compiletime defaults for pointer\n"); } return TRUE; } Bool winConfigFiles() { MessageType from; XF86ConfFilesPtr filesptr = NULL; /* set some shortcuts */ if (g_xf86configptr != NULL) { filesptr = g_xf86configptr->conf_files; } /* Fontpath */ from = X_DEFAULT; if (g_cmdline.fontPath) { from = X_CMDLINE; defaultFontPath = g_cmdline.fontPath; } else if (filesptr != NULL && filesptr->file_fontpath) { from = X_CONFIG; defaultFontPath = strdup(filesptr->file_fontpath); } winMsg(from, "FontPath set to \"%s\"\n", defaultFontPath); return TRUE; } #else Bool winConfigFiles(void) { /* Fontpath */ if (g_cmdline.fontPath) { defaultFontPath = g_cmdline.fontPath; winMsg(X_CMDLINE, "FontPath set to \"%s\"\n", defaultFontPath); } return TRUE; } #endif Bool winConfigOptions(void) { return TRUE; } Bool winConfigScreens(void) { return TRUE; } #ifdef XWIN_XF86CONFIG char * winSetStrOption(void *optlist, const char *name, char *deflt) { OptionInfoRec o; o.name = name; o.type = OPTV_STRING; if (ParseOptionValue(-1, optlist, &o)) deflt = o.value.str; if (deflt) return strdup(deflt); else return NULL; } int winSetBoolOption(void *optlist, const char *name, int deflt) { OptionInfoRec o; o.name = name; o.type = OPTV_BOOLEAN; if (ParseOptionValue(-1, optlist, &o)) deflt = o.value.boolean; return deflt; } int winSetIntOption(void *optlist, const char *name, int deflt) { OptionInfoRec o; o.name = name; o.type = OPTV_INTEGER; if (ParseOptionValue(-1, optlist, &o)) deflt = o.value.num; return deflt; } double winSetRealOption(void *optlist, const char *name, double deflt) { OptionInfoRec o; o.name = name; o.type = OPTV_REAL; if (ParseOptionValue(-1, optlist, &o)) deflt = o.value.realnum; return deflt; } double winSetPercentOption(void *optlist, const char *name, double deflt) { OptionInfoRec o; o.name = name; o.type = OPTV_PERCENT; if (ParseOptionValue(-1, optlist, &o)) deflt = o.value.realnum; return deflt; } #endif /* * Compare two strings for equality. This is caseinsensitive and * The characters '_', ' ' (space) and '\t' (tab) are treated as * not existing. */ int winNameCompare(const char *s1, const char *s2) { char c1, c2; if (!s1 || *s1 == 0) { if (!s2 || *s2 == 0) return 0; else return 1; } while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') s1++; while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; c1 = (isupper((int) *s1) ? tolower((int) *s1) : *s1); c2 = (isupper((int) *s2) ? tolower((int) *s2) : *s2); while (c1 == c2) { if (c1 == 0) return 0; s1++; s2++; while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') s1++; while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; c1 = (isupper((int) *s1) ? tolower((int) *s1) : *s1); c2 = (isupper((int) *s2) ? tolower((int) *s2) : *s2); } return c1 - c2; } #ifdef XWIN_XF86CONFIG /* * Find the named option in the list. * @return the pointer to the option record, or NULL if not found. */ XF86OptionPtr winFindOption(XF86OptionPtr list, const char *name) { while (list) { if (winNameCompare(list->opt_name, name) == 0) return list; list = list->list.next; } return NULL; } /* * Find the Value of an named option. * @return The option value or NULL if not found. */ char * winFindOptionValue(XF86OptionPtr list, const char *name) { list = winFindOption(list, name); if (list) { if (list->opt_val) return list->opt_val; else return ""; } return NULL; } /* * Parse the option. */ static Bool ParseOptionValue(int scrnIndex, void *options, OptionInfoPtr p) { char *s, *end; if ((s = winFindOptionValue(options, p->name)) != NULL) { switch (p->type) { case OPTV_INTEGER: if (*s == '\0') { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires an integer value\n", p->name); p->found = FALSE; } else { p->value.num = strtoul(s, &end, 0); if (*end == '\0') { p->found = TRUE; } else { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires an integer value\n", p->name); p->found = FALSE; } } break; case OPTV_STRING: if (*s == '\0') { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a string value\n", p->name); p->found = FALSE; } else { p->value.str = s; p->found = TRUE; } break; case OPTV_ANYSTR: p->value.str = s; p->found = TRUE; break; case OPTV_REAL: if (*s == '\0') { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a floating point value\n", p->name); p->found = FALSE; } else { p->value.realnum = strtod(s, &end); if (*end == '\0') { p->found = TRUE; } else { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a floating point value\n", p->name); p->found = FALSE; } } break; case OPTV_BOOLEAN: if (GetBoolValue(p, s)) { p->found = TRUE; } else { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a boolean value\n", p->name); p->found = FALSE; } break; case OPTV_PERCENT: if (*s == '\0') { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a percent value\n", p->name); p->found = FALSE; } else { double percent = strtod(s, &end); if (end != s && winNameCompare(end, "%")) { p->found = TRUE; p->value.realnum = percent; } else { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a frequency value\n", p->name); p->found = FALSE; } } case OPTV_FREQ: if (*s == '\0') { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a frequency value\n", p->name); p->found = FALSE; } else { double freq = strtod(s, &end); int units = 0; if (end != s) { p->found = TRUE; if (!winNameCompare(end, "Hz")) units = 1; else if (!winNameCompare(end, "kHz") || !winNameCompare(end, "k")) units = 1000; else if (!winNameCompare(end, "MHz") || !winNameCompare(end, "M")) units = 1000000; else { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a frequency value\n", p->name); p->found = FALSE; } if (p->found) freq *= (double) units; } else { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a frequency value\n", p->name); p->found = FALSE; } if (p->found) { p->value.freq.freq = freq; p->value.freq.units = units; } } break; case OPTV_NONE: /* Should never get here */ p->found = FALSE; break; } if (p->found) { winDrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", p->name); if (!(p->type == OPTV_BOOLEAN && *s == 0)) { winErrorFVerb(2, " \"%s\"", s); } winErrorFVerb(2, "\n"); } } else if (p->type == OPTV_BOOLEAN) { /* Look for matches with options with or without a "No" prefix. */ char *n, *newn; OptionInfoRec opt; n = winNormalizeName(p->name); if (!n) { p->found = FALSE; return FALSE; } if (strncmp(n, "no", 2) == 0) { newn = n + 2; } else { free(n); n = malloc(strlen(p->name) + 2 + 1); if (!n) { p->found = FALSE; return FALSE; } strcpy(n, "No"); strcat(n, p->name); newn = n; } if ((s = winFindOptionValue(options, newn)) != NULL) { if (GetBoolValue(&opt, s)) { p->value.boolean = !opt.value.boolean; p->found = TRUE; } else { winDrvMsg(scrnIndex, X_WARNING, "Option \"%s\" requires a boolean value\n", newn); p->found = FALSE; } } else { p->found = FALSE; } if (p->found) { winDrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); if (*s != 0) { winErrorFVerb(2, " \"%s\"", s); } winErrorFVerb(2, "\n"); } free(n); } else { p->found = FALSE; } return p->found; } static Bool configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, char *default_layout) { #if 0 #pragma warn UNIMPLEMENTED #endif return TRUE; } static Bool configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen) { #if 0 #pragma warn UNIMPLEMENTED #endif return TRUE; } static Bool GetBoolValue(OptionInfoPtr p, const char *s) { if (*s == 0) { p->value.boolean = TRUE; } else { if (winNameCompare(s, "1") == 0) p->value.boolean = TRUE; else if (winNameCompare(s, "on") == 0) p->value.boolean = TRUE; else if (winNameCompare(s, "true") == 0) p->value.boolean = TRUE; else if (winNameCompare(s, "yes") == 0) p->value.boolean = TRUE; else if (winNameCompare(s, "0") == 0) p->value.boolean = FALSE; else if (winNameCompare(s, "off") == 0) p->value.boolean = FALSE; else if (winNameCompare(s, "false") == 0) p->value.boolean = FALSE; else if (winNameCompare(s, "no") == 0) p->value.boolean = FALSE; } return TRUE; } #endif char * winNormalizeName(const char *s) { char *ret, *q; const char *p; if (s == NULL) return NULL; ret = malloc(strlen(s) + 1); for (p = s, q = ret; *p != 0; p++) { switch (*p) { case '_': case ' ': case '\t': continue; default: if (isupper((int) *p)) *q++ = tolower((int) *p); else *q++ = *p; } } *q = '\0'; return ret; }