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; 2671b5d61b8Smrg winMsg(X_PROBED, "Setting autorepeat to delay=%ld, rate=%ld\n", 2681b5d61b8Smrg g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); 2691b5d61b8Smrg 27035c4bbdfSmrg } 2719ace9065Smrg } 2729ace9065Smrg 27335c4bbdfSmrg keyboardType = GetKeyboardType(0); 27435c4bbdfSmrg if (keyboardType > 0 && GetKeyboardLayoutName(layoutName)) { 27535c4bbdfSmrg WinKBLayoutPtr pLayout; 27635c4bbdfSmrg Bool bfound = FALSE; 27735c4bbdfSmrg int pass; 27835c4bbdfSmrg 27935c4bbdfSmrg layoutNum = strtoul(layoutName, (char **) NULL, 16); 28035c4bbdfSmrg if ((layoutNum & 0xffff) == 0x411) { 28135c4bbdfSmrg if (keyboardType == 7) { 28235c4bbdfSmrg /* Japanese layouts have problems with key event messages 28335c4bbdfSmrg such as the lack of WM_KEYUP for Caps Lock key. 28435c4bbdfSmrg Loading US layout fixes this problem. */ 28535c4bbdfSmrg if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL) 28635c4bbdfSmrg winMsg(X_INFO, "Loading US keyboard layout.\n"); 28735c4bbdfSmrg else 28835c4bbdfSmrg winMsg(X_ERROR, "LoadKeyboardLayout failed.\n"); 28935c4bbdfSmrg } 29035c4bbdfSmrg } 2919ace9065Smrg 29235c4bbdfSmrg /* Discover the friendly name of the current layout */ 29335c4bbdfSmrg { 29435c4bbdfSmrg HKEY regkey = NULL; 29535c4bbdfSmrg const char regtempl[] = 29635c4bbdfSmrg "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"; 29735c4bbdfSmrg char *regpath; 29835c4bbdfSmrg DWORD namesize = sizeof(layoutFriendlyName); 29935c4bbdfSmrg 30035c4bbdfSmrg regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1); 30135c4bbdfSmrg strcpy(regpath, regtempl); 30235c4bbdfSmrg strcat(regpath, layoutName); 30335c4bbdfSmrg 30435c4bbdfSmrg if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key)) 30535c4bbdfSmrg RegQueryValueEx(regkey, "Layout Text", 0, NULL, 30635c4bbdfSmrg layoutFriendlyName, &namesize); 30735c4bbdfSmrg 30835c4bbdfSmrg /* Close registry key */ 30935c4bbdfSmrg if (regkey) 31035c4bbdfSmrg RegCloseKey(regkey); 31135c4bbdfSmrg free(regpath); 31235c4bbdfSmrg } 3139ace9065Smrg 3149ace9065Smrg winMsg(X_PROBED, 31535c4bbdfSmrg "Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n", 31635c4bbdfSmrg layoutName, layoutNum, layoutFriendlyName, keyboardType); 31735c4bbdfSmrg 31835c4bbdfSmrg deviceIdentifier = layoutNum >> 16; 31935c4bbdfSmrg for (pass = 0; pass < 2; pass++) { 320ed6184dfSmrg /* If we didn't find an exact match for the input locale identifier, 32135c4bbdfSmrg try to find an match on the language identifier part only */ 32235c4bbdfSmrg if (pass == 1) 32335c4bbdfSmrg layoutNum = (layoutNum & 0xffff); 32435c4bbdfSmrg 32535c4bbdfSmrg for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) { 32635c4bbdfSmrg if (pLayout->winlayout != layoutNum) 32735c4bbdfSmrg continue; 32835c4bbdfSmrg if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType) 32935c4bbdfSmrg continue; 33035c4bbdfSmrg 33135c4bbdfSmrg bfound = TRUE; 33235c4bbdfSmrg winMsg(X_PROBED, 33335c4bbdfSmrg "Found matching XKB configuration \"%s\"\n", 33435c4bbdfSmrg pLayout->layoutname); 33535c4bbdfSmrg 33635c4bbdfSmrg winMsg(X_PROBED, 33735c4bbdfSmrg "Model = \"%s\" Layout = \"%s\"" 33835c4bbdfSmrg " Variant = \"%s\" Options = \"%s\"\n", 33935c4bbdfSmrg pLayout->xkbmodel ? pLayout->xkbmodel : "none", 34035c4bbdfSmrg pLayout->xkblayout ? pLayout->xkblayout : "none", 34135c4bbdfSmrg pLayout->xkbvariant ? pLayout->xkbvariant : "none", 34235c4bbdfSmrg pLayout->xkboptions ? pLayout->xkboptions : "none"); 34335c4bbdfSmrg 34435c4bbdfSmrg g_winInfo.xkb.model = pLayout->xkbmodel; 34535c4bbdfSmrg g_winInfo.xkb.layout = pLayout->xkblayout; 34635c4bbdfSmrg g_winInfo.xkb.variant = pLayout->xkbvariant; 34735c4bbdfSmrg g_winInfo.xkb.options = pLayout->xkboptions; 34835c4bbdfSmrg 34935c4bbdfSmrg if (deviceIdentifier == 0xa000) { 35035c4bbdfSmrg winMsg(X_PROBED, "Windows keyboard layout device identifier indicates Macintosh, setting Model = \"macintosh\""); 35135c4bbdfSmrg g_winInfo.xkb.model = "macintosh"; 35235c4bbdfSmrg } 35335c4bbdfSmrg 35435c4bbdfSmrg break; 35535c4bbdfSmrg } 3569ace9065Smrg 35735c4bbdfSmrg if (bfound) 35835c4bbdfSmrg break; 35935c4bbdfSmrg } 3609ace9065Smrg 36135c4bbdfSmrg if (!bfound) { 36235c4bbdfSmrg winMsg(X_ERROR, 36335c4bbdfSmrg "Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n", 36435c4bbdfSmrg layoutFriendlyName, layoutName); 36535c4bbdfSmrg } 36635c4bbdfSmrg } 3679ace9065Smrg 36835c4bbdfSmrg /* parse the configuration */ 36905b261ecSmrg#ifdef XWIN_XF86CONFIG 37035c4bbdfSmrg if (g_cmdline.keyboard) 37135c4bbdfSmrg kbdfrom = X_CMDLINE; 37235c4bbdfSmrg 37335c4bbdfSmrg /* 37435c4bbdfSmrg * Until the layout code is finished, I search for the keyboard 37535c4bbdfSmrg * device and configure the server with it. 37635c4bbdfSmrg */ 37735c4bbdfSmrg 37835c4bbdfSmrg if (g_xf86configptr != NULL) 37935c4bbdfSmrg input_list = g_xf86configptr->conf_input_lst; 38035c4bbdfSmrg 38135c4bbdfSmrg while (input_list != NULL) { 38235c4bbdfSmrg if (winNameCompare(input_list->inp_driver, "keyboard") == 0) { 38335c4bbdfSmrg /* Check if device name matches requested name */ 38435c4bbdfSmrg if (g_cmdline.keyboard && winNameCompare(input_list->inp_identifier, 38535c4bbdfSmrg g_cmdline.keyboard)) 38635c4bbdfSmrg continue; 38735c4bbdfSmrg kbd = input_list; 38835c4bbdfSmrg } 38935c4bbdfSmrg input_list = input_list->list.next; 39005b261ecSmrg } 39105b261ecSmrg 39235c4bbdfSmrg if (kbd != NULL) { 39335c4bbdfSmrg 39435c4bbdfSmrg if (kbd->inp_identifier) 39535c4bbdfSmrg winMsg(kbdfrom, "Using keyboard \"%s\" as primary keyboard\n", 39635c4bbdfSmrg kbd->inp_identifier); 39735c4bbdfSmrg 39835c4bbdfSmrg if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL))) { 39935c4bbdfSmrg if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay, 40035c4bbdfSmrg &g_winInfo.keyboard.rate) != 2) || 40135c4bbdfSmrg (g_winInfo.keyboard.delay < 1) || 40235c4bbdfSmrg (g_winInfo.keyboard.rate == 0) || 40335c4bbdfSmrg (1000 / g_winInfo.keyboard.rate) < 1) { 40435c4bbdfSmrg winErrorFVerb(2, "\"%s\" is not a valid AutoRepeat value", s); 40535c4bbdfSmrg free(s); 40635c4bbdfSmrg return FALSE; 40705b261ecSmrg } 40835c4bbdfSmrg free(s); 40935c4bbdfSmrg winMsg(X_CONFIG, "AutoRepeat: %ld %ld\n", 41035c4bbdfSmrg g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); 41105b261ecSmrg } 41205b261ecSmrg#endif 41335c4bbdfSmrg 4146747b715Smrg s = NULL; 41535c4bbdfSmrg if (g_cmdline.xkbRules) { 4166747b715Smrg s = g_cmdline.xkbRules; 4176747b715Smrg from = X_CMDLINE; 41835c4bbdfSmrg } 41905b261ecSmrg#ifdef XWIN_XF86CONFIG 42035c4bbdfSmrg else { 42135c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbRules", NULL); 4226747b715Smrg from = X_CONFIG; 42335c4bbdfSmrg } 42405b261ecSmrg#endif 42535c4bbdfSmrg if (s) { 42635c4bbdfSmrg g_winInfo.xkb.rules = NULL_IF_EMPTY(s); 42735c4bbdfSmrg winMsg(from, "XKB: rules: \"%s\"\n", s); 42835c4bbdfSmrg } 42935c4bbdfSmrg 4306747b715Smrg s = NULL; 43135c4bbdfSmrg if (g_cmdline.xkbModel) { 4326747b715Smrg s = g_cmdline.xkbModel; 4336747b715Smrg from = X_CMDLINE; 43435c4bbdfSmrg } 43505b261ecSmrg#ifdef XWIN_XF86CONFIG 43635c4bbdfSmrg else { 43735c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbModel", NULL); 4386747b715Smrg from = X_CONFIG; 43935c4bbdfSmrg } 44005b261ecSmrg#endif 44135c4bbdfSmrg if (s) { 44235c4bbdfSmrg g_winInfo.xkb.model = NULL_IF_EMPTY(s); 44335c4bbdfSmrg winMsg(from, "XKB: model: \"%s\"\n", s); 44435c4bbdfSmrg } 44505b261ecSmrg 4466747b715Smrg s = NULL; 44735c4bbdfSmrg if (g_cmdline.xkbLayout) { 4486747b715Smrg s = g_cmdline.xkbLayout; 4496747b715Smrg from = X_CMDLINE; 45035c4bbdfSmrg } 45105b261ecSmrg#ifdef XWIN_XF86CONFIG 45235c4bbdfSmrg else { 45335c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbLayout", NULL); 4546747b715Smrg from = X_CONFIG; 45535c4bbdfSmrg } 45605b261ecSmrg#endif 45735c4bbdfSmrg if (s) { 45835c4bbdfSmrg g_winInfo.xkb.layout = NULL_IF_EMPTY(s); 45935c4bbdfSmrg winMsg(from, "XKB: layout: \"%s\"\n", s); 46035c4bbdfSmrg } 46105b261ecSmrg 4626747b715Smrg s = NULL; 46335c4bbdfSmrg if (g_cmdline.xkbVariant) { 4646747b715Smrg s = g_cmdline.xkbVariant; 4656747b715Smrg from = X_CMDLINE; 46635c4bbdfSmrg } 46705b261ecSmrg#ifdef XWIN_XF86CONFIG 46835c4bbdfSmrg else { 46935c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbVariant", NULL); 4706747b715Smrg from = X_CONFIG; 47135c4bbdfSmrg } 47205b261ecSmrg#endif 47335c4bbdfSmrg if (s) { 47435c4bbdfSmrg g_winInfo.xkb.variant = NULL_IF_EMPTY(s); 47535c4bbdfSmrg winMsg(from, "XKB: variant: \"%s\"\n", s); 47635c4bbdfSmrg } 47705b261ecSmrg 4786747b715Smrg s = NULL; 47935c4bbdfSmrg if (g_cmdline.xkbOptions) { 4806747b715Smrg s = g_cmdline.xkbOptions; 4816747b715Smrg from = X_CMDLINE; 48235c4bbdfSmrg } 48305b261ecSmrg#ifdef XWIN_XF86CONFIG 48435c4bbdfSmrg else { 48535c4bbdfSmrg s = winSetStrOption(kbd->inp_option_lst, "XkbOptions", NULL); 4866747b715Smrg from = X_CONFIG; 48735c4bbdfSmrg } 48805b261ecSmrg#endif 48935c4bbdfSmrg if (s) { 49035c4bbdfSmrg g_winInfo.xkb.options = NULL_IF_EMPTY(s); 49135c4bbdfSmrg winMsg(from, "XKB: options: \"%s\"\n", s); 49235c4bbdfSmrg } 49305b261ecSmrg 49405b261ecSmrg#ifdef XWIN_XF86CONFIG 49505b261ecSmrg } 49605b261ecSmrg#endif 49705b261ecSmrg 49835c4bbdfSmrg return TRUE; 49905b261ecSmrg} 50005b261ecSmrg 50105b261ecSmrg#ifdef XWIN_XF86CONFIG 50205b261ecSmrgBool 50335c4bbdfSmrgwinConfigMouse(DeviceIntPtr pDevice) 50405b261ecSmrg{ 50535c4bbdfSmrg MessageType mousefrom = X_CONFIG; 50605b261ecSmrg 50735c4bbdfSmrg XF86ConfInputPtr mouse = NULL; 50835c4bbdfSmrg XF86ConfInputPtr input_list = NULL; 50905b261ecSmrg 51035c4bbdfSmrg if (g_cmdline.mouse) 51135c4bbdfSmrg mousefrom = X_CMDLINE; 51205b261ecSmrg 51335c4bbdfSmrg if (g_xf86configptr != NULL) 51435c4bbdfSmrg input_list = g_xf86configptr->conf_input_lst; 51505b261ecSmrg 51635c4bbdfSmrg while (input_list != NULL) { 51735c4bbdfSmrg if (winNameCompare(input_list->inp_driver, "mouse") == 0) { 51835c4bbdfSmrg /* Check if device name matches requested name */ 51935c4bbdfSmrg if (g_cmdline.mouse && winNameCompare(input_list->inp_identifier, 52035c4bbdfSmrg g_cmdline.mouse)) 52135c4bbdfSmrg continue; 52235c4bbdfSmrg mouse = input_list; 52335c4bbdfSmrg } 52435c4bbdfSmrg input_list = input_list->list.next; 52505b261ecSmrg } 52605b261ecSmrg 52735c4bbdfSmrg if (mouse != NULL) { 52835c4bbdfSmrg if (mouse->inp_identifier) 52935c4bbdfSmrg winMsg(mousefrom, "Using pointer \"%s\" as primary pointer\n", 53035c4bbdfSmrg mouse->inp_identifier); 53135c4bbdfSmrg 53235c4bbdfSmrg g_winInfo.pointer.emulate3Buttons = 53335c4bbdfSmrg winSetBoolOption(mouse->inp_option_lst, "Emulate3Buttons", FALSE); 53435c4bbdfSmrg if (g_cmdline.emulate3buttons) 53535c4bbdfSmrg g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons; 53635c4bbdfSmrg 53735c4bbdfSmrg g_winInfo.pointer.emulate3Timeout = 53835c4bbdfSmrg winSetIntOption(mouse->inp_option_lst, "Emulate3Timeout", 50); 53935c4bbdfSmrg if (g_cmdline.emulate3timeout) 54035c4bbdfSmrg g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout; 54105b261ecSmrg } 54235c4bbdfSmrg else { 54335c4bbdfSmrg winMsg(X_ERROR, "No primary pointer configured\n"); 54435c4bbdfSmrg winMsg(X_DEFAULT, "Using compiletime defaults for pointer\n"); 54505b261ecSmrg } 54605b261ecSmrg 54735c4bbdfSmrg return TRUE; 54805b261ecSmrg} 54905b261ecSmrg 55005b261ecSmrgBool 55135c4bbdfSmrgwinConfigFiles() 55205b261ecSmrg{ 55335c4bbdfSmrg MessageType from; 55435c4bbdfSmrg XF86ConfFilesPtr filesptr = NULL; 55505b261ecSmrg 55635c4bbdfSmrg /* set some shortcuts */ 55735c4bbdfSmrg if (g_xf86configptr != NULL) { 55835c4bbdfSmrg filesptr = g_xf86configptr->conf_files; 55905b261ecSmrg } 56005b261ecSmrg 56135c4bbdfSmrg /* Fontpath */ 56235c4bbdfSmrg from = X_DEFAULT; 56305b261ecSmrg 56435c4bbdfSmrg if (g_cmdline.fontPath) { 56535c4bbdfSmrg from = X_CMDLINE; 56635c4bbdfSmrg defaultFontPath = g_cmdline.fontPath; 56705b261ecSmrg } 56835c4bbdfSmrg else if (filesptr != NULL && filesptr->file_fontpath) { 56935c4bbdfSmrg from = X_CONFIG; 57035c4bbdfSmrg defaultFontPath = strdup(filesptr->file_fontpath); 57105b261ecSmrg } 57235c4bbdfSmrg winMsg(from, "FontPath set to \"%s\"\n", defaultFontPath); 57305b261ecSmrg 57435c4bbdfSmrg return TRUE; 57505b261ecSmrg} 57605b261ecSmrg#else 57705b261ecSmrgBool 57835c4bbdfSmrgwinConfigFiles(void) 57905b261ecSmrg{ 58035c4bbdfSmrg /* Fontpath */ 58135c4bbdfSmrg if (g_cmdline.fontPath) { 58235c4bbdfSmrg defaultFontPath = g_cmdline.fontPath; 58335c4bbdfSmrg winMsg(X_CMDLINE, "FontPath set to \"%s\"\n", defaultFontPath); 58405b261ecSmrg } 58505b261ecSmrg 58635c4bbdfSmrg return TRUE; 58705b261ecSmrg} 58805b261ecSmrg#endif 58905b261ecSmrg 59005b261ecSmrgBool 59135c4bbdfSmrgwinConfigOptions(void) 59205b261ecSmrg{ 59335c4bbdfSmrg return TRUE; 59405b261ecSmrg} 59505b261ecSmrg 59605b261ecSmrgBool 59735c4bbdfSmrgwinConfigScreens(void) 59805b261ecSmrg{ 59935c4bbdfSmrg return TRUE; 60005b261ecSmrg} 60105b261ecSmrg 60205b261ecSmrg#ifdef XWIN_XF86CONFIG 60305b261ecSmrgchar * 60435c4bbdfSmrgwinSetStrOption(void *optlist, const char *name, char *deflt) 60505b261ecSmrg{ 60635c4bbdfSmrg OptionInfoRec o; 60735c4bbdfSmrg 60835c4bbdfSmrg o.name = name; 60935c4bbdfSmrg o.type = OPTV_STRING; 61035c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 61135c4bbdfSmrg deflt = o.value.str; 61235c4bbdfSmrg if (deflt) 61335c4bbdfSmrg return strdup(deflt); 61435c4bbdfSmrg else 61535c4bbdfSmrg return NULL; 61605b261ecSmrg} 61705b261ecSmrg 61805b261ecSmrgint 61935c4bbdfSmrgwinSetBoolOption(void *optlist, const char *name, int deflt) 62005b261ecSmrg{ 62135c4bbdfSmrg OptionInfoRec o; 62205b261ecSmrg 62335c4bbdfSmrg o.name = name; 62435c4bbdfSmrg o.type = OPTV_BOOLEAN; 62535c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 626ed6184dfSmrg deflt = o.value.boolean; 62735c4bbdfSmrg return deflt; 62805b261ecSmrg} 62905b261ecSmrg 63005b261ecSmrgint 63135c4bbdfSmrgwinSetIntOption(void *optlist, const char *name, int deflt) 63205b261ecSmrg{ 63335c4bbdfSmrg OptionInfoRec o; 63405b261ecSmrg 63535c4bbdfSmrg o.name = name; 63635c4bbdfSmrg o.type = OPTV_INTEGER; 63735c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 63835c4bbdfSmrg deflt = o.value.num; 63935c4bbdfSmrg return deflt; 64005b261ecSmrg} 64105b261ecSmrg 64205b261ecSmrgdouble 64335c4bbdfSmrgwinSetRealOption(void *optlist, const char *name, double deflt) 64405b261ecSmrg{ 64535c4bbdfSmrg OptionInfoRec o; 64605b261ecSmrg 64735c4bbdfSmrg o.name = name; 64835c4bbdfSmrg o.type = OPTV_REAL; 64935c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 65035c4bbdfSmrg deflt = o.value.realnum; 65135c4bbdfSmrg return deflt; 65205b261ecSmrg} 6536747b715Smrg 6546747b715Smrgdouble 65535c4bbdfSmrgwinSetPercentOption(void *optlist, const char *name, double deflt) 6566747b715Smrg{ 65735c4bbdfSmrg OptionInfoRec o; 6586747b715Smrg 65935c4bbdfSmrg o.name = name; 66035c4bbdfSmrg o.type = OPTV_PERCENT; 66135c4bbdfSmrg if (ParseOptionValue(-1, optlist, &o)) 66235c4bbdfSmrg deflt = o.value.realnum; 66335c4bbdfSmrg return deflt; 6646747b715Smrg} 66505b261ecSmrg#endif 66605b261ecSmrg 66705b261ecSmrg/* 66805b261ecSmrg * Compare two strings for equality. This is caseinsensitive and 66935c4bbdfSmrg * The characters '_', ' ' (space) and '\t' (tab) are treated as 67005b261ecSmrg * not existing. 67105b261ecSmrg */ 67205b261ecSmrg 67305b261ecSmrgint 67435c4bbdfSmrgwinNameCompare(const char *s1, const char *s2) 67505b261ecSmrg{ 67635c4bbdfSmrg char c1, c2; 67705b261ecSmrg 67835c4bbdfSmrg if (!s1 || *s1 == 0) { 67935c4bbdfSmrg if (!s2 || *s2 == 0) 68035c4bbdfSmrg return 0; 68135c4bbdfSmrg else 68235c4bbdfSmrg return 1; 68305b261ecSmrg } 68405b261ecSmrg 68535c4bbdfSmrg while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') 68635c4bbdfSmrg s1++; 68735c4bbdfSmrg while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') 68835c4bbdfSmrg s2++; 68905b261ecSmrg 69035c4bbdfSmrg c1 = (isupper((int) *s1) ? tolower((int) *s1) : *s1); 69135c4bbdfSmrg c2 = (isupper((int) *s2) ? tolower((int) *s2) : *s2); 69205b261ecSmrg 69335c4bbdfSmrg while (c1 == c2) { 69435c4bbdfSmrg if (c1 == 0) 69535c4bbdfSmrg return 0; 69635c4bbdfSmrg s1++; 69735c4bbdfSmrg s2++; 69835c4bbdfSmrg 69935c4bbdfSmrg while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') 70035c4bbdfSmrg s1++; 70135c4bbdfSmrg while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') 70235c4bbdfSmrg s2++; 70335c4bbdfSmrg 70435c4bbdfSmrg c1 = (isupper((int) *s1) ? tolower((int) *s1) : *s1); 70535c4bbdfSmrg c2 = (isupper((int) *s2) ? tolower((int) *s2) : *s2); 70605b261ecSmrg } 70735c4bbdfSmrg return c1 - c2; 70805b261ecSmrg} 70905b261ecSmrg 71005b261ecSmrg#ifdef XWIN_XF86CONFIG 71105b261ecSmrg/* 71235c4bbdfSmrg * Find the named option in the list. 71305b261ecSmrg * @return the pointer to the option record, or NULL if not found. 71405b261ecSmrg */ 71505b261ecSmrg 71605b261ecSmrgXF86OptionPtr 71735c4bbdfSmrgwinFindOption(XF86OptionPtr list, const char *name) 71805b261ecSmrg{ 71935c4bbdfSmrg while (list) { 72035c4bbdfSmrg if (winNameCompare(list->opt_name, name) == 0) 72135c4bbdfSmrg return list; 72235c4bbdfSmrg list = list->list.next; 72305b261ecSmrg } 72435c4bbdfSmrg return NULL; 72505b261ecSmrg} 72605b261ecSmrg 72705b261ecSmrg/* 72805b261ecSmrg * Find the Value of an named option. 72905b261ecSmrg * @return The option value or NULL if not found. 73005b261ecSmrg */ 73105b261ecSmrg 73205b261ecSmrgchar * 73335c4bbdfSmrgwinFindOptionValue(XF86OptionPtr list, const char *name) 73405b261ecSmrg{ 73535c4bbdfSmrg list = winFindOption(list, name); 73635c4bbdfSmrg if (list) { 73735c4bbdfSmrg if (list->opt_val) 73835c4bbdfSmrg return list->opt_val; 73935c4bbdfSmrg else 74035c4bbdfSmrg return ""; 74105b261ecSmrg } 74235c4bbdfSmrg return NULL; 74305b261ecSmrg} 74405b261ecSmrg 74505b261ecSmrg/* 74605b261ecSmrg * Parse the option. 74705b261ecSmrg */ 74805b261ecSmrg 74905b261ecSmrgstatic Bool 75035c4bbdfSmrgParseOptionValue(int scrnIndex, void *options, OptionInfoPtr p) 75105b261ecSmrg{ 75235c4bbdfSmrg char *s, *end; 75335c4bbdfSmrg 75435c4bbdfSmrg if ((s = winFindOptionValue(options, p->name)) != NULL) { 75535c4bbdfSmrg switch (p->type) { 75635c4bbdfSmrg case OPTV_INTEGER: 75735c4bbdfSmrg if (*s == '\0') { 75835c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 75935c4bbdfSmrg "Option \"%s\" requires an integer value\n", p->name); 76035c4bbdfSmrg p->found = FALSE; 76135c4bbdfSmrg } 76235c4bbdfSmrg else { 76335c4bbdfSmrg p->value.num = strtoul(s, &end, 0); 76435c4bbdfSmrg if (*end == '\0') { 76535c4bbdfSmrg p->found = TRUE; 76635c4bbdfSmrg } 76735c4bbdfSmrg else { 76835c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 76935c4bbdfSmrg "Option \"%s\" requires an integer value\n", 77035c4bbdfSmrg p->name); 77135c4bbdfSmrg p->found = FALSE; 77235c4bbdfSmrg } 77335c4bbdfSmrg } 77435c4bbdfSmrg break; 77535c4bbdfSmrg case OPTV_STRING: 77635c4bbdfSmrg if (*s == '\0') { 77735c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 77835c4bbdfSmrg "Option \"%s\" requires a string value\n", p->name); 77935c4bbdfSmrg p->found = FALSE; 78035c4bbdfSmrg } 78135c4bbdfSmrg else { 78235c4bbdfSmrg p->value.str = s; 78335c4bbdfSmrg p->found = TRUE; 78435c4bbdfSmrg } 78535c4bbdfSmrg break; 78635c4bbdfSmrg case OPTV_ANYSTR: 78735c4bbdfSmrg p->value.str = s; 78835c4bbdfSmrg p->found = TRUE; 78935c4bbdfSmrg break; 79035c4bbdfSmrg case OPTV_REAL: 79135c4bbdfSmrg if (*s == '\0') { 79235c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 79335c4bbdfSmrg "Option \"%s\" requires a floating point value\n", 79435c4bbdfSmrg p->name); 79535c4bbdfSmrg p->found = FALSE; 79635c4bbdfSmrg } 79735c4bbdfSmrg else { 79835c4bbdfSmrg p->value.realnum = strtod(s, &end); 79935c4bbdfSmrg if (*end == '\0') { 80035c4bbdfSmrg p->found = TRUE; 80135c4bbdfSmrg } 80235c4bbdfSmrg else { 80335c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 80435c4bbdfSmrg "Option \"%s\" requires a floating point value\n", 80535c4bbdfSmrg p->name); 80635c4bbdfSmrg p->found = FALSE; 80735c4bbdfSmrg } 80835c4bbdfSmrg } 80935c4bbdfSmrg break; 81035c4bbdfSmrg case OPTV_BOOLEAN: 81135c4bbdfSmrg if (GetBoolValue(p, s)) { 81235c4bbdfSmrg p->found = TRUE; 81335c4bbdfSmrg } 81435c4bbdfSmrg else { 81535c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 81635c4bbdfSmrg "Option \"%s\" requires a boolean value\n", p->name); 81735c4bbdfSmrg p->found = FALSE; 81835c4bbdfSmrg } 81935c4bbdfSmrg break; 82035c4bbdfSmrg case OPTV_PERCENT: 82135c4bbdfSmrg if (*s == '\0') { 82235c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 82335c4bbdfSmrg "Option \"%s\" requires a percent value\n", p->name); 82435c4bbdfSmrg p->found = FALSE; 82535c4bbdfSmrg } 82635c4bbdfSmrg else { 82735c4bbdfSmrg double percent = strtod(s, &end); 82835c4bbdfSmrg 82935c4bbdfSmrg if (end != s && winNameCompare(end, "%")) { 83035c4bbdfSmrg p->found = TRUE; 83135c4bbdfSmrg p->value.realnum = percent; 83235c4bbdfSmrg } 83335c4bbdfSmrg else { 83435c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 83535c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 83635c4bbdfSmrg p->name); 83735c4bbdfSmrg p->found = FALSE; 83835c4bbdfSmrg } 83935c4bbdfSmrg } 84035c4bbdfSmrg case OPTV_FREQ: 84135c4bbdfSmrg if (*s == '\0') { 84235c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 84335c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 84435c4bbdfSmrg p->name); 84535c4bbdfSmrg p->found = FALSE; 84635c4bbdfSmrg } 84735c4bbdfSmrg else { 84835c4bbdfSmrg double freq = strtod(s, &end); 84935c4bbdfSmrg int units = 0; 85035c4bbdfSmrg 85135c4bbdfSmrg if (end != s) { 85235c4bbdfSmrg p->found = TRUE; 85335c4bbdfSmrg if (!winNameCompare(end, "Hz")) 85435c4bbdfSmrg units = 1; 85535c4bbdfSmrg else if (!winNameCompare(end, "kHz") || 85635c4bbdfSmrg !winNameCompare(end, "k")) 85735c4bbdfSmrg units = 1000; 85835c4bbdfSmrg else if (!winNameCompare(end, "MHz") || 85935c4bbdfSmrg !winNameCompare(end, "M")) 86035c4bbdfSmrg units = 1000000; 86135c4bbdfSmrg else { 86235c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 86335c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 86435c4bbdfSmrg p->name); 86535c4bbdfSmrg p->found = FALSE; 86635c4bbdfSmrg } 86735c4bbdfSmrg if (p->found) 86835c4bbdfSmrg freq *= (double) units; 86935c4bbdfSmrg } 87035c4bbdfSmrg else { 87135c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 87235c4bbdfSmrg "Option \"%s\" requires a frequency value\n", 87335c4bbdfSmrg p->name); 87435c4bbdfSmrg p->found = FALSE; 87535c4bbdfSmrg } 87635c4bbdfSmrg if (p->found) { 87735c4bbdfSmrg p->value.freq.freq = freq; 87835c4bbdfSmrg p->value.freq.units = units; 87935c4bbdfSmrg } 88035c4bbdfSmrg } 88135c4bbdfSmrg break; 88235c4bbdfSmrg case OPTV_NONE: 88335c4bbdfSmrg /* Should never get here */ 88435c4bbdfSmrg p->found = FALSE; 88535c4bbdfSmrg break; 88635c4bbdfSmrg } 88735c4bbdfSmrg if (p->found) { 88835c4bbdfSmrg winDrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", p->name); 88935c4bbdfSmrg if (!(p->type == OPTV_BOOLEAN && *s == 0)) { 89035c4bbdfSmrg winErrorFVerb(2, " \"%s\"", s); 89135c4bbdfSmrg } 89235c4bbdfSmrg winErrorFVerb(2, "\n"); 89335c4bbdfSmrg } 89405b261ecSmrg } 89535c4bbdfSmrg else if (p->type == OPTV_BOOLEAN) { 89635c4bbdfSmrg /* Look for matches with options with or without a "No" prefix. */ 89735c4bbdfSmrg char *n, *newn; 89835c4bbdfSmrg OptionInfoRec opt; 89935c4bbdfSmrg 90035c4bbdfSmrg n = winNormalizeName(p->name); 90135c4bbdfSmrg if (!n) { 90235c4bbdfSmrg p->found = FALSE; 90335c4bbdfSmrg return FALSE; 90435c4bbdfSmrg } 90535c4bbdfSmrg if (strncmp(n, "no", 2) == 0) { 90635c4bbdfSmrg newn = n + 2; 90735c4bbdfSmrg } 90835c4bbdfSmrg else { 90935c4bbdfSmrg free(n); 91035c4bbdfSmrg n = malloc(strlen(p->name) + 2 + 1); 91135c4bbdfSmrg if (!n) { 91235c4bbdfSmrg p->found = FALSE; 91335c4bbdfSmrg return FALSE; 91435c4bbdfSmrg } 91535c4bbdfSmrg strcpy(n, "No"); 91635c4bbdfSmrg strcat(n, p->name); 91735c4bbdfSmrg newn = n; 91835c4bbdfSmrg } 91935c4bbdfSmrg if ((s = winFindOptionValue(options, newn)) != NULL) { 92035c4bbdfSmrg if (GetBoolValue(&opt, s)) { 921ed6184dfSmrg p->value.boolean = !opt.value.boolean; 92235c4bbdfSmrg p->found = TRUE; 92335c4bbdfSmrg } 92435c4bbdfSmrg else { 92535c4bbdfSmrg winDrvMsg(scrnIndex, X_WARNING, 92635c4bbdfSmrg "Option \"%s\" requires a boolean value\n", newn); 92735c4bbdfSmrg p->found = FALSE; 92835c4bbdfSmrg } 92935c4bbdfSmrg } 93035c4bbdfSmrg else { 93135c4bbdfSmrg p->found = FALSE; 93235c4bbdfSmrg } 93335c4bbdfSmrg if (p->found) { 93435c4bbdfSmrg winDrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); 93535c4bbdfSmrg if (*s != 0) { 93635c4bbdfSmrg winErrorFVerb(2, " \"%s\"", s); 93735c4bbdfSmrg } 93835c4bbdfSmrg winErrorFVerb(2, "\n"); 93935c4bbdfSmrg } 94035c4bbdfSmrg free(n); 94105b261ecSmrg } 94235c4bbdfSmrg else { 94335c4bbdfSmrg p->found = FALSE; 94405b261ecSmrg } 94535c4bbdfSmrg return p->found; 94605b261ecSmrg} 94705b261ecSmrg 94805b261ecSmrgstatic Bool 94935c4bbdfSmrgconfigLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, 95035c4bbdfSmrg char *default_layout) 95105b261ecSmrg{ 95205b261ecSmrg#if 0 95305b261ecSmrg#pragma warn UNIMPLEMENTED 95405b261ecSmrg#endif 95535c4bbdfSmrg return TRUE; 95605b261ecSmrg} 95705b261ecSmrg 95805b261ecSmrgstatic Bool 95935c4bbdfSmrgconfigImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen) 96005b261ecSmrg{ 96105b261ecSmrg#if 0 96205b261ecSmrg#pragma warn UNIMPLEMENTED 96305b261ecSmrg#endif 96435c4bbdfSmrg return TRUE; 96505b261ecSmrg} 96605b261ecSmrg 96705b261ecSmrgstatic Bool 96835c4bbdfSmrgGetBoolValue(OptionInfoPtr p, const char *s) 96905b261ecSmrg{ 97035c4bbdfSmrg if (*s == 0) { 971ed6184dfSmrg p->value.boolean = TRUE; 97205b261ecSmrg } 97335c4bbdfSmrg else { 97435c4bbdfSmrg if (winNameCompare(s, "1") == 0) 975ed6184dfSmrg p->value.boolean = TRUE; 97635c4bbdfSmrg else if (winNameCompare(s, "on") == 0) 977ed6184dfSmrg p->value.boolean = TRUE; 97835c4bbdfSmrg else if (winNameCompare(s, "true") == 0) 979ed6184dfSmrg p->value.boolean = TRUE; 98035c4bbdfSmrg else if (winNameCompare(s, "yes") == 0) 981ed6184dfSmrg p->value.boolean = TRUE; 98235c4bbdfSmrg else if (winNameCompare(s, "0") == 0) 983ed6184dfSmrg p->value.boolean = FALSE; 98435c4bbdfSmrg else if (winNameCompare(s, "off") == 0) 985ed6184dfSmrg p->value.boolean = FALSE; 98635c4bbdfSmrg else if (winNameCompare(s, "false") == 0) 987ed6184dfSmrg p->value.boolean = FALSE; 98835c4bbdfSmrg else if (winNameCompare(s, "no") == 0) 989ed6184dfSmrg p->value.boolean = FALSE; 99005b261ecSmrg } 99135c4bbdfSmrg return TRUE; 99205b261ecSmrg} 99305b261ecSmrg#endif 99405b261ecSmrg 99505b261ecSmrgchar * 99635c4bbdfSmrgwinNormalizeName(const char *s) 99705b261ecSmrg{ 99835c4bbdfSmrg char *ret, *q; 99935c4bbdfSmrg const char *p; 100035c4bbdfSmrg 100135c4bbdfSmrg if (s == NULL) 100235c4bbdfSmrg return NULL; 100335c4bbdfSmrg 100435c4bbdfSmrg ret = malloc(strlen(s) + 1); 100535c4bbdfSmrg for (p = s, q = ret; *p != 0; p++) { 100635c4bbdfSmrg switch (*p) { 100735c4bbdfSmrg case '_': 100835c4bbdfSmrg case ' ': 100935c4bbdfSmrg case '\t': 101035c4bbdfSmrg continue; 101135c4bbdfSmrg default: 101235c4bbdfSmrg if (isupper((int) *p)) 101335c4bbdfSmrg *q++ = tolower((int) *p); 101435c4bbdfSmrg else 101535c4bbdfSmrg *q++ = *p; 101635c4bbdfSmrg } 101705b261ecSmrg } 101835c4bbdfSmrg *q = '\0'; 101935c4bbdfSmrg return ret; 102005b261ecSmrg} 1021