winconfig.c revision 35c4bbdf
105b261ecSmrg/* 205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 305b261ecSmrg * 405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining 505b261ecSmrg * a copy of this software and associated documentation files (the 605b261ecSmrg *"Software"), to deal in the Software without restriction, including 705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish, 805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to 905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to 1005b261ecSmrg *the following conditions: 1105b261ecSmrg * 1205b261ecSmrg *The above copyright notice and this permission notice shall be 1305b261ecSmrg *included in all copies or substantial portions of the Software. 1405b261ecSmrg * 1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2205b261ecSmrg * 2305b261ecSmrg *Except as contained in this notice, the name of the XFree86 Project 2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use 2505b261ecSmrg *or other dealings in this Software without prior written authorization 2605b261ecSmrg *from the XFree86 Project. 2705b261ecSmrg * 2805b261ecSmrg * Authors: Alexander Gottwald 2905b261ecSmrg */ 3005b261ecSmrg 3105b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H 3205b261ecSmrg#include <xwin-config.h> 3305b261ecSmrg#endif 3405b261ecSmrg#include "win.h" 3505b261ecSmrg#include "winconfig.h" 3605b261ecSmrg#include "winmsg.h" 3705b261ecSmrg#include "globals.h" 3805b261ecSmrg 396747b715Smrg#include "xkbsrv.h" 4005b261ecSmrg 4105b261ecSmrg#ifdef XWIN_XF86CONFIG 4205b261ecSmrg#ifndef CONFIGPATH 4305b261ecSmrg#define CONFIGPATH "%A," "%R," \ 4405b261ecSmrg "/etc/X11/%R," "%P/etc/X11/%R," \ 4505b261ecSmrg "%E," "%F," \ 4605b261ecSmrg "/etc/X11/%F," "%P/etc/X11/%F," \ 4705b261ecSmrg "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ 4805b261ecSmrg "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ 4905b261ecSmrg "%P/etc/X11/%X," \ 5005b261ecSmrg "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ 5105b261ecSmrg "%P/lib/X11/%X" 5205b261ecSmrg#endif 536747b715Smrg#ifndef CONFIGDIRPATH 546747b715Smrg#define CONFIGDIRPATH "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ 556747b715Smrg "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ 566747b715Smrg "%P/etc/X11/%X," \ 576747b715Smrg "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ 586747b715Smrg "%P/lib/X11/%X" 596747b715Smrg#endif 6005b261ecSmrg 6105b261ecSmrgXF86ConfigPtr g_xf86configptr = NULL; 6205b261ecSmrg#endif 6305b261ecSmrg 6405b261ecSmrgWinCmdlineRec g_cmdline = { 6505b261ecSmrg#ifdef XWIN_XF86CONFIG 6635c4bbdfSmrg NULL, /* configFile */ 6735c4bbdfSmrg NULL, /* configDir */ 6805b261ecSmrg#endif 6935c4bbdfSmrg NULL, /* fontPath */ 7005b261ecSmrg#ifdef XWIN_XF86CONFIG 7135c4bbdfSmrg NULL, /* keyboard */ 7205b261ecSmrg#endif 7335c4bbdfSmrg NULL, /* xkbRules */ 7435c4bbdfSmrg NULL, /* xkbModel */ 7535c4bbdfSmrg NULL, /* xkbLayout */ 7635c4bbdfSmrg NULL, /* xkbVariant */ 7735c4bbdfSmrg NULL, /* xkbOptions */ 7835c4bbdfSmrg NULL, /* screenname */ 7935c4bbdfSmrg NULL, /* mousename */ 8035c4bbdfSmrg FALSE, /* emulate3Buttons */ 8135c4bbdfSmrg 0 /* emulate3Timeout */ 8205b261ecSmrg}; 8305b261ecSmrg 8405b261ecSmrgwinInfoRec g_winInfo = { 8535c4bbdfSmrg { /* keyboard */ 8635c4bbdfSmrg 0, /* leds */ 8735c4bbdfSmrg 500, /* delay */ 8835c4bbdfSmrg 30 /* rate */ 8935c4bbdfSmrg } 9035c4bbdfSmrg , 9135c4bbdfSmrg { /* xkb */ 9235c4bbdfSmrg NULL, /* rules */ 9335c4bbdfSmrg NULL, /* model */ 9435c4bbdfSmrg NULL, /* layout */ 9535c4bbdfSmrg NULL, /* variant */ 9635c4bbdfSmrg NULL, /* options */ 9735c4bbdfSmrg } 9835c4bbdfSmrg , 9935c4bbdfSmrg { 10035c4bbdfSmrg FALSE, 10135c4bbdfSmrg 50} 10205b261ecSmrg}; 10305b261ecSmrg 10405b261ecSmrg#define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL) 10505b261ecSmrg 10605b261ecSmrg#ifdef XWIN_XF86CONFIG 10705b261ecSmrgserverLayoutRec g_winConfigLayout; 10805b261ecSmrg 10935c4bbdfSmrgstatic Bool ParseOptionValue(int scrnIndex, void *options, OptionInfoPtr p); 11035c4bbdfSmrgstatic Bool configLayout(serverLayoutPtr, XF86ConfLayoutPtr, char *); 11135c4bbdfSmrgstatic Bool configImpliedLayout(serverLayoutPtr, XF86ConfScreenPtr); 11235c4bbdfSmrgstatic Bool GetBoolValue(OptionInfoPtr p, const char *s); 11305b261ecSmrg 11405b261ecSmrgBool 11535c4bbdfSmrgwinReadConfigfile() 11605b261ecSmrg{ 11735c4bbdfSmrg Bool retval = TRUE; 11835c4bbdfSmrg char *filename, *dirname; 11935c4bbdfSmrg MessageType filefrom = X_DEFAULT; 12035c4bbdfSmrg MessageType dirfrom = X_DEFAULT; 12135c4bbdfSmrg char *xf86ConfigFile = NULL; 12235c4bbdfSmrg char *xf86ConfigDir = NULL; 12335c4bbdfSmrg 12435c4bbdfSmrg if (g_cmdline.configFile) { 12535c4bbdfSmrg filefrom = X_CMDLINE; 12635c4bbdfSmrg xf86ConfigFile = g_cmdline.configFile; 12705b261ecSmrg } 12835c4bbdfSmrg if (g_cmdline.configDir) { 12935c4bbdfSmrg dirfrom = X_CMDLINE; 13035c4bbdfSmrg xf86ConfigDir = g_cmdline.configDir; 1316747b715Smrg } 13205b261ecSmrg 13335c4bbdfSmrg /* Parse config file into data structure */ 13435c4bbdfSmrg xf86initConfigFiles(); 13535c4bbdfSmrg dirname = xf86openConfigDirFiles(CONFIGDIRPATH, xf86ConfigDir, PROJECTROOT); 13635c4bbdfSmrg filename = xf86openConfigFile(CONFIGPATH, xf86ConfigFile, PROJECTROOT); 1376747b715Smrg 13835c4bbdfSmrg /* Hack for backward compatibility */ 13935c4bbdfSmrg if (!filename && from == X_DEFAULT) 14035c4bbdfSmrg filename = xf86openConfigFile(CONFIGPATH, "XF86Config", PROJECTROOT); 14105b261ecSmrg 14235c4bbdfSmrg if (filename) { 14335c4bbdfSmrg winMsg(from, "Using config file: \"%s\"\n", filename); 14405b261ecSmrg } 14535c4bbdfSmrg else { 14635c4bbdfSmrg winMsg(X_ERROR, "Unable to locate/open config file"); 14735c4bbdfSmrg if (xf86ConfigFile) 14835c4bbdfSmrg ErrorF(": \"%s\"", xf86ConfigFile); 14935c4bbdfSmrg ErrorF("\n"); 1506747b715Smrg } 15135c4bbdfSmrg if (dirname) { 15235c4bbdfSmrg winMsg(from, "Using config directory: \"%s\"\n", dirname); 1536747b715Smrg } 15435c4bbdfSmrg else { 15535c4bbdfSmrg winMsg(X_ERROR, "Unable to locate/open config directory"); 15635c4bbdfSmrg if (xf86ConfigDir) 15735c4bbdfSmrg ErrorF(": \"%s\"", xf86ConfigDir); 15835c4bbdfSmrg ErrorF("\n"); 1596747b715Smrg } 16035c4bbdfSmrg if (!filename && !dirname) { 16135c4bbdfSmrg return FALSE; 16205b261ecSmrg } 16335c4bbdfSmrg free(filename); 16435c4bbdfSmrg free(dirname); 16535c4bbdfSmrg if ((g_xf86configptr = xf86readConfigFile()) == NULL) { 16635c4bbdfSmrg winMsg(X_ERROR, "Problem parsing the config file\n"); 16735c4bbdfSmrg return FALSE; 16805b261ecSmrg } 16935c4bbdfSmrg xf86closeConfigFile(); 17005b261ecSmrg 17135c4bbdfSmrg LogPrintMarkers(); 17205b261ecSmrg 17335c4bbdfSmrg /* set options from data structure */ 17405b261ecSmrg 17535c4bbdfSmrg if (g_xf86configptr->conf_layout_lst == NULL || 17635c4bbdfSmrg g_cmdline.screenname != NULL) { 17735c4bbdfSmrg if (g_cmdline.screenname == NULL) { 17835c4bbdfSmrg winMsg(X_WARNING, 17935c4bbdfSmrg "No Layout section. Using the first Screen section.\n"); 18035c4bbdfSmrg } 18135c4bbdfSmrg if (!configImpliedLayout(&g_winConfigLayout, 18235c4bbdfSmrg g_xf86configptr->conf_screen_lst)) { 18335c4bbdfSmrg winMsg(X_ERROR, "Unable to determine the screen layout\n"); 18435c4bbdfSmrg return FALSE; 18535c4bbdfSmrg } 18605b261ecSmrg } 18735c4bbdfSmrg else { 18835c4bbdfSmrg /* Check if layout is given in the config file */ 18935c4bbdfSmrg if (g_xf86configptr->conf_flags != NULL) { 19035c4bbdfSmrg char *dfltlayout = NULL; 19135c4bbdfSmrg void *optlist = g_xf86configptr->conf_flags->flg_option_lst; 19235c4bbdfSmrg 19335c4bbdfSmrg if (optlist && winFindOption(optlist, "defaultserverlayout")) 19435c4bbdfSmrg dfltlayout = 19535c4bbdfSmrg winSetStrOption(optlist, "defaultserverlayout", NULL); 19635c4bbdfSmrg 19735c4bbdfSmrg if (!configLayout(&g_winConfigLayout, 19835c4bbdfSmrg g_xf86configptr->conf_layout_lst, dfltlayout)) { 19935c4bbdfSmrg winMsg(X_ERROR, "Unable to determine the screen layout\n"); 20035c4bbdfSmrg return FALSE; 20135c4bbdfSmrg } 20235c4bbdfSmrg } 20335c4bbdfSmrg else { 20435c4bbdfSmrg if (!configLayout(&g_winConfigLayout, 20535c4bbdfSmrg g_xf86configptr->conf_layout_lst, NULL)) { 20635c4bbdfSmrg winMsg(X_ERROR, "Unable to determine the screen layout\n"); 20735c4bbdfSmrg return FALSE; 20835c4bbdfSmrg } 20935c4bbdfSmrg } 21005b261ecSmrg } 21105b261ecSmrg 21235c4bbdfSmrg /* setup special config files */ 21335c4bbdfSmrg winConfigFiles(); 21435c4bbdfSmrg return retval; 21505b261ecSmrg} 21605b261ecSmrg#endif 21705b261ecSmrg 21805b261ecSmrg/* load layout definitions */ 21905b261ecSmrg#include "winlayouts.h" 22005b261ecSmrg 22105b261ecSmrg/* Set the keyboard configuration */ 22205b261ecSmrgBool 22335c4bbdfSmrgwinConfigKeyboard(DeviceIntPtr pDevice) 22405b261ecSmrg{ 22535c4bbdfSmrg char layoutName[KL_NAMELENGTH]; 22635c4bbdfSmrg unsigned char layoutFriendlyName[256]; 22735c4bbdfSmrg unsigned int layoutNum = 0; 22835c4bbdfSmrg unsigned int deviceIdentifier = 0; 22935c4bbdfSmrg int keyboardType; 23035c4bbdfSmrg 23105b261ecSmrg#ifdef XWIN_XF86CONFIG 23235c4bbdfSmrg XF86ConfInputPtr kbd = NULL; 23335c4bbdfSmrg XF86ConfInputPtr input_list = NULL; 23435c4bbdfSmrg MessageType kbdfrom = X_CONFIG; 23505b261ecSmrg#endif 23635c4bbdfSmrg MessageType from = X_DEFAULT; 23735c4bbdfSmrg char *s = NULL; 2389ace9065Smrg 23935c4bbdfSmrg /* Setup defaults */ 24035c4bbdfSmrg XkbGetRulesDflts(&g_winInfo.xkb); 24135c4bbdfSmrg 24235c4bbdfSmrg /* 24335c4bbdfSmrg * Query the windows autorepeat settings and change the xserver defaults. 24435c4bbdfSmrg */ 2459ace9065Smrg { 24635c4bbdfSmrg int kbd_delay; 24735c4bbdfSmrg DWORD kbd_speed; 24835c4bbdfSmrg 24935c4bbdfSmrg if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) && 25035c4bbdfSmrg SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0)) { 25135c4bbdfSmrg switch (kbd_delay) { 25235c4bbdfSmrg case 0: 25335c4bbdfSmrg g_winInfo.keyboard.delay = 250; 25435c4bbdfSmrg break; 25535c4bbdfSmrg case 1: 25635c4bbdfSmrg g_winInfo.keyboard.delay = 500; 25735c4bbdfSmrg break; 25835c4bbdfSmrg case 2: 25935c4bbdfSmrg g_winInfo.keyboard.delay = 750; 26035c4bbdfSmrg break; 26135c4bbdfSmrg default: 26235c4bbdfSmrg case 3: 26335c4bbdfSmrg g_winInfo.keyboard.delay = 1000; 26435c4bbdfSmrg break; 26535c4bbdfSmrg } 26635c4bbdfSmrg g_winInfo.keyboard.rate = (kbd_speed > 0) ? kbd_speed : 1; 26735c4bbdfSmrg winMsgVerb(X_PROBED, 1, "Setting autorepeat to delay=%ld, rate=%ld\n", 26835c4bbdfSmrg g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); 26935c4bbdfSmrg } 2709ace9065Smrg } 2719ace9065Smrg 27235c4bbdfSmrg keyboardType = GetKeyboardType(0); 27335c4bbdfSmrg if (keyboardType > 0 && GetKeyboardLayoutName(layoutName)) { 27435c4bbdfSmrg WinKBLayoutPtr pLayout; 27535c4bbdfSmrg Bool bfound = FALSE; 27635c4bbdfSmrg int pass; 27735c4bbdfSmrg 27835c4bbdfSmrg layoutNum = strtoul(layoutName, (char **) NULL, 16); 27935c4bbdfSmrg if ((layoutNum & 0xffff) == 0x411) { 28035c4bbdfSmrg if (keyboardType == 7) { 28135c4bbdfSmrg /* Japanese layouts have problems with key event messages 28235c4bbdfSmrg such as the lack of WM_KEYUP for Caps Lock key. 28335c4bbdfSmrg Loading US layout fixes this problem. */ 28435c4bbdfSmrg if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL) 28535c4bbdfSmrg winMsg(X_INFO, "Loading US keyboard layout.\n"); 28635c4bbdfSmrg else 28735c4bbdfSmrg winMsg(X_ERROR, "LoadKeyboardLayout failed.\n"); 28835c4bbdfSmrg } 28935c4bbdfSmrg } 2909ace9065Smrg 29135c4bbdfSmrg /* Discover the friendly name of the current layout */ 29235c4bbdfSmrg { 29335c4bbdfSmrg HKEY regkey = NULL; 29435c4bbdfSmrg const char regtempl[] = 29535c4bbdfSmrg "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"; 29635c4bbdfSmrg char *regpath; 29735c4bbdfSmrg DWORD namesize = sizeof(layoutFriendlyName); 29835c4bbdfSmrg 29935c4bbdfSmrg regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1); 30035c4bbdfSmrg strcpy(regpath, regtempl); 30135c4bbdfSmrg strcat(regpath, layoutName); 30235c4bbdfSmrg 30335c4bbdfSmrg if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key)) 30435c4bbdfSmrg RegQueryValueEx(regkey, "Layout Text", 0, NULL, 30535c4bbdfSmrg layoutFriendlyName, &namesize); 30635c4bbdfSmrg 30735c4bbdfSmrg /* Close registry key */ 30835c4bbdfSmrg if (regkey) 30935c4bbdfSmrg RegCloseKey(regkey); 31035c4bbdfSmrg free(regpath); 31135c4bbdfSmrg } 3129ace9065Smrg 3139ace9065Smrg winMsg(X_PROBED, 31435c4bbdfSmrg "Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n", 31535c4bbdfSmrg layoutName, layoutNum, layoutFriendlyName, keyboardType); 31635c4bbdfSmrg 31735c4bbdfSmrg deviceIdentifier = layoutNum >> 16; 31835c4bbdfSmrg for (pass = 0; pass < 2; pass++) { 31935c4bbdfSmrg /* If we didn't find an exact match for the input locale identifer, 32035c4bbdfSmrg try to find an match on the language identifier part only */ 32135c4bbdfSmrg if (pass == 1) 32235c4bbdfSmrg layoutNum = (layoutNum & 0xffff); 32335c4bbdfSmrg 32435c4bbdfSmrg for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) { 32535c4bbdfSmrg if (pLayout->winlayout != layoutNum) 32635c4bbdfSmrg continue; 32735c4bbdfSmrg if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType) 32835c4bbdfSmrg continue; 32935c4bbdfSmrg 33035c4bbdfSmrg bfound = TRUE; 33135c4bbdfSmrg winMsg(X_PROBED, 33235c4bbdfSmrg "Found matching XKB configuration \"%s\"\n", 33335c4bbdfSmrg pLayout->layoutname); 33435c4bbdfSmrg 33535c4bbdfSmrg winMsg(X_PROBED, 33635c4bbdfSmrg "Model = \"%s\" Layout = \"%s\"" 33735c4bbdfSmrg " Variant = \"%s\" Options = \"%s\"\n", 33835c4bbdfSmrg pLayout->xkbmodel ? pLayout->xkbmodel : "none", 33935c4bbdfSmrg pLayout->xkblayout ? pLayout->xkblayout : "none", 34035c4bbdfSmrg pLayout->xkbvariant ? pLayout->xkbvariant : "none", 34135c4bbdfSmrg pLayout->xkboptions ? pLayout->xkboptions : "none"); 34235c4bbdfSmrg 34335c4bbdfSmrg g_winInfo.xkb.model = pLayout->xkbmodel; 34435c4bbdfSmrg g_winInfo.xkb.layout = pLayout->xkblayout; 34535c4bbdfSmrg g_winInfo.xkb.variant = pLayout->xkbvariant; 34635c4bbdfSmrg g_winInfo.xkb.options = pLayout->xkboptions; 34735c4bbdfSmrg 34835c4bbdfSmrg if (deviceIdentifier == 0xa000) { 34935c4bbdfSmrg winMsg(X_PROBED, "Windows keyboard layout device identifier indicates Macintosh, setting Model = \"macintosh\""); 35035c4bbdfSmrg g_winInfo.xkb.model = "macintosh"; 35135c4bbdfSmrg } 35235c4bbdfSmrg 35335c4bbdfSmrg break; 35435c4bbdfSmrg } 3559ace9065Smrg 35635c4bbdfSmrg if (bfound) 35735c4bbdfSmrg break; 35835c4bbdfSmrg } 3599ace9065Smrg 36035c4bbdfSmrg if (!bfound) { 36135c4bbdfSmrg winMsg(X_ERROR, 36235c4bbdfSmrg "Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n", 36335c4bbdfSmrg layoutFriendlyName, layoutName); 36435c4bbdfSmrg } 36535c4bbdfSmrg } 3669ace9065Smrg 36735c4bbdfSmrg /* parse the configuration */ 36805b261ecSmrg#ifdef XWIN_XF86CONFIG 36935c4bbdfSmrg if (g_cmdline.keyboard) 37035c4bbdfSmrg kbdfrom = X_CMDLINE; 37135c4bbdfSmrg 37235c4bbdfSmrg /* 37335c4bbdfSmrg * Until the layout code is finished, I search for the keyboard 37435c4bbdfSmrg * device and configure the server with it. 37535c4bbdfSmrg */ 37635c4bbdfSmrg 37735c4bbdfSmrg if (g_xf86configptr != NULL) 37835c4bbdfSmrg input_list = g_xf86configptr->conf_input_lst; 37935c4bbdfSmrg 38035c4bbdfSmrg while (input_list != NULL) { 38135c4bbdfSmrg if (winNameCompare(input_list->inp_driver, "keyboard") == 0) { 38235c4bbdfSmrg /* Check if device name matches requested name */ 38335c4bbdfSmrg if (g_cmdline.keyboard && winNameCompare(input_list->inp_identifier, 38435c4bbdfSmrg g_cmdline.keyboard)) 38535c4bbdfSmrg continue; 38635c4bbdfSmrg kbd = input_list; 38735c4bbdfSmrg } 38835c4bbdfSmrg input_list = input_list->list.next; 38905b261ecSmrg } 39005b261ecSmrg 39135c4bbdfSmrg if (kbd != NULL) { 39235c4bbdfSmrg 39335c4bbdfSmrg if (kbd->inp_identifier) 39435c4bbdfSmrg winMsg(kbdfrom, "Using keyboard \"%s\" as primary keyboard\n", 39535c4bbdfSmrg kbd->inp_identifier); 39635c4bbdfSmrg 39735c4bbdfSmrg if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL))) { 39835c4bbdfSmrg if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay, 39935c4bbdfSmrg &g_winInfo.keyboard.rate) != 2) || 40035c4bbdfSmrg (g_winInfo.keyboard.delay < 1) || 40135c4bbdfSmrg (g_winInfo.keyboard.rate == 0) || 40235c4bbdfSmrg (1000 / g_winInfo.keyboard.rate) < 1) { 40335c4bbdfSmrg winErrorFVerb(2, "\"%s\" is not a valid AutoRepeat value", s); 40435c4bbdfSmrg free(s); 40535c4bbdfSmrg return FALSE; 40605b261ecSmrg } 40735c4bbdfSmrg free(s); 40835c4bbdfSmrg winMsg(X_CONFIG, "AutoRepeat: %ld %ld\n", 40935c4bbdfSmrg g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); 41005b261ecSmrg } 41105b261ecSmrg#endif 41235c4bbdfSmrg 4136747b715Smrg s = NULL; 41435c4bbdfSmrg if (g_cmdline.xkbRules) { 4156747b715Smrg s = g_cmdline.xkbRules; 4166747b715Smrg from = X_CMDLINE; 41735c4bbdfSmrg } 41805b261ecSmrg#ifdef XWIN_XF86CONFIG 41935c4bbdfSmrg else { 42035c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbRules", NULL); 4216747b715Smrg from = X_CONFIG; 42235c4bbdfSmrg } 42305b261ecSmrg#endif 42435c4bbdfSmrg if (s) { 42535c4bbdfSmrg g_winInfo.xkb.rules = NULL_IF_EMPTY(s); 42635c4bbdfSmrg winMsg(from, "XKB: rules: \"%s\"\n", s); 42735c4bbdfSmrg } 42835c4bbdfSmrg 4296747b715Smrg s = NULL; 43035c4bbdfSmrg if (g_cmdline.xkbModel) { 4316747b715Smrg s = g_cmdline.xkbModel; 4326747b715Smrg from = X_CMDLINE; 43335c4bbdfSmrg } 43405b261ecSmrg#ifdef XWIN_XF86CONFIG 43535c4bbdfSmrg else { 43635c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbModel", NULL); 4376747b715Smrg from = X_CONFIG; 43835c4bbdfSmrg } 43905b261ecSmrg#endif 44035c4bbdfSmrg if (s) { 44135c4bbdfSmrg g_winInfo.xkb.model = NULL_IF_EMPTY(s); 44235c4bbdfSmrg winMsg(from, "XKB: model: \"%s\"\n", s); 44335c4bbdfSmrg } 44405b261ecSmrg 4456747b715Smrg s = NULL; 44635c4bbdfSmrg if (g_cmdline.xkbLayout) { 4476747b715Smrg s = g_cmdline.xkbLayout; 4486747b715Smrg from = X_CMDLINE; 44935c4bbdfSmrg } 45005b261ecSmrg#ifdef XWIN_XF86CONFIG 45135c4bbdfSmrg else { 45235c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbLayout", NULL); 4536747b715Smrg from = X_CONFIG; 45435c4bbdfSmrg } 45505b261ecSmrg#endif 45635c4bbdfSmrg if (s) { 45735c4bbdfSmrg g_winInfo.xkb.layout = NULL_IF_EMPTY(s); 45835c4bbdfSmrg winMsg(from, "XKB: layout: \"%s\"\n", s); 45935c4bbdfSmrg } 46005b261ecSmrg 4616747b715Smrg s = NULL; 46235c4bbdfSmrg if (g_cmdline.xkbVariant) { 4636747b715Smrg s = g_cmdline.xkbVariant; 4646747b715Smrg from = X_CMDLINE; 46535c4bbdfSmrg } 46605b261ecSmrg#ifdef XWIN_XF86CONFIG 46735c4bbdfSmrg else { 46835c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbVariant", NULL); 4696747b715Smrg from = X_CONFIG; 47035c4bbdfSmrg } 47105b261ecSmrg#endif 47235c4bbdfSmrg if (s) { 47335c4bbdfSmrg g_winInfo.xkb.variant = NULL_IF_EMPTY(s); 47435c4bbdfSmrg winMsg(from, "XKB: variant: \"%s\"\n", s); 47535c4bbdfSmrg } 47605b261ecSmrg 4776747b715Smrg s = NULL; 47835c4bbdfSmrg if (g_cmdline.xkbOptions) { 4796747b715Smrg s = g_cmdline.xkbOptions; 4806747b715Smrg from = X_CMDLINE; 48135c4bbdfSmrg } 48205b261ecSmrg#ifdef XWIN_XF86CONFIG 48335c4bbdfSmrg else { 48435c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbOptions", NULL); 4856747b715Smrg from = X_CONFIG; 48635c4bbdfSmrg } 48705b261ecSmrg#endif 48835c4bbdfSmrg if (s) { 48935c4bbdfSmrg g_winInfo.xkb.options = NULL_IF_EMPTY(s); 49035c4bbdfSmrg winMsg(from, "XKB: options: \"%s\"\n", s); 49135c4bbdfSmrg } 49205b261ecSmrg 49305b261ecSmrg#ifdef XWIN_XF86CONFIG 49405b261ecSmrg } 49505b261ecSmrg#endif 49605b261ecSmrg 49735c4bbdfSmrg return TRUE; 49805b261ecSmrg} 49905b261ecSmrg 50005b261ecSmrg#ifdef XWIN_XF86CONFIG 50105b261ecSmrgBool 50235c4bbdfSmrgwinConfigMouse(DeviceIntPtr pDevice) 50305b261ecSmrg{ 50435c4bbdfSmrg MessageType mousefrom = X_CONFIG; 50505b261ecSmrg 50635c4bbdfSmrg XF86ConfInputPtr mouse = NULL; 50735c4bbdfSmrg XF86ConfInputPtr input_list = NULL; 50805b261ecSmrg 50935c4bbdfSmrg if (g_cmdline.mouse) 51035c4bbdfSmrg mousefrom = X_CMDLINE; 51105b261ecSmrg 51235c4bbdfSmrg if (g_xf86configptr != NULL) 51335c4bbdfSmrg input_list = g_xf86configptr->conf_input_lst; 51405b261ecSmrg 51535c4bbdfSmrg while (input_list != NULL) { 51635c4bbdfSmrg if (winNameCompare(input_list->inp_driver, "mouse") == 0) { 51735c4bbdfSmrg /* Check if device name matches requested name */ 51835c4bbdfSmrg if (g_cmdline.mouse && winNameCompare(input_list->inp_identifier, 51935c4bbdfSmrg g_cmdline.mouse)) 52035c4bbdfSmrg continue; 52135c4bbdfSmrg mouse = input_list; 52235c4bbdfSmrg } 52335c4bbdfSmrg input_list = input_list->list.next; 52405b261ecSmrg } 52505b261ecSmrg 52635c4bbdfSmrg if (mouse != NULL) { 52735c4bbdfSmrg if (mouse->inp_identifier) 52835c4bbdfSmrg winMsg(mousefrom, "Using pointer \"%s\" as primary pointer\n", 52935c4bbdfSmrg mouse->inp_identifier); 53035c4bbdfSmrg 53135c4bbdfSmrg g_winInfo.pointer.emulate3Buttons = 53235c4bbdfSmrg winSetBoolOption(mouse->inp_option_lst, "Emulate3Buttons", FALSE); 53335c4bbdfSmrg if (g_cmdline.emulate3buttons) 53435c4bbdfSmrg g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons; 53535c4bbdfSmrg 53635c4bbdfSmrg g_winInfo.pointer.emulate3Timeout = 53735c4bbdfSmrg winSetIntOption(mouse->inp_option_lst, "Emulate3Timeout", 50); 53835c4bbdfSmrg if (g_cmdline.emulate3timeout) 53935c4bbdfSmrg g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout; 54005b261ecSmrg } 54135c4bbdfSmrg else { 54235c4bbdfSmrg winMsg(X_ERROR, "No primary pointer configured\n"); 54335c4bbdfSmrg winMsg(X_DEFAULT, "Using compiletime defaults for pointer\n"); 54405b261ecSmrg } 54505b261ecSmrg 54635c4bbdfSmrg return TRUE; 54705b261ecSmrg} 54805b261ecSmrg 54905b261ecSmrgBool 55035c4bbdfSmrgwinConfigFiles() 55105b261ecSmrg{ 55235c4bbdfSmrg MessageType from; 55335c4bbdfSmrg XF86ConfFilesPtr filesptr = NULL; 55405b261ecSmrg 55535c4bbdfSmrg /* set some shortcuts */ 55635c4bbdfSmrg if (g_xf86configptr != NULL) { 55735c4bbdfSmrg filesptr = g_xf86configptr->conf_files; 55805b261ecSmrg } 55905b261ecSmrg 56035c4bbdfSmrg /* Fontpath */ 56135c4bbdfSmrg from = X_DEFAULT; 56205b261ecSmrg 56335c4bbdfSmrg if (g_cmdline.fontPath) { 56435c4bbdfSmrg from = X_CMDLINE; 56535c4bbdfSmrg defaultFontPath = g_cmdline.fontPath; 56605b261ecSmrg } 56735c4bbdfSmrg else if (filesptr != NULL && filesptr->file_fontpath) { 56835c4bbdfSmrg from = X_CONFIG; 56935c4bbdfSmrg defaultFontPath = strdup(filesptr->file_fontpath); 57005b261ecSmrg } 57135c4bbdfSmrg winMsg(from, "FontPath set to \"%s\"\n", defaultFontPath); 57205b261ecSmrg 57335c4bbdfSmrg return TRUE; 57405b261ecSmrg} 57505b261ecSmrg#else 57605b261ecSmrgBool 57735c4bbdfSmrgwinConfigFiles(void) 57805b261ecSmrg{ 57935c4bbdfSmrg /* Fontpath */ 58035c4bbdfSmrg if (g_cmdline.fontPath) { 58135c4bbdfSmrg defaultFontPath = g_cmdline.fontPath; 58235c4bbdfSmrg winMsg(X_CMDLINE, "FontPath set to \"%s\"\n", defaultFontPath); 58305b261ecSmrg } 58405b261ecSmrg 58535c4bbdfSmrg return TRUE; 58605b261ecSmrg} 58705b261ecSmrg#endif 58805b261ecSmrg 58905b261ecSmrgBool 59035c4bbdfSmrgwinConfigOptions(void) 59105b261ecSmrg{ 59235c4bbdfSmrg return TRUE; 59305b261ecSmrg} 59405b261ecSmrg 59505b261ecSmrgBool 59635c4bbdfSmrgwinConfigScreens(void) 59705b261ecSmrg{ 59835c4bbdfSmrg return TRUE; 59905b261ecSmrg} 60005b261ecSmrg 60105b261ecSmrg#ifdef XWIN_XF86CONFIG 60205b261ecSmrgchar * 60335c4bbdfSmrgwinSetStrOption(void *optlist, const char *name, char *deflt) 60405b261ecSmrg{ 60535c4bbdfSmrg OptionInfoRec o; 60635c4bbdfSmrg 60735c4bbdfSmrg o.name = name; 60835c4bbdfSmrg o.type = OPTV_STRING; 60935c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 61035c4bbdfSmrg deflt = o.value.str; 61135c4bbdfSmrg if (deflt) 61235c4bbdfSmrg return strdup(deflt); 61335c4bbdfSmrg else 61435c4bbdfSmrg return NULL; 61505b261ecSmrg} 61605b261ecSmrg 61705b261ecSmrgint 61835c4bbdfSmrgwinSetBoolOption(void *optlist, const char *name, int deflt) 61905b261ecSmrg{ 62035c4bbdfSmrg OptionInfoRec o; 62105b261ecSmrg 62235c4bbdfSmrg o.name = name; 62335c4bbdfSmrg o.type = OPTV_BOOLEAN; 62435c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 62535c4bbdfSmrg deflt = o.value.bool; 62635c4bbdfSmrg return deflt; 62705b261ecSmrg} 62805b261ecSmrg 62905b261ecSmrgint 63035c4bbdfSmrgwinSetIntOption(void *optlist, const char *name, int deflt) 63105b261ecSmrg{ 63235c4bbdfSmrg OptionInfoRec o; 63305b261ecSmrg 63435c4bbdfSmrg o.name = name; 63535c4bbdfSmrg o.type = OPTV_INTEGER; 63635c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 63735c4bbdfSmrg deflt = o.value.num; 63835c4bbdfSmrg return deflt; 63905b261ecSmrg} 64005b261ecSmrg 64105b261ecSmrgdouble 64235c4bbdfSmrgwinSetRealOption(void *optlist, const char *name, double deflt) 64305b261ecSmrg{ 64435c4bbdfSmrg OptionInfoRec o; 64505b261ecSmrg 64635c4bbdfSmrg o.name = name; 64735c4bbdfSmrg o.type = OPTV_REAL; 64835c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 64935c4bbdfSmrg deflt = o.value.realnum; 65035c4bbdfSmrg return deflt; 65105b261ecSmrg} 6526747b715Smrg 6536747b715Smrgdouble 65435c4bbdfSmrgwinSetPercentOption(void *optlist, const char *name, double deflt) 6556747b715Smrg{ 65635c4bbdfSmrg OptionInfoRec o; 6576747b715Smrg 65835c4bbdfSmrg o.name = name; 65935c4bbdfSmrg o.type = OPTV_PERCENT; 66035c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 66135c4bbdfSmrg deflt = o.value.realnum; 66235c4bbdfSmrg return deflt; 6636747b715Smrg} 66405b261ecSmrg#endif 66505b261ecSmrg 66605b261ecSmrg/* 66705b261ecSmrg * Compare two strings for equality. This is caseinsensitive and 66835c4bbdfSmrg * The characters '_', ' ' (space) and '\t' (tab) are treated as 66905b261ecSmrg * not existing. 67005b261ecSmrg */ 67105b261ecSmrg 67205b261ecSmrgint 67335c4bbdfSmrgwinNameCompare(const char *s1, const char *s2) 67405b261ecSmrg{ 67535c4bbdfSmrg char c1, c2; 67605b261ecSmrg 67735c4bbdfSmrg if (!s1 || *s1 == 0) { 67835c4bbdfSmrg if (!s2 || *s2 == 0) 67935c4bbdfSmrg return 0; 68035c4bbdfSmrg else 68135c4bbdfSmrg return 1; 68205b261ecSmrg } 68305b261ecSmrg 68435c4bbdfSmrg while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') 68535c4bbdfSmrg s1++; 68635c4bbdfSmrg while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') 68735c4bbdfSmrg s2++; 68805b261ecSmrg 68935c4bbdfSmrg c1 = (isupper((int) *s1) ? tolower((int) *s1) : *s1); 69035c4bbdfSmrg c2 = (isupper((int) *s2) ? tolower((int) *s2) : *s2); 69105b261ecSmrg 69235c4bbdfSmrg while (c1 == c2) { 69335c4bbdfSmrg if (c1 == 0) 69435c4bbdfSmrg return 0; 69535c4bbdfSmrg s1++; 69635c4bbdfSmrg s2++; 69735c4bbdfSmrg 69835c4bbdfSmrg while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') 69935c4bbdfSmrg s1++; 70035c4bbdfSmrg while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') 70135c4bbdfSmrg s2++; 70235c4bbdfSmrg 70335c4bbdfSmrg c1 = (isupper((int) *s1) ? tolower((int) *s1) : *s1); 70435c4bbdfSmrg c2 = (isupper((int) *s2) ? tolower((int) *s2) : *s2); 70505b261ecSmrg } 70635c4bbdfSmrg return c1 - c2; 70705b261ecSmrg} 70805b261ecSmrg 70905b261ecSmrg#ifdef XWIN_XF86CONFIG 71005b261ecSmrg/* 71135c4bbdfSmrg * Find the named option in the list. 71205b261ecSmrg * @return the pointer to the option record, or NULL if not found. 71305b261ecSmrg */ 71405b261ecSmrg 71505b261ecSmrgXF86OptionPtr 71635c4bbdfSmrgwinFindOption(XF86OptionPtr list, const char *name) 71705b261ecSmrg{ 71835c4bbdfSmrg while (list) { 71935c4bbdfSmrg if (winNameCompare(list->opt_name, name) == 0) 72035c4bbdfSmrg return list; 72135c4bbdfSmrg list = list->list.next; 72205b261ecSmrg } 72335c4bbdfSmrg return NULL; 72405b261ecSmrg} 72505b261ecSmrg 72605b261ecSmrg/* 72705b261ecSmrg * Find the Value of an named option. 72805b261ecSmrg * @return The option value or NULL if not found. 72905b261ecSmrg */ 73005b261ecSmrg 73105b261ecSmrgchar * 73235c4bbdfSmrgwinFindOptionValue(XF86OptionPtr list, const char *name) 73305b261ecSmrg{ 73435c4bbdfSmrg list = winFindOption(list, name); 73535c4bbdfSmrg if (list) { 73635c4bbdfSmrg if (list->opt_val) 73735c4bbdfSmrg return list->opt_val; 73835c4bbdfSmrg else 73935c4bbdfSmrg return ""; 74005b261ecSmrg } 74135c4bbdfSmrg return NULL; 74205b261ecSmrg} 74305b261ecSmrg 74405b261ecSmrg/* 74505b261ecSmrg * Parse the option. 74605b261ecSmrg */ 74705b261ecSmrg 74805b261ecSmrgstatic Bool 74935c4bbdfSmrgParseOptionValue(int scrnIndex, void *options, OptionInfoPtr p) 75005b261ecSmrg{ 75135c4bbdfSmrg char *s, *end; 75235c4bbdfSmrg 75335c4bbdfSmrg if ((s = winFindOptionValue(options, p->name)) != NULL) { 75435c4bbdfSmrg switch (p->type) { 75535c4bbdfSmrg case OPTV_INTEGER: 75635c4bbdfSmrg if (*s == '\0') { 75735c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 75835c4bbdfSmrg "Option \"%s\" requires an integer value\n", p->name); 75935c4bbdfSmrg p->found = FALSE; 76035c4bbdfSmrg } 76135c4bbdfSmrg else { 76235c4bbdfSmrg p->value.num = strtoul(s, &end, 0); 76335c4bbdfSmrg if (*end == '\0') { 76435c4bbdfSmrg p->found = TRUE; 76535c4bbdfSmrg } 76635c4bbdfSmrg else { 76735c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 76835c4bbdfSmrg "Option \"%s\" requires an integer value\n", 76935c4bbdfSmrg p->name); 77035c4bbdfSmrg p->found = FALSE; 77135c4bbdfSmrg } 77235c4bbdfSmrg } 77335c4bbdfSmrg break; 77435c4bbdfSmrg case OPTV_STRING: 77535c4bbdfSmrg if (*s == '\0') { 77635c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 77735c4bbdfSmrg "Option \"%s\" requires a string value\n", p->name); 77835c4bbdfSmrg p->found = FALSE; 77935c4bbdfSmrg } 78035c4bbdfSmrg else { 78135c4bbdfSmrg p->value.str = s; 78235c4bbdfSmrg p->found = TRUE; 78335c4bbdfSmrg } 78435c4bbdfSmrg break; 78535c4bbdfSmrg case OPTV_ANYSTR: 78635c4bbdfSmrg p->value.str = s; 78735c4bbdfSmrg p->found = TRUE; 78835c4bbdfSmrg break; 78935c4bbdfSmrg case OPTV_REAL: 79035c4bbdfSmrg if (*s == '\0') { 79135c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 79235c4bbdfSmrg "Option \"%s\" requires a floating point value\n", 79335c4bbdfSmrg p->name); 79435c4bbdfSmrg p->found = FALSE; 79535c4bbdfSmrg } 79635c4bbdfSmrg else { 79735c4bbdfSmrg p->value.realnum = strtod(s, &end); 79835c4bbdfSmrg if (*end == '\0') { 79935c4bbdfSmrg p->found = TRUE; 80035c4bbdfSmrg } 80135c4bbdfSmrg else { 80235c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 80335c4bbdfSmrg "Option \"%s\" requires a floating point value\n", 80435c4bbdfSmrg p->name); 80535c4bbdfSmrg p->found = FALSE; 80635c4bbdfSmrg } 80735c4bbdfSmrg } 80835c4bbdfSmrg break; 80935c4bbdfSmrg case OPTV_BOOLEAN: 81035c4bbdfSmrg if (GetBoolValue(p, s)) { 81135c4bbdfSmrg p->found = TRUE; 81235c4bbdfSmrg } 81335c4bbdfSmrg else { 81435c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 81535c4bbdfSmrg "Option \"%s\" requires a boolean value\n", p->name); 81635c4bbdfSmrg p->found = FALSE; 81735c4bbdfSmrg } 81835c4bbdfSmrg break; 81935c4bbdfSmrg case OPTV_PERCENT: 82035c4bbdfSmrg if (*s == '\0') { 82135c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 82235c4bbdfSmrg "Option \"%s\" requires a percent value\n", p->name); 82335c4bbdfSmrg p->found = FALSE; 82435c4bbdfSmrg } 82535c4bbdfSmrg else { 82635c4bbdfSmrg double percent = strtod(s, &end); 82735c4bbdfSmrg 82835c4bbdfSmrg if (end != s && winNameCompare(end, "%")) { 82935c4bbdfSmrg p->found = TRUE; 83035c4bbdfSmrg p->value.realnum = percent; 83135c4bbdfSmrg } 83235c4bbdfSmrg else { 83335c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 83435c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 83535c4bbdfSmrg p->name); 83635c4bbdfSmrg p->found = FALSE; 83735c4bbdfSmrg } 83835c4bbdfSmrg } 83935c4bbdfSmrg case OPTV_FREQ: 84035c4bbdfSmrg if (*s == '\0') { 84135c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 84235c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 84335c4bbdfSmrg p->name); 84435c4bbdfSmrg p->found = FALSE; 84535c4bbdfSmrg } 84635c4bbdfSmrg else { 84735c4bbdfSmrg double freq = strtod(s, &end); 84835c4bbdfSmrg int units = 0; 84935c4bbdfSmrg 85035c4bbdfSmrg if (end != s) { 85135c4bbdfSmrg p->found = TRUE; 85235c4bbdfSmrg if (!winNameCompare(end, "Hz")) 85335c4bbdfSmrg units = 1; 85435c4bbdfSmrg else if (!winNameCompare(end, "kHz") || 85535c4bbdfSmrg !winNameCompare(end, "k")) 85635c4bbdfSmrg units = 1000; 85735c4bbdfSmrg else if (!winNameCompare(end, "MHz") || 85835c4bbdfSmrg !winNameCompare(end, "M")) 85935c4bbdfSmrg units = 1000000; 86035c4bbdfSmrg else { 86135c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 86235c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 86335c4bbdfSmrg p->name); 86435c4bbdfSmrg p->found = FALSE; 86535c4bbdfSmrg } 86635c4bbdfSmrg if (p->found) 86735c4bbdfSmrg freq *= (double) units; 86835c4bbdfSmrg } 86935c4bbdfSmrg else { 87035c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 87135c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 87235c4bbdfSmrg p->name); 87335c4bbdfSmrg p->found = FALSE; 87435c4bbdfSmrg } 87535c4bbdfSmrg if (p->found) { 87635c4bbdfSmrg p->value.freq.freq = freq; 87735c4bbdfSmrg p->value.freq.units = units; 87835c4bbdfSmrg } 87935c4bbdfSmrg } 88035c4bbdfSmrg break; 88135c4bbdfSmrg case OPTV_NONE: 88235c4bbdfSmrg /* Should never get here */ 88335c4bbdfSmrg p->found = FALSE; 88435c4bbdfSmrg break; 88535c4bbdfSmrg } 88635c4bbdfSmrg if (p->found) { 88735c4bbdfSmrg winDrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", p->name); 88835c4bbdfSmrg if (!(p->type == OPTV_BOOLEAN && *s == 0)) { 88935c4bbdfSmrg winErrorFVerb(2, " \"%s\"", s); 89035c4bbdfSmrg } 89135c4bbdfSmrg winErrorFVerb(2, "\n"); 89235c4bbdfSmrg } 89305b261ecSmrg } 89435c4bbdfSmrg else if (p->type == OPTV_BOOLEAN) { 89535c4bbdfSmrg /* Look for matches with options with or without a "No" prefix. */ 89635c4bbdfSmrg char *n, *newn; 89735c4bbdfSmrg OptionInfoRec opt; 89835c4bbdfSmrg 89935c4bbdfSmrg n = winNormalizeName(p->name); 90035c4bbdfSmrg if (!n) { 90135c4bbdfSmrg p->found = FALSE; 90235c4bbdfSmrg return FALSE; 90335c4bbdfSmrg } 90435c4bbdfSmrg if (strncmp(n, "no", 2) == 0) { 90535c4bbdfSmrg newn = n + 2; 90635c4bbdfSmrg } 90735c4bbdfSmrg else { 90835c4bbdfSmrg free(n); 90935c4bbdfSmrg n = malloc(strlen(p->name) + 2 + 1); 91035c4bbdfSmrg if (!n) { 91135c4bbdfSmrg p->found = FALSE; 91235c4bbdfSmrg return FALSE; 91335c4bbdfSmrg } 91435c4bbdfSmrg strcpy(n, "No"); 91535c4bbdfSmrg strcat(n, p->name); 91635c4bbdfSmrg newn = n; 91735c4bbdfSmrg } 91835c4bbdfSmrg if ((s = winFindOptionValue(options, newn)) != NULL) { 91935c4bbdfSmrg if (GetBoolValue(&opt, s)) { 92035c4bbdfSmrg p->value.bool = !opt.value.bool; 92135c4bbdfSmrg p->found = TRUE; 92235c4bbdfSmrg } 92335c4bbdfSmrg else { 92435c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 92535c4bbdfSmrg "Option \"%s\" requires a boolean value\n", newn); 92635c4bbdfSmrg p->found = FALSE; 92735c4bbdfSmrg } 92835c4bbdfSmrg } 92935c4bbdfSmrg else { 93035c4bbdfSmrg p->found = FALSE; 93135c4bbdfSmrg } 93235c4bbdfSmrg if (p->found) { 93335c4bbdfSmrg winDrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); 93435c4bbdfSmrg if (*s != 0) { 93535c4bbdfSmrg winErrorFVerb(2, " \"%s\"", s); 93635c4bbdfSmrg } 93735c4bbdfSmrg winErrorFVerb(2, "\n"); 93835c4bbdfSmrg } 93935c4bbdfSmrg free(n); 94005b261ecSmrg } 94135c4bbdfSmrg else { 94235c4bbdfSmrg p->found = FALSE; 94305b261ecSmrg } 94435c4bbdfSmrg return p->found; 94505b261ecSmrg} 94605b261ecSmrg 94705b261ecSmrgstatic Bool 94835c4bbdfSmrgconfigLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, 94935c4bbdfSmrg char *default_layout) 95005b261ecSmrg{ 95105b261ecSmrg#if 0 95205b261ecSmrg#pragma warn UNIMPLEMENTED 95305b261ecSmrg#endif 95435c4bbdfSmrg return TRUE; 95505b261ecSmrg} 95605b261ecSmrg 95705b261ecSmrgstatic Bool 95835c4bbdfSmrgconfigImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen) 95905b261ecSmrg{ 96005b261ecSmrg#if 0 96105b261ecSmrg#pragma warn UNIMPLEMENTED 96205b261ecSmrg#endif 96335c4bbdfSmrg return TRUE; 96405b261ecSmrg} 96505b261ecSmrg 96605b261ecSmrgstatic Bool 96735c4bbdfSmrgGetBoolValue(OptionInfoPtr p, const char *s) 96805b261ecSmrg{ 96935c4bbdfSmrg if (*s == 0) { 97035c4bbdfSmrg p->value.bool = TRUE; 97105b261ecSmrg } 97235c4bbdfSmrg else { 97335c4bbdfSmrg if (winNameCompare(s, "1") == 0) 97435c4bbdfSmrg p->value.bool = TRUE; 97535c4bbdfSmrg else if (winNameCompare(s, "on") == 0) 97635c4bbdfSmrg p->value.bool = TRUE; 97735c4bbdfSmrg else if (winNameCompare(s, "true") == 0) 97835c4bbdfSmrg p->value.bool = TRUE; 97935c4bbdfSmrg else if (winNameCompare(s, "yes") == 0) 98035c4bbdfSmrg p->value.bool = TRUE; 98135c4bbdfSmrg else if (winNameCompare(s, "0") == 0) 98235c4bbdfSmrg p->value.bool = FALSE; 98335c4bbdfSmrg else if (winNameCompare(s, "off") == 0) 98435c4bbdfSmrg p->value.bool = FALSE; 98535c4bbdfSmrg else if (winNameCompare(s, "false") == 0) 98635c4bbdfSmrg p->value.bool = FALSE; 98735c4bbdfSmrg else if (winNameCompare(s, "no") == 0) 98835c4bbdfSmrg p->value.bool = FALSE; 98905b261ecSmrg } 99035c4bbdfSmrg return TRUE; 99105b261ecSmrg} 99205b261ecSmrg#endif 99305b261ecSmrg 99405b261ecSmrgchar * 99535c4bbdfSmrgwinNormalizeName(const char *s) 99605b261ecSmrg{ 99735c4bbdfSmrg char *ret, *q; 99835c4bbdfSmrg const char *p; 99935c4bbdfSmrg 100035c4bbdfSmrg if (s == NULL) 100135c4bbdfSmrg return NULL; 100235c4bbdfSmrg 100335c4bbdfSmrg ret = malloc(strlen(s) + 1); 100435c4bbdfSmrg for (p = s, q = ret; *p != 0; p++) { 100535c4bbdfSmrg switch (*p) { 100635c4bbdfSmrg case '_': 100735c4bbdfSmrg case ' ': 100835c4bbdfSmrg case '\t': 100935c4bbdfSmrg continue; 101035c4bbdfSmrg default: 101135c4bbdfSmrg if (isupper((int) *p)) 101235c4bbdfSmrg *q++ = tolower((int) *p); 101335c4bbdfSmrg else 101435c4bbdfSmrg *q++ = *p; 101535c4bbdfSmrg } 101605b261ecSmrg } 101735c4bbdfSmrg *q = '\0'; 101835c4bbdfSmrg return ret; 101905b261ecSmrg} 1020