winconfig.c revision 6747b715
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
6605b261ecSmrg  NULL,				/* configFile */
676747b715Smrg  NULL,				/* configDir */
6805b261ecSmrg#endif
6905b261ecSmrg  NULL,				/* fontPath */
7005b261ecSmrg#ifdef XWIN_XF86CONFIG
7105b261ecSmrg  NULL,				/* keyboard */
7205b261ecSmrg#endif
7305b261ecSmrg  NULL,             /* xkbRules */
7405b261ecSmrg  NULL,             /* xkbModel */
7505b261ecSmrg  NULL,             /* xkbLayout */
7605b261ecSmrg  NULL,             /* xkbVariant */
7705b261ecSmrg  NULL,             /* xkbOptions */
7805b261ecSmrg  NULL,				/* screenname */
7905b261ecSmrg  NULL,				/* mousename */
8005b261ecSmrg  FALSE,			/* emulate3Buttons */
8105b261ecSmrg  0				/* emulate3Timeout */
8205b261ecSmrg};
8305b261ecSmrg
8405b261ecSmrgwinInfoRec g_winInfo = {
8505b261ecSmrg  {				/* keyboard */
8605b261ecSmrg   0,				/* leds */
8705b261ecSmrg   500,				/* delay */
8805b261ecSmrg   30				/* rate */
8905b261ecSmrg   }
9005b261ecSmrg  ,
9105b261ecSmrg  {				/* xkb */
9205b261ecSmrg   NULL,			/* rules */
9305b261ecSmrg   NULL,			/* model */
9405b261ecSmrg   NULL,			/* layout */
9505b261ecSmrg   NULL,			/* variant */
9605b261ecSmrg   NULL,			/* options */
9705b261ecSmrg   }
9805b261ecSmrg  ,
9905b261ecSmrg  {
10005b261ecSmrg   FALSE,
10105b261ecSmrg   50}
10205b261ecSmrg};
10305b261ecSmrg
10405b261ecSmrg#define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL)
10505b261ecSmrg
10605b261ecSmrg#ifdef XWIN_XF86CONFIG
10705b261ecSmrgserverLayoutRec g_winConfigLayout;
10805b261ecSmrg
10905b261ecSmrgstatic Bool ParseOptionValue (int scrnIndex, pointer options,
11005b261ecSmrg			      OptionInfoPtr p);
11105b261ecSmrgstatic Bool configLayout (serverLayoutPtr, XF86ConfLayoutPtr, char *);
11205b261ecSmrgstatic Bool configImpliedLayout (serverLayoutPtr, XF86ConfScreenPtr);
11305b261ecSmrgstatic Bool GetBoolValue (OptionInfoPtr p, const char *s);
11405b261ecSmrg
11505b261ecSmrg
11605b261ecSmrgBool
11705b261ecSmrgwinReadConfigfile ()
11805b261ecSmrg{
11905b261ecSmrg  Bool		retval = TRUE;
1206747b715Smrg  const char	*filename, *dirname;
1216747b715Smrg  MessageType	filefrom = X_DEFAULT;
1226747b715Smrg  MessageType	dirfrom = X_DEFAULT;
12305b261ecSmrg  char		*xf86ConfigFile = NULL;
1246747b715Smrg  char		*xf86ConfigDir = NULL;
12505b261ecSmrg
12605b261ecSmrg  if (g_cmdline.configFile)
12705b261ecSmrg    {
1286747b715Smrg      filefrom = X_CMDLINE;
12905b261ecSmrg      xf86ConfigFile = g_cmdline.configFile;
13005b261ecSmrg    }
1316747b715Smrg  if (g_cmdline.configDir)
1326747b715Smrg    {
1336747b715Smrg      dirfrom = X_CMDLINE;
1346747b715Smrg      xf86ConfigDir = g_cmdline.configDir;
1356747b715Smrg    }
13605b261ecSmrg
13705b261ecSmrg  /* Parse config file into data structure */
1386747b715Smrg  xf86initConfigFiles();
1396747b715Smrg  dirname = xf86openConfigDirFiles (CONFIGDIRPATH, xf86ConfigDir, PROJECTROOT);
14005b261ecSmrg  filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT);
1416747b715Smrg
14205b261ecSmrg  /* Hack for backward compatibility */
14305b261ecSmrg  if (!filename && from == X_DEFAULT)
14405b261ecSmrg    filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT);
14505b261ecSmrg
14605b261ecSmrg  if (filename)
14705b261ecSmrg    {
14805b261ecSmrg      winMsg (from, "Using config file: \"%s\"\n", filename);
14905b261ecSmrg    }
15005b261ecSmrg  else
15105b261ecSmrg    {
15205b261ecSmrg      winMsg (X_ERROR, "Unable to locate/open config file");
15305b261ecSmrg      if (xf86ConfigFile)
15405b261ecSmrg	ErrorF (": \"%s\"", xf86ConfigFile);
15505b261ecSmrg      ErrorF ("\n");
1566747b715Smrg    }
1576747b715Smrg  if (dirname)
1586747b715Smrg    {
1596747b715Smrg      winMsg (from, "Using config directory: \"%s\"\n", dirname);
1606747b715Smrg    }
1616747b715Smrg  else
1626747b715Smrg    {
1636747b715Smrg      winMsg (X_ERROR, "Unable to locate/open config directory");
1646747b715Smrg      if (xf86ConfigDir)
1656747b715Smrg	ErrorF (": \"%s\"", xf86ConfigDir);
1666747b715Smrg      ErrorF ("\n");
1676747b715Smrg    }
1686747b715Smrg  if (!filename && !dirname)
1696747b715Smrg    {
17005b261ecSmrg      return FALSE;
17105b261ecSmrg    }
17205b261ecSmrg  if ((g_xf86configptr = xf86readConfigFile ()) == NULL)
17305b261ecSmrg    {
17405b261ecSmrg      winMsg (X_ERROR, "Problem parsing the config file\n");
17505b261ecSmrg      return FALSE;
17605b261ecSmrg    }
17705b261ecSmrg  xf86closeConfigFile ();
17805b261ecSmrg
17905b261ecSmrg  LogPrintMarkers();
18005b261ecSmrg
18105b261ecSmrg  /* set options from data structure */
18205b261ecSmrg
18305b261ecSmrg  if (g_xf86configptr->conf_layout_lst == NULL || g_cmdline.screenname != NULL)
18405b261ecSmrg    {
18505b261ecSmrg      if (g_cmdline.screenname == NULL)
18605b261ecSmrg	{
18705b261ecSmrg	  winMsg (X_WARNING,
18805b261ecSmrg		  "No Layout section. Using the first Screen section.\n");
18905b261ecSmrg	}
19005b261ecSmrg      if (!configImpliedLayout (&g_winConfigLayout,
19105b261ecSmrg				g_xf86configptr->conf_screen_lst))
19205b261ecSmrg	{
19305b261ecSmrg	  winMsg (X_ERROR, "Unable to determine the screen layout\n");
19405b261ecSmrg	  return FALSE;
19505b261ecSmrg	}
19605b261ecSmrg    }
19705b261ecSmrg  else
19805b261ecSmrg    {
19905b261ecSmrg      /* Check if layout is given in the config file */
20005b261ecSmrg      if (g_xf86configptr->conf_flags != NULL)
20105b261ecSmrg	{
20205b261ecSmrg	  char *dfltlayout = NULL;
20305b261ecSmrg	  pointer optlist = g_xf86configptr->conf_flags->flg_option_lst;
20405b261ecSmrg
20505b261ecSmrg	  if (optlist && winFindOption (optlist, "defaultserverlayout"))
20605b261ecSmrg	    dfltlayout =
20705b261ecSmrg	      winSetStrOption (optlist, "defaultserverlayout", NULL);
20805b261ecSmrg
20905b261ecSmrg	  if (!configLayout (&g_winConfigLayout,
21005b261ecSmrg			     g_xf86configptr->conf_layout_lst,
21105b261ecSmrg			     dfltlayout))
21205b261ecSmrg	    {
21305b261ecSmrg	      winMsg (X_ERROR, "Unable to determine the screen layout\n");
21405b261ecSmrg	      return FALSE;
21505b261ecSmrg	    }
21605b261ecSmrg	}
21705b261ecSmrg      else
21805b261ecSmrg	{
21905b261ecSmrg	  if (!configLayout (&g_winConfigLayout,
22005b261ecSmrg			     g_xf86configptr->conf_layout_lst,
22105b261ecSmrg			     NULL))
22205b261ecSmrg	    {
22305b261ecSmrg	      winMsg (X_ERROR, "Unable to determine the screen layout\n");
22405b261ecSmrg	      return FALSE;
22505b261ecSmrg	    }
22605b261ecSmrg	}
22705b261ecSmrg    }
22805b261ecSmrg
22905b261ecSmrg  /* setup special config files */
23005b261ecSmrg  winConfigFiles ();
23105b261ecSmrg  return retval;
23205b261ecSmrg}
23305b261ecSmrg#endif
23405b261ecSmrg
23505b261ecSmrg/* load layout definitions */
23605b261ecSmrg#include "winlayouts.h"
23705b261ecSmrg
23805b261ecSmrg/* Set the keyboard configuration */
23905b261ecSmrgBool
24005b261ecSmrgwinConfigKeyboard (DeviceIntPtr pDevice)
24105b261ecSmrg{
24205b261ecSmrg  char                          layoutName[KL_NAMELENGTH];
24305b261ecSmrg  static unsigned int           layoutNum = 0;
24405b261ecSmrg  int                           keyboardType;
24505b261ecSmrg#ifdef XWIN_XF86CONFIG
24605b261ecSmrg  XF86ConfInputPtr		kbd = NULL;
24705b261ecSmrg  XF86ConfInputPtr		input_list = NULL;
24805b261ecSmrg  MessageType			kbdfrom = X_CONFIG;
24905b261ecSmrg#endif
25005b261ecSmrg  MessageType			from = X_DEFAULT;
25105b261ecSmrg  char				*s = NULL;
25205b261ecSmrg
25305b261ecSmrg  /* Setup defaults */
2546747b715Smrg  XkbGetRulesDflts(&g_winInfo.xkb);
25505b261ecSmrg
25605b261ecSmrg  /*
25705b261ecSmrg   * Query the windows autorepeat settings and change the xserver defaults.
25805b261ecSmrg   */
25905b261ecSmrg  {
26005b261ecSmrg    int kbd_delay;
26105b261ecSmrg    DWORD kbd_speed;
26205b261ecSmrg    if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) &&
26305b261ecSmrg        SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0))
26405b261ecSmrg      {
26505b261ecSmrg        switch (kbd_delay)
26605b261ecSmrg          {
26705b261ecSmrg            case 0:  g_winInfo.keyboard.delay = 250; break;
26805b261ecSmrg            case 1:  g_winInfo.keyboard.delay = 500; break;
26905b261ecSmrg            case 2:  g_winInfo.keyboard.delay = 750; break;
27005b261ecSmrg            default:
27105b261ecSmrg            case 3:  g_winInfo.keyboard.delay = 1000; break;
27205b261ecSmrg          }
27305b261ecSmrg        g_winInfo.keyboard.rate = (kbd_speed>0)?kbd_speed:1;
27405b261ecSmrg        winMsgVerb(X_PROBED, 1, "Setting autorepeat to delay=%d, rate=%d\n",
27505b261ecSmrg                g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
27605b261ecSmrg      }
27705b261ecSmrg  }
27805b261ecSmrg
27905b261ecSmrg
28005b261ecSmrg  keyboardType = GetKeyboardType (0);
28105b261ecSmrg  if (keyboardType > 0 && GetKeyboardLayoutName (layoutName))
28205b261ecSmrg  {
28305b261ecSmrg    WinKBLayoutPtr	pLayout;
28405b261ecSmrg    Bool                bfound = FALSE;
28505b261ecSmrg
28605b261ecSmrg    if (! layoutNum)
28705b261ecSmrg      layoutNum = strtoul (layoutName, (char **)NULL, 16);
28805b261ecSmrg    if ((layoutNum & 0xffff) == 0x411) {
28905b261ecSmrg        /* The japanese layouts know a lot of different IMEs which all have
29005b261ecSmrg	   different layout numbers set. Map them to a single entry.
29105b261ecSmrg	   Same might apply for chinese, korean and other symbol languages
29205b261ecSmrg	   too */
29305b261ecSmrg        layoutNum = (layoutNum & 0xffff);
29405b261ecSmrg	if (keyboardType == 7)
29505b261ecSmrg	  {
29605b261ecSmrg	    /* Japanese layouts have problems with key event messages
29705b261ecSmrg	       such as the lack of WM_KEYUP for Caps Lock key.
29805b261ecSmrg	       Loading US layout fixes this problem. */
29905b261ecSmrg	    if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL)
30005b261ecSmrg	      winMsg (X_INFO, "Loading US keyboard layout.\n");
30105b261ecSmrg	    else
30205b261ecSmrg	      winMsg (X_ERROR, "LoadKeyboardLaout failed.\n");
30305b261ecSmrg	  }
30405b261ecSmrg    }
30505b261ecSmrg    winMsg (X_PROBED, "winConfigKeyboard - Layout: \"%s\" (%08x) \n",
30605b261ecSmrg            layoutName, layoutNum);
30705b261ecSmrg
30805b261ecSmrg    for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++)
30905b261ecSmrg      {
31005b261ecSmrg	if (pLayout->winlayout != layoutNum)
31105b261ecSmrg	  continue;
31205b261ecSmrg	if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
31305b261ecSmrg	  continue;
31405b261ecSmrg
31505b261ecSmrg        bfound = TRUE;
31605b261ecSmrg	winMsg (X_PROBED,
31705b261ecSmrg		"Using preset keyboard for \"%s\" (%x), type \"%d\"\n",
31805b261ecSmrg		pLayout->layoutname, pLayout->winlayout, keyboardType);
31905b261ecSmrg
32005b261ecSmrg	g_winInfo.xkb.model = pLayout->xkbmodel;
32105b261ecSmrg	g_winInfo.xkb.layout = pLayout->xkblayout;
32205b261ecSmrg	g_winInfo.xkb.variant = pLayout->xkbvariant;
32305b261ecSmrg	g_winInfo.xkb.options = pLayout->xkboptions;
32405b261ecSmrg	break;
32505b261ecSmrg      }
32605b261ecSmrg
32705b261ecSmrg    if (!bfound)
32805b261ecSmrg      {
32905b261ecSmrg        HKEY                regkey = NULL;
33005b261ecSmrg        const char          regtempl[] =
33105b261ecSmrg          "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
33205b261ecSmrg        char                *regpath;
3336747b715Smrg        unsigned char       lname[256];
33405b261ecSmrg        DWORD               namesize = sizeof(lname);
33505b261ecSmrg
33605b261ecSmrg        regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
33705b261ecSmrg        strcpy(regpath, regtempl);
33805b261ecSmrg        strcat(regpath, layoutName);
33905b261ecSmrg
34005b261ecSmrg        if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, &regkey) &&
34105b261ecSmrg          !RegQueryValueEx(regkey, "Layout Text", 0, NULL, lname, &namesize))
34205b261ecSmrg          {
34305b261ecSmrg	    winMsg (X_ERROR,
34405b261ecSmrg		"Keyboardlayout \"%s\" (%s) is unknown\n", lname, layoutName);
34505b261ecSmrg          }
34605b261ecSmrg
34705b261ecSmrg	/* Close registry key */
34805b261ecSmrg	if (regkey)
34905b261ecSmrg	  RegCloseKey (regkey);
35005b261ecSmrg        free(regpath);
35105b261ecSmrg      }
35205b261ecSmrg  }
35305b261ecSmrg
35405b261ecSmrg  /* parse the configuration */
35505b261ecSmrg#ifdef XWIN_XF86CONFIG
35605b261ecSmrg  if (g_cmdline.keyboard)
35705b261ecSmrg    kbdfrom = X_CMDLINE;
35805b261ecSmrg
35905b261ecSmrg  /*
36005b261ecSmrg   * Until the layout code is finished, I search for the keyboard
36105b261ecSmrg   * device and configure the server with it.
36205b261ecSmrg   */
36305b261ecSmrg
36405b261ecSmrg  if (g_xf86configptr != NULL)
36505b261ecSmrg    input_list = g_xf86configptr->conf_input_lst;
36605b261ecSmrg
36705b261ecSmrg  while (input_list != NULL)
36805b261ecSmrg    {
36905b261ecSmrg      if (winNameCompare (input_list->inp_driver, "keyboard") == 0)
37005b261ecSmrg	{
37105b261ecSmrg	  /* Check if device name matches requested name */
37205b261ecSmrg	  if (g_cmdline.keyboard && winNameCompare (input_list->inp_identifier,
37305b261ecSmrg						    g_cmdline.keyboard))
37405b261ecSmrg	    continue;
37505b261ecSmrg	  kbd = input_list;
37605b261ecSmrg	}
37705b261ecSmrg      input_list = input_list->list.next;
37805b261ecSmrg    }
37905b261ecSmrg
38005b261ecSmrg  if (kbd != NULL)
38105b261ecSmrg    {
38205b261ecSmrg
38305b261ecSmrg      if (kbd->inp_identifier)
38405b261ecSmrg	winMsg (kbdfrom, "Using keyboard \"%s\" as primary keyboard\n",
38505b261ecSmrg		kbd->inp_identifier);
38605b261ecSmrg
38705b261ecSmrg      if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL)))
38805b261ecSmrg        {
38905b261ecSmrg          if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay,
39005b261ecSmrg                      &g_winInfo.keyboard.rate) != 2) ||
39105b261ecSmrg                  (g_winInfo.keyboard.delay < 1) ||
39205b261ecSmrg                  (g_winInfo.keyboard.rate == 0) ||
39305b261ecSmrg                  (1000 / g_winInfo.keyboard.rate) < 1)
39405b261ecSmrg            {
39505b261ecSmrg              winErrorFVerb (2, "\"%s\" is not a valid AutoRepeat value", s);
3966747b715Smrg              free(s);
39705b261ecSmrg              return FALSE;
39805b261ecSmrg            }
3996747b715Smrg          free(s);
40005b261ecSmrg          winMsg (X_CONFIG, "AutoRepeat: %ld %ld\n",
40105b261ecSmrg                  g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
40205b261ecSmrg        }
40305b261ecSmrg#endif
40405b261ecSmrg
4056747b715Smrg        s = NULL;
4066747b715Smrg        if (g_cmdline.xkbRules)
4076747b715Smrg          {
4086747b715Smrg            s = g_cmdline.xkbRules;
4096747b715Smrg            from = X_CMDLINE;
4106747b715Smrg          }
41105b261ecSmrg#ifdef XWIN_XF86CONFIG
4126747b715Smrg        else
4136747b715Smrg          {
4146747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbRules", NULL);
4156747b715Smrg            from = X_CONFIG;
4166747b715Smrg          }
41705b261ecSmrg#endif
4186747b715Smrg        if (s)
4196747b715Smrg          {
4206747b715Smrg            g_winInfo.xkb.rules = NULL_IF_EMPTY (s);
4216747b715Smrg            winMsg (from, "XKB: rules: \"%s\"\n", s);
4226747b715Smrg	  }
42305b261ecSmrg
4246747b715Smrg        s = NULL;
4256747b715Smrg        if (g_cmdline.xkbModel)
4266747b715Smrg          {
4276747b715Smrg            s = g_cmdline.xkbModel;
4286747b715Smrg            from = X_CMDLINE;
4296747b715Smrg          }
43005b261ecSmrg#ifdef XWIN_XF86CONFIG
4316747b715Smrg        else
4326747b715Smrg          {
4336747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbModel", NULL);
4346747b715Smrg            from = X_CONFIG;
4356747b715Smrg          }
43605b261ecSmrg#endif
4376747b715Smrg        if (s)
4386747b715Smrg	  {
4396747b715Smrg	    g_winInfo.xkb.model = NULL_IF_EMPTY (s);
4406747b715Smrg	    winMsg (from, "XKB: model: \"%s\"\n", s);
4416747b715Smrg	  }
44205b261ecSmrg
4436747b715Smrg        s = NULL;
4446747b715Smrg        if (g_cmdline.xkbLayout)
4456747b715Smrg          {
4466747b715Smrg            s = g_cmdline.xkbLayout;
4476747b715Smrg            from = X_CMDLINE;
4486747b715Smrg          }
44905b261ecSmrg#ifdef XWIN_XF86CONFIG
4506747b715Smrg        else
4516747b715Smrg          {
4526747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbLayout", NULL);
4536747b715Smrg            from = X_CONFIG;
4546747b715Smrg          }
45505b261ecSmrg#endif
4566747b715Smrg        if (s)
4576747b715Smrg          {
4586747b715Smrg	    g_winInfo.xkb.layout = NULL_IF_EMPTY (s);
4596747b715Smrg	    winMsg (from, "XKB: layout: \"%s\"\n", s);
4606747b715Smrg	  }
46105b261ecSmrg
4626747b715Smrg        s = NULL;
4636747b715Smrg        if (g_cmdline.xkbVariant)
4646747b715Smrg          {
4656747b715Smrg            s = g_cmdline.xkbVariant;
4666747b715Smrg            from = X_CMDLINE;
4676747b715Smrg          }
46805b261ecSmrg#ifdef XWIN_XF86CONFIG
4696747b715Smrg        else
4706747b715Smrg          {
4716747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbVariant", NULL);
4726747b715Smrg            from = X_CONFIG;
4736747b715Smrg          }
47405b261ecSmrg#endif
4756747b715Smrg	if (s)
4766747b715Smrg	  {
4776747b715Smrg	    g_winInfo.xkb.variant = NULL_IF_EMPTY (s);
4786747b715Smrg	    winMsg (from, "XKB: variant: \"%s\"\n", s);
4796747b715Smrg	  }
48005b261ecSmrg
4816747b715Smrg        s = NULL;
4826747b715Smrg        if (g_cmdline.xkbOptions)
4836747b715Smrg          {
4846747b715Smrg            s = g_cmdline.xkbOptions;
4856747b715Smrg            from = X_CMDLINE;
4866747b715Smrg          }
48705b261ecSmrg#ifdef XWIN_XF86CONFIG
4886747b715Smrg        else
4896747b715Smrg          {
4906747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbOptions", NULL);
4916747b715Smrg            from = X_CONFIG;
4926747b715Smrg          }
49305b261ecSmrg#endif
4946747b715Smrg        if (s)
4956747b715Smrg	  {
4966747b715Smrg	    g_winInfo.xkb.options = NULL_IF_EMPTY (s);
4976747b715Smrg	    winMsg (from, "XKB: options: \"%s\"\n", s);
4986747b715Smrg	  }
49905b261ecSmrg
50005b261ecSmrg#ifdef XWIN_XF86CONFIG
50105b261ecSmrg    }
50205b261ecSmrg#endif
50305b261ecSmrg
50405b261ecSmrg  return TRUE;
50505b261ecSmrg}
50605b261ecSmrg
50705b261ecSmrg
50805b261ecSmrg#ifdef XWIN_XF86CONFIG
50905b261ecSmrgBool
51005b261ecSmrgwinConfigMouse (DeviceIntPtr pDevice)
51105b261ecSmrg{
51205b261ecSmrg  MessageType			mousefrom = X_CONFIG;
51305b261ecSmrg
51405b261ecSmrg  XF86ConfInputPtr		mouse = NULL;
51505b261ecSmrg  XF86ConfInputPtr		input_list = NULL;
51605b261ecSmrg
51705b261ecSmrg  if (g_cmdline.mouse)
51805b261ecSmrg    mousefrom = X_CMDLINE;
51905b261ecSmrg
52005b261ecSmrg  if (g_xf86configptr != NULL)
52105b261ecSmrg    input_list = g_xf86configptr->conf_input_lst;
52205b261ecSmrg
52305b261ecSmrg  while (input_list != NULL)
52405b261ecSmrg    {
52505b261ecSmrg      if (winNameCompare (input_list->inp_driver, "mouse") == 0)
52605b261ecSmrg	{
52705b261ecSmrg	  /* Check if device name matches requested name */
52805b261ecSmrg	  if (g_cmdline.mouse && winNameCompare (input_list->inp_identifier,
52905b261ecSmrg						 g_cmdline.mouse))
53005b261ecSmrg	    continue;
53105b261ecSmrg	  mouse = input_list;
53205b261ecSmrg	}
53305b261ecSmrg      input_list = input_list->list.next;
53405b261ecSmrg    }
53505b261ecSmrg
53605b261ecSmrg  if (mouse != NULL)
53705b261ecSmrg    {
53805b261ecSmrg      if (mouse->inp_identifier)
53905b261ecSmrg	winMsg (mousefrom, "Using pointer \"%s\" as primary pointer\n",
54005b261ecSmrg		mouse->inp_identifier);
54105b261ecSmrg
54205b261ecSmrg      g_winInfo.pointer.emulate3Buttons =
54305b261ecSmrg	winSetBoolOption (mouse->inp_option_lst, "Emulate3Buttons", FALSE);
54405b261ecSmrg      if (g_cmdline.emulate3buttons)
54505b261ecSmrg	g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons;
54605b261ecSmrg
54705b261ecSmrg      g_winInfo.pointer.emulate3Timeout =
54805b261ecSmrg	winSetIntOption (mouse->inp_option_lst, "Emulate3Timeout", 50);
54905b261ecSmrg      if (g_cmdline.emulate3timeout)
55005b261ecSmrg	g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout;
55105b261ecSmrg    }
55205b261ecSmrg  else
55305b261ecSmrg    {
55405b261ecSmrg      winMsg (X_ERROR, "No primary pointer configured\n");
55505b261ecSmrg      winMsg (X_DEFAULT, "Using compiletime defaults for pointer\n");
55605b261ecSmrg    }
55705b261ecSmrg
55805b261ecSmrg  return TRUE;
55905b261ecSmrg}
56005b261ecSmrg
56105b261ecSmrg
56205b261ecSmrgBool
56305b261ecSmrgwinConfigFiles ()
56405b261ecSmrg{
56505b261ecSmrg  MessageType from;
56605b261ecSmrg  XF86ConfFilesPtr filesptr = NULL;
56705b261ecSmrg
56805b261ecSmrg  /* set some shortcuts */
56905b261ecSmrg  if (g_xf86configptr != NULL)
57005b261ecSmrg    {
57105b261ecSmrg      filesptr = g_xf86configptr->conf_files;
57205b261ecSmrg    }
57305b261ecSmrg
57405b261ecSmrg
57505b261ecSmrg  /* Fontpath */
57605b261ecSmrg  from = X_DEFAULT;
57705b261ecSmrg
57805b261ecSmrg  if (g_cmdline.fontPath)
57905b261ecSmrg    {
58005b261ecSmrg      from = X_CMDLINE;
58105b261ecSmrg      defaultFontPath = g_cmdline.fontPath;
58205b261ecSmrg    }
58305b261ecSmrg  else if (filesptr != NULL && filesptr->file_fontpath)
58405b261ecSmrg    {
58505b261ecSmrg      from = X_CONFIG;
5866747b715Smrg      defaultFontPath = strdup (filesptr->file_fontpath);
58705b261ecSmrg    }
58805b261ecSmrg  winMsg (from, "FontPath set to \"%s\"\n", defaultFontPath);
58905b261ecSmrg
59005b261ecSmrg  return TRUE;
59105b261ecSmrg}
59205b261ecSmrg#else
59305b261ecSmrgBool
5946747b715SmrgwinConfigFiles (void)
59505b261ecSmrg{
59605b261ecSmrg  /* Fontpath */
59705b261ecSmrg  if (g_cmdline.fontPath)
59805b261ecSmrg    {
59905b261ecSmrg      defaultFontPath = g_cmdline.fontPath;
60005b261ecSmrg      winMsg (X_CMDLINE, "FontPath set to \"%s\"\n", defaultFontPath);
60105b261ecSmrg    }
60205b261ecSmrg
60305b261ecSmrg  return TRUE;
60405b261ecSmrg}
60505b261ecSmrg#endif
60605b261ecSmrg
60705b261ecSmrg
60805b261ecSmrgBool
6096747b715SmrgwinConfigOptions (void)
61005b261ecSmrg{
61105b261ecSmrg  return TRUE;
61205b261ecSmrg}
61305b261ecSmrg
61405b261ecSmrg
61505b261ecSmrgBool
6166747b715SmrgwinConfigScreens (void)
61705b261ecSmrg{
61805b261ecSmrg  return TRUE;
61905b261ecSmrg}
62005b261ecSmrg
62105b261ecSmrg
62205b261ecSmrg#ifdef XWIN_XF86CONFIG
62305b261ecSmrgchar *
62405b261ecSmrgwinSetStrOption (pointer optlist, const char *name, char *deflt)
62505b261ecSmrg{
62605b261ecSmrg  OptionInfoRec o;
62705b261ecSmrg
62805b261ecSmrg  o.name = name;
62905b261ecSmrg  o.type = OPTV_STRING;
63005b261ecSmrg  if (ParseOptionValue (-1, optlist, &o))
63105b261ecSmrg    deflt = o.value.str;
63205b261ecSmrg  if (deflt)
6336747b715Smrg    return strdup (deflt);
63405b261ecSmrg  else
63505b261ecSmrg    return NULL;
63605b261ecSmrg}
63705b261ecSmrg
63805b261ecSmrg
63905b261ecSmrgint
64005b261ecSmrgwinSetBoolOption (pointer optlist, const char *name, int deflt)
64105b261ecSmrg{
64205b261ecSmrg  OptionInfoRec o;
64305b261ecSmrg
64405b261ecSmrg  o.name = name;
64505b261ecSmrg  o.type = OPTV_BOOLEAN;
64605b261ecSmrg  if (ParseOptionValue (-1, optlist, &o))
64705b261ecSmrg    deflt = o.value.bool;
64805b261ecSmrg  return deflt;
64905b261ecSmrg}
65005b261ecSmrg
65105b261ecSmrg
65205b261ecSmrgint
65305b261ecSmrgwinSetIntOption (pointer optlist, const char *name, int deflt)
65405b261ecSmrg{
65505b261ecSmrg  OptionInfoRec o;
65605b261ecSmrg
65705b261ecSmrg  o.name = name;
65805b261ecSmrg  o.type = OPTV_INTEGER;
65905b261ecSmrg  if (ParseOptionValue (-1, optlist, &o))
66005b261ecSmrg    deflt = o.value.num;
66105b261ecSmrg  return deflt;
66205b261ecSmrg}
66305b261ecSmrg
66405b261ecSmrg
66505b261ecSmrgdouble
66605b261ecSmrgwinSetRealOption (pointer optlist, const char *name, double deflt)
66705b261ecSmrg{
66805b261ecSmrg  OptionInfoRec o;
66905b261ecSmrg
67005b261ecSmrg  o.name = name;
67105b261ecSmrg  o.type = OPTV_REAL;
67205b261ecSmrg  if (ParseOptionValue (-1, optlist, &o))
67305b261ecSmrg    deflt = o.value.realnum;
67405b261ecSmrg  return deflt;
67505b261ecSmrg}
6766747b715Smrg
6776747b715Smrgdouble
6786747b715SmrgwinSetPercentOption (pointer optlist, const char *name, double deflt)
6796747b715Smrg{
6806747b715Smrg  OptionInfoRec o;
6816747b715Smrg
6826747b715Smrg  o.name = name;
6836747b715Smrg  o.type = OPTV_PERCENT;
6846747b715Smrg  if (ParseOptionValue (-1, optlist, &o))
6856747b715Smrg    deflt = o.value.realnum;
6866747b715Smrg  return deflt;
6876747b715Smrg}
68805b261ecSmrg#endif
68905b261ecSmrg
69005b261ecSmrg
69105b261ecSmrg/*
69205b261ecSmrg * Compare two strings for equality. This is caseinsensitive  and
69305b261ecSmrg * The characters '_', ' ' (space) and '\t' (tab) are treated as
69405b261ecSmrg * not existing.
69505b261ecSmrg */
69605b261ecSmrg
69705b261ecSmrgint
69805b261ecSmrgwinNameCompare (const char *s1, const char *s2)
69905b261ecSmrg{
70005b261ecSmrg  char c1, c2;
70105b261ecSmrg
70205b261ecSmrg  if (!s1 || *s1 == 0)
70305b261ecSmrg    {
70405b261ecSmrg      if (!s2 || *s2 == 0)
70505b261ecSmrg	return 0;
70605b261ecSmrg      else
70705b261ecSmrg	return 1;
70805b261ecSmrg    }
70905b261ecSmrg
71005b261ecSmrg  while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
71105b261ecSmrg    s1++;
71205b261ecSmrg  while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
71305b261ecSmrg    s2++;
71405b261ecSmrg
71505b261ecSmrg  c1 = (isupper (*s1) ? tolower (*s1) : *s1);
71605b261ecSmrg  c2 = (isupper (*s2) ? tolower (*s2) : *s2);
71705b261ecSmrg
71805b261ecSmrg  while (c1 == c2)
71905b261ecSmrg    {
72005b261ecSmrg      if (c1 == 0)
72105b261ecSmrg	return 0;
72205b261ecSmrg      s1++;
72305b261ecSmrg      s2++;
72405b261ecSmrg
72505b261ecSmrg      while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
72605b261ecSmrg	s1++;
72705b261ecSmrg      while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
72805b261ecSmrg	s2++;
72905b261ecSmrg
73005b261ecSmrg      c1 = (isupper (*s1) ? tolower (*s1) : *s1);
73105b261ecSmrg      c2 = (isupper (*s2) ? tolower (*s2) : *s2);
73205b261ecSmrg    }
7336747b715Smrg  return c1 - c2;
73405b261ecSmrg}
73505b261ecSmrg
73605b261ecSmrg
73705b261ecSmrg#ifdef XWIN_XF86CONFIG
73805b261ecSmrg/*
73905b261ecSmrg * Find the named option in the list.
74005b261ecSmrg * @return the pointer to the option record, or NULL if not found.
74105b261ecSmrg */
74205b261ecSmrg
74305b261ecSmrgXF86OptionPtr
74405b261ecSmrgwinFindOption (XF86OptionPtr list, const char *name)
74505b261ecSmrg{
74605b261ecSmrg  while (list)
74705b261ecSmrg    {
74805b261ecSmrg      if (winNameCompare (list->opt_name, name) == 0)
74905b261ecSmrg	return list;
75005b261ecSmrg      list = list->list.next;
75105b261ecSmrg    }
75205b261ecSmrg  return NULL;
75305b261ecSmrg}
75405b261ecSmrg
75505b261ecSmrg
75605b261ecSmrg/*
75705b261ecSmrg * Find the Value of an named option.
75805b261ecSmrg * @return The option value or NULL if not found.
75905b261ecSmrg */
76005b261ecSmrg
76105b261ecSmrgchar *
76205b261ecSmrgwinFindOptionValue (XF86OptionPtr list, const char *name)
76305b261ecSmrg{
76405b261ecSmrg  list = winFindOption (list, name);
76505b261ecSmrg  if (list)
76605b261ecSmrg    {
76705b261ecSmrg      if (list->opt_val)
7686747b715Smrg	return list->opt_val;
76905b261ecSmrg      else
77005b261ecSmrg	return "";
77105b261ecSmrg    }
7726747b715Smrg  return NULL;
77305b261ecSmrg}
77405b261ecSmrg
77505b261ecSmrg
77605b261ecSmrg/*
77705b261ecSmrg * Parse the option.
77805b261ecSmrg */
77905b261ecSmrg
78005b261ecSmrgstatic Bool
78105b261ecSmrgParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p)
78205b261ecSmrg{
78305b261ecSmrg  char *s, *end;
78405b261ecSmrg
78505b261ecSmrg  if ((s = winFindOptionValue (options, p->name)) != NULL)
78605b261ecSmrg    {
78705b261ecSmrg      switch (p->type)
78805b261ecSmrg	{
78905b261ecSmrg	case OPTV_INTEGER:
79005b261ecSmrg	  if (*s == '\0')
79105b261ecSmrg	    {
79205b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
79305b261ecSmrg			 "Option \"%s\" requires an integer value\n",
79405b261ecSmrg			 p->name);
79505b261ecSmrg	      p->found = FALSE;
79605b261ecSmrg	    }
79705b261ecSmrg	  else
79805b261ecSmrg	    {
79905b261ecSmrg	      p->value.num = strtoul (s, &end, 0);
80005b261ecSmrg	      if (*end == '\0')
80105b261ecSmrg		{
80205b261ecSmrg		  p->found = TRUE;
80305b261ecSmrg		}
80405b261ecSmrg	      else
80505b261ecSmrg		{
80605b261ecSmrg		  winDrvMsg (scrnIndex, X_WARNING,
80705b261ecSmrg			     "Option \"%s\" requires an integer value\n",
80805b261ecSmrg			     p->name);
80905b261ecSmrg		  p->found = FALSE;
81005b261ecSmrg		}
81105b261ecSmrg	    }
81205b261ecSmrg	  break;
81305b261ecSmrg	case OPTV_STRING:
81405b261ecSmrg	  if (*s == '\0')
81505b261ecSmrg	    {
81605b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
81705b261ecSmrg			 "Option \"%s\" requires an string value\n", p->name);
81805b261ecSmrg	      p->found = FALSE;
81905b261ecSmrg	    }
82005b261ecSmrg	  else
82105b261ecSmrg	    {
82205b261ecSmrg	      p->value.str = s;
82305b261ecSmrg	      p->found = TRUE;
82405b261ecSmrg	    }
82505b261ecSmrg	  break;
82605b261ecSmrg	case OPTV_ANYSTR:
82705b261ecSmrg	  p->value.str = s;
82805b261ecSmrg	  p->found = TRUE;
82905b261ecSmrg	  break;
83005b261ecSmrg	case OPTV_REAL:
83105b261ecSmrg	  if (*s == '\0')
83205b261ecSmrg	    {
83305b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
83405b261ecSmrg			 "Option \"%s\" requires a floating point value\n",
83505b261ecSmrg			 p->name);
83605b261ecSmrg	      p->found = FALSE;
83705b261ecSmrg	    }
83805b261ecSmrg	  else
83905b261ecSmrg	    {
84005b261ecSmrg	      p->value.realnum = strtod (s, &end);
84105b261ecSmrg	      if (*end == '\0')
84205b261ecSmrg		{
84305b261ecSmrg		  p->found = TRUE;
84405b261ecSmrg		}
84505b261ecSmrg	      else
84605b261ecSmrg		{
84705b261ecSmrg		  winDrvMsg (scrnIndex, X_WARNING,
84805b261ecSmrg			     "Option \"%s\" requires a floating point value\n",
84905b261ecSmrg			     p->name);
85005b261ecSmrg		  p->found = FALSE;
85105b261ecSmrg		}
85205b261ecSmrg	    }
85305b261ecSmrg	  break;
85405b261ecSmrg	case OPTV_BOOLEAN:
85505b261ecSmrg	  if (GetBoolValue (p, s))
85605b261ecSmrg	    {
85705b261ecSmrg	      p->found = TRUE;
85805b261ecSmrg	    }
85905b261ecSmrg	  else
86005b261ecSmrg	    {
86105b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
86205b261ecSmrg			 "Option \"%s\" requires a boolean value\n", p->name);
86305b261ecSmrg	      p->found = FALSE;
86405b261ecSmrg	    }
86505b261ecSmrg	  break;
8666747b715Smrg	case OPTV_PERCENT:
8676747b715Smrg	  if (*s == '\0')
8686747b715Smrg	    {
8696747b715Smrg	      winDrvMsg (scrnIndex, X_WARNING,
8706747b715Smrg			 "Option \"%s\" requires a percent value\n",
8716747b715Smrg			 p->name);
8726747b715Smrg	      p->found = FALSE;
8736747b715Smrg	    }
8746747b715Smrg	  else
8756747b715Smrg	    {
8766747b715Smrg	       double percent = strtod (s, &end);
8776747b715Smrg
8786747b715Smrg	       if (end != s && winNameCompare (end, "%"))
8796747b715Smrg		 {
8806747b715Smrg		   p->found = TRUE;
8816747b715Smrg		   p->value.realnum = percent;
8826747b715Smrg		 }
8836747b715Smrg	       else
8846747b715Smrg		 {
8856747b715Smrg		   winDrvMsg (scrnIndex, X_WARNING,
8866747b715Smrg			      "Option \"%s\" requires a frequency value\n",
8876747b715Smrg			       p->name);
8886747b715Smrg		   p->found = FALSE;
8896747b715Smrg		 }
8906747b715Smrg	    }
89105b261ecSmrg	case OPTV_FREQ:
89205b261ecSmrg	  if (*s == '\0')
89305b261ecSmrg	    {
89405b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
89505b261ecSmrg			 "Option \"%s\" requires a frequency value\n",
89605b261ecSmrg			 p->name);
89705b261ecSmrg	      p->found = FALSE;
89805b261ecSmrg	    }
89905b261ecSmrg	  else
90005b261ecSmrg	    {
90105b261ecSmrg	      double freq = strtod (s, &end);
90205b261ecSmrg	      int units = 0;
90305b261ecSmrg
90405b261ecSmrg	      if (end != s)
90505b261ecSmrg		{
90605b261ecSmrg		  p->found = TRUE;
90705b261ecSmrg		  if (!winNameCompare (end, "Hz"))
90805b261ecSmrg		    units = 1;
90905b261ecSmrg		  else if (!winNameCompare (end, "kHz") ||
91005b261ecSmrg			   !winNameCompare (end, "k"))
91105b261ecSmrg		    units = 1000;
91205b261ecSmrg		  else if (!winNameCompare (end, "MHz") ||
91305b261ecSmrg			   !winNameCompare (end, "M"))
91405b261ecSmrg		    units = 1000000;
91505b261ecSmrg		  else
91605b261ecSmrg		    {
91705b261ecSmrg		      winDrvMsg (scrnIndex, X_WARNING,
91805b261ecSmrg				 "Option \"%s\" requires a frequency value\n",
91905b261ecSmrg				 p->name);
92005b261ecSmrg		      p->found = FALSE;
92105b261ecSmrg		    }
92205b261ecSmrg		  if (p->found)
92305b261ecSmrg		    freq *= (double) units;
92405b261ecSmrg		}
92505b261ecSmrg	      else
92605b261ecSmrg		{
92705b261ecSmrg		  winDrvMsg (scrnIndex, X_WARNING,
92805b261ecSmrg			     "Option \"%s\" requires a frequency value\n",
92905b261ecSmrg			     p->name);
93005b261ecSmrg		  p->found = FALSE;
93105b261ecSmrg		}
93205b261ecSmrg	      if (p->found)
93305b261ecSmrg		{
93405b261ecSmrg		  p->value.freq.freq = freq;
93505b261ecSmrg		  p->value.freq.units = units;
93605b261ecSmrg		}
93705b261ecSmrg	    }
93805b261ecSmrg	  break;
93905b261ecSmrg	case OPTV_NONE:
94005b261ecSmrg	  /* Should never get here */
94105b261ecSmrg	  p->found = FALSE;
94205b261ecSmrg	  break;
94305b261ecSmrg	}
94405b261ecSmrg      if (p->found)
94505b261ecSmrg	{
94605b261ecSmrg	  winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", p->name);
94705b261ecSmrg	  if (!(p->type == OPTV_BOOLEAN && *s == 0))
94805b261ecSmrg	    {
94905b261ecSmrg	      winErrorFVerb (2, " \"%s\"", s);
95005b261ecSmrg	    }
95105b261ecSmrg	  winErrorFVerb (2, "\n");
95205b261ecSmrg	}
95305b261ecSmrg    }
95405b261ecSmrg  else if (p->type == OPTV_BOOLEAN)
95505b261ecSmrg    {
95605b261ecSmrg      /* Look for matches with options with or without a "No" prefix. */
95705b261ecSmrg      char *n, *newn;
95805b261ecSmrg      OptionInfoRec opt;
95905b261ecSmrg
96005b261ecSmrg      n = winNormalizeName (p->name);
96105b261ecSmrg      if (!n)
96205b261ecSmrg	{
96305b261ecSmrg	  p->found = FALSE;
96405b261ecSmrg	  return FALSE;
96505b261ecSmrg	}
96605b261ecSmrg      if (strncmp (n, "no", 2) == 0)
96705b261ecSmrg	{
96805b261ecSmrg	  newn = n + 2;
96905b261ecSmrg	}
97005b261ecSmrg      else
97105b261ecSmrg	{
97205b261ecSmrg	  free (n);
97305b261ecSmrg	  n = malloc (strlen (p->name) + 2 + 1);
97405b261ecSmrg	  if (!n)
97505b261ecSmrg	    {
97605b261ecSmrg	      p->found = FALSE;
97705b261ecSmrg	      return FALSE;
97805b261ecSmrg	    }
97905b261ecSmrg	  strcpy (n, "No");
98005b261ecSmrg	  strcat (n, p->name);
98105b261ecSmrg	  newn = n;
98205b261ecSmrg	}
98305b261ecSmrg      if ((s = winFindOptionValue (options, newn)) != NULL)
98405b261ecSmrg	{
98505b261ecSmrg	  if (GetBoolValue (&opt, s))
98605b261ecSmrg	    {
98705b261ecSmrg	      p->value.bool = !opt.value.bool;
98805b261ecSmrg	      p->found = TRUE;
98905b261ecSmrg	    }
99005b261ecSmrg	  else
99105b261ecSmrg	    {
99205b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
99305b261ecSmrg			 "Option \"%s\" requires a boolean value\n", newn);
99405b261ecSmrg	      p->found = FALSE;
99505b261ecSmrg	    }
99605b261ecSmrg	}
99705b261ecSmrg      else
99805b261ecSmrg	{
99905b261ecSmrg	  p->found = FALSE;
100005b261ecSmrg	}
100105b261ecSmrg      if (p->found)
100205b261ecSmrg	{
100305b261ecSmrg	  winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
100405b261ecSmrg	  if (*s != 0)
100505b261ecSmrg	    {
100605b261ecSmrg	      winErrorFVerb (2, " \"%s\"", s);
100705b261ecSmrg	    }
100805b261ecSmrg	  winErrorFVerb (2, "\n");
100905b261ecSmrg	}
101005b261ecSmrg      free (n);
101105b261ecSmrg    }
101205b261ecSmrg  else
101305b261ecSmrg    {
101405b261ecSmrg      p->found = FALSE;
101505b261ecSmrg    }
101605b261ecSmrg  return p->found;
101705b261ecSmrg}
101805b261ecSmrg
101905b261ecSmrg
102005b261ecSmrgstatic Bool
102105b261ecSmrgconfigLayout (serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
102205b261ecSmrg	      char *default_layout)
102305b261ecSmrg{
102405b261ecSmrg#if 0
102505b261ecSmrg#pragma warn UNIMPLEMENTED
102605b261ecSmrg#endif
102705b261ecSmrg  return TRUE;
102805b261ecSmrg}
102905b261ecSmrg
103005b261ecSmrg
103105b261ecSmrgstatic Bool
103205b261ecSmrgconfigImpliedLayout (serverLayoutPtr servlayoutp,
103305b261ecSmrg		     XF86ConfScreenPtr conf_screen)
103405b261ecSmrg{
103505b261ecSmrg#if 0
103605b261ecSmrg#pragma warn UNIMPLEMENTED
103705b261ecSmrg#endif
103805b261ecSmrg  return TRUE;
103905b261ecSmrg}
104005b261ecSmrg
104105b261ecSmrg
104205b261ecSmrgstatic Bool
104305b261ecSmrgGetBoolValue (OptionInfoPtr p, const char *s)
104405b261ecSmrg{
104505b261ecSmrg  if (*s == 0)
104605b261ecSmrg    {
104705b261ecSmrg      p->value.bool = TRUE;
104805b261ecSmrg    }
104905b261ecSmrg  else
105005b261ecSmrg    {
105105b261ecSmrg      if (winNameCompare (s, "1") == 0)
105205b261ecSmrg	p->value.bool = TRUE;
105305b261ecSmrg      else if (winNameCompare (s, "on") == 0)
105405b261ecSmrg	p->value.bool = TRUE;
105505b261ecSmrg      else if (winNameCompare (s, "true") == 0)
105605b261ecSmrg	p->value.bool = TRUE;
105705b261ecSmrg      else if (winNameCompare (s, "yes") == 0)
105805b261ecSmrg	p->value.bool = TRUE;
105905b261ecSmrg      else if (winNameCompare (s, "0") == 0)
106005b261ecSmrg	p->value.bool = FALSE;
106105b261ecSmrg      else if (winNameCompare (s, "off") == 0)
106205b261ecSmrg	p->value.bool = FALSE;
106305b261ecSmrg      else if (winNameCompare (s, "false") == 0)
106405b261ecSmrg	p->value.bool = FALSE;
106505b261ecSmrg      else if (winNameCompare (s, "no") == 0)
106605b261ecSmrg	p->value.bool = FALSE;
106705b261ecSmrg    }
106805b261ecSmrg  return TRUE;
106905b261ecSmrg}
107005b261ecSmrg#endif
107105b261ecSmrg
107205b261ecSmrg
107305b261ecSmrgchar *
107405b261ecSmrgwinNormalizeName (const char *s)
107505b261ecSmrg{
107605b261ecSmrg  char *ret, *q;
107705b261ecSmrg  const char *p;
107805b261ecSmrg
107905b261ecSmrg  if (s == NULL)
108005b261ecSmrg    return NULL;
108105b261ecSmrg
108205b261ecSmrg  ret = malloc (strlen (s) + 1);
108305b261ecSmrg  for (p = s, q = ret; *p != 0; p++)
108405b261ecSmrg    {
108505b261ecSmrg      switch (*p)
108605b261ecSmrg	{
108705b261ecSmrg	case '_':
108805b261ecSmrg	case ' ':
108905b261ecSmrg	case '\t':
109005b261ecSmrg	  continue;
109105b261ecSmrg	default:
109205b261ecSmrg	  if (isupper (*p))
109305b261ecSmrg	    *q++ = tolower (*p);
109405b261ecSmrg	  else
109505b261ecSmrg	    *q++ = *p;
109605b261ecSmrg	}
109705b261ecSmrg    }
109805b261ecSmrg  *q = '\0';
109905b261ecSmrg  return ret;
110005b261ecSmrg}
110105b261ecSmrg
1102