winconfig.c revision 9ace9065
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];
2439ace9065Smrg  unsigned char                 layoutFriendlyName[256];
24405b261ecSmrg  static unsigned int           layoutNum = 0;
24505b261ecSmrg  int                           keyboardType;
24605b261ecSmrg#ifdef XWIN_XF86CONFIG
24705b261ecSmrg  XF86ConfInputPtr		kbd = NULL;
24805b261ecSmrg  XF86ConfInputPtr		input_list = NULL;
24905b261ecSmrg  MessageType			kbdfrom = X_CONFIG;
25005b261ecSmrg#endif
25105b261ecSmrg  MessageType			from = X_DEFAULT;
25205b261ecSmrg  char				*s = NULL;
25305b261ecSmrg
25405b261ecSmrg  /* Setup defaults */
2556747b715Smrg  XkbGetRulesDflts(&g_winInfo.xkb);
25605b261ecSmrg
25705b261ecSmrg  /*
25805b261ecSmrg   * Query the windows autorepeat settings and change the xserver defaults.
25905b261ecSmrg   */
26005b261ecSmrg  {
26105b261ecSmrg    int kbd_delay;
26205b261ecSmrg    DWORD kbd_speed;
26305b261ecSmrg    if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) &&
26405b261ecSmrg        SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0))
26505b261ecSmrg      {
26605b261ecSmrg        switch (kbd_delay)
26705b261ecSmrg          {
26805b261ecSmrg            case 0:  g_winInfo.keyboard.delay = 250; break;
26905b261ecSmrg            case 1:  g_winInfo.keyboard.delay = 500; break;
27005b261ecSmrg            case 2:  g_winInfo.keyboard.delay = 750; break;
27105b261ecSmrg            default:
27205b261ecSmrg            case 3:  g_winInfo.keyboard.delay = 1000; break;
27305b261ecSmrg          }
27405b261ecSmrg        g_winInfo.keyboard.rate = (kbd_speed>0)?kbd_speed:1;
27505b261ecSmrg        winMsgVerb(X_PROBED, 1, "Setting autorepeat to delay=%d, rate=%d\n",
27605b261ecSmrg                g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
27705b261ecSmrg      }
27805b261ecSmrg  }
27905b261ecSmrg
28005b261ecSmrg
28105b261ecSmrg  keyboardType = GetKeyboardType (0);
28205b261ecSmrg  if (keyboardType > 0 && GetKeyboardLayoutName (layoutName))
28305b261ecSmrg  {
28405b261ecSmrg    WinKBLayoutPtr	pLayout;
28505b261ecSmrg    Bool                bfound = FALSE;
28605b261ecSmrg
28705b261ecSmrg    if (! layoutNum)
28805b261ecSmrg      layoutNum = strtoul (layoutName, (char **)NULL, 16);
28905b261ecSmrg    if ((layoutNum & 0xffff) == 0x411) {
29005b261ecSmrg        /* The japanese layouts know a lot of different IMEs which all have
29105b261ecSmrg	   different layout numbers set. Map them to a single entry.
29205b261ecSmrg	   Same might apply for chinese, korean and other symbol languages
29305b261ecSmrg	   too */
29405b261ecSmrg        layoutNum = (layoutNum & 0xffff);
29505b261ecSmrg	if (keyboardType == 7)
29605b261ecSmrg	  {
29705b261ecSmrg	    /* Japanese layouts have problems with key event messages
29805b261ecSmrg	       such as the lack of WM_KEYUP for Caps Lock key.
29905b261ecSmrg	       Loading US layout fixes this problem. */
30005b261ecSmrg	    if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL)
30105b261ecSmrg	      winMsg (X_INFO, "Loading US keyboard layout.\n");
30205b261ecSmrg	    else
3039ace9065Smrg	      winMsg (X_ERROR, "LoadKeyboardLayout failed.\n");
30405b261ecSmrg	  }
30505b261ecSmrg    }
3069ace9065Smrg
3079ace9065Smrg    /* Discover the friendly name of the current layout */
3089ace9065Smrg    {
3099ace9065Smrg      HKEY                regkey = NULL;
3109ace9065Smrg      const char          regtempl[] = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
3119ace9065Smrg      char                *regpath;
3129ace9065Smrg      DWORD               namesize = sizeof(layoutFriendlyName);
3139ace9065Smrg
3149ace9065Smrg      regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
3159ace9065Smrg      strcpy(regpath, regtempl);
3169ace9065Smrg      strcat(regpath, layoutName);
3179ace9065Smrg
3189ace9065Smrg      if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, &regkey))
3199ace9065Smrg          RegQueryValueEx(regkey, "Layout Text", 0, NULL, layoutFriendlyName, &namesize);
3209ace9065Smrg
3219ace9065Smrg      /* Close registry key */
3229ace9065Smrg      if (regkey)
3239ace9065Smrg        RegCloseKey (regkey);
3249ace9065Smrg      free(regpath);
3259ace9065Smrg    }
3269ace9065Smrg
3279ace9065Smrg    winMsg (X_PROBED, "Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n",
3289ace9065Smrg            layoutName, layoutNum, layoutFriendlyName, keyboardType);
32905b261ecSmrg
33005b261ecSmrg    for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++)
33105b261ecSmrg      {
33205b261ecSmrg	if (pLayout->winlayout != layoutNum)
33305b261ecSmrg	  continue;
33405b261ecSmrg	if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
33505b261ecSmrg	  continue;
3369ace9065Smrg
33705b261ecSmrg        bfound = TRUE;
33805b261ecSmrg	winMsg (X_PROBED,
3399ace9065Smrg		"Found matching XKB configuration \"%s\"\n",
3409ace9065Smrg		pLayout->layoutname);
3419ace9065Smrg
3429ace9065Smrg        winMsg(X_PROBED,
3439ace9065Smrg               "Model = \"%s\" Layout = \"%s\""
3449ace9065Smrg               " Variant = \"%s\" Options = \"%s\"\n",
3459ace9065Smrg               pLayout->xkbmodel ? pLayout->xkbmodel : "none",
3469ace9065Smrg               pLayout->xkblayout ? pLayout->xkblayout : "none",
3479ace9065Smrg               pLayout->xkbvariant ? pLayout->xkbvariant : "none",
3489ace9065Smrg               pLayout->xkboptions ? pLayout->xkboptions : "none");
3499ace9065Smrg
35005b261ecSmrg	g_winInfo.xkb.model = pLayout->xkbmodel;
35105b261ecSmrg	g_winInfo.xkb.layout = pLayout->xkblayout;
35205b261ecSmrg	g_winInfo.xkb.variant = pLayout->xkbvariant;
3539ace9065Smrg	g_winInfo.xkb.options = pLayout->xkboptions;
3549ace9065Smrg
3559ace9065Smrg
35605b261ecSmrg	break;
35705b261ecSmrg      }
3589ace9065Smrg
35905b261ecSmrg    if (!bfound)
36005b261ecSmrg      {
3619ace9065Smrg        winMsg (X_ERROR, "Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n", layoutFriendlyName, layoutName);
36205b261ecSmrg      }
3639ace9065Smrg  }
3649ace9065Smrg
36505b261ecSmrg  /* parse the configuration */
36605b261ecSmrg#ifdef XWIN_XF86CONFIG
36705b261ecSmrg  if (g_cmdline.keyboard)
36805b261ecSmrg    kbdfrom = X_CMDLINE;
36905b261ecSmrg
37005b261ecSmrg  /*
37105b261ecSmrg   * Until the layout code is finished, I search for the keyboard
37205b261ecSmrg   * device and configure the server with it.
37305b261ecSmrg   */
37405b261ecSmrg
37505b261ecSmrg  if (g_xf86configptr != NULL)
37605b261ecSmrg    input_list = g_xf86configptr->conf_input_lst;
37705b261ecSmrg
37805b261ecSmrg  while (input_list != NULL)
37905b261ecSmrg    {
38005b261ecSmrg      if (winNameCompare (input_list->inp_driver, "keyboard") == 0)
38105b261ecSmrg	{
38205b261ecSmrg	  /* Check if device name matches requested name */
38305b261ecSmrg	  if (g_cmdline.keyboard && winNameCompare (input_list->inp_identifier,
38405b261ecSmrg						    g_cmdline.keyboard))
38505b261ecSmrg	    continue;
38605b261ecSmrg	  kbd = input_list;
38705b261ecSmrg	}
38805b261ecSmrg      input_list = input_list->list.next;
38905b261ecSmrg    }
39005b261ecSmrg
39105b261ecSmrg  if (kbd != NULL)
39205b261ecSmrg    {
39305b261ecSmrg
39405b261ecSmrg      if (kbd->inp_identifier)
39505b261ecSmrg	winMsg (kbdfrom, "Using keyboard \"%s\" as primary keyboard\n",
39605b261ecSmrg		kbd->inp_identifier);
39705b261ecSmrg
39805b261ecSmrg      if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL)))
39905b261ecSmrg        {
40005b261ecSmrg          if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay,
40105b261ecSmrg                      &g_winInfo.keyboard.rate) != 2) ||
40205b261ecSmrg                  (g_winInfo.keyboard.delay < 1) ||
40305b261ecSmrg                  (g_winInfo.keyboard.rate == 0) ||
40405b261ecSmrg                  (1000 / g_winInfo.keyboard.rate) < 1)
40505b261ecSmrg            {
40605b261ecSmrg              winErrorFVerb (2, "\"%s\" is not a valid AutoRepeat value", s);
4076747b715Smrg              free(s);
40805b261ecSmrg              return FALSE;
40905b261ecSmrg            }
4106747b715Smrg          free(s);
41105b261ecSmrg          winMsg (X_CONFIG, "AutoRepeat: %ld %ld\n",
41205b261ecSmrg                  g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
41305b261ecSmrg        }
41405b261ecSmrg#endif
41505b261ecSmrg
4166747b715Smrg        s = NULL;
4176747b715Smrg        if (g_cmdline.xkbRules)
4186747b715Smrg          {
4196747b715Smrg            s = g_cmdline.xkbRules;
4206747b715Smrg            from = X_CMDLINE;
4216747b715Smrg          }
42205b261ecSmrg#ifdef XWIN_XF86CONFIG
4236747b715Smrg        else
4246747b715Smrg          {
4256747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbRules", NULL);
4266747b715Smrg            from = X_CONFIG;
4276747b715Smrg          }
42805b261ecSmrg#endif
4296747b715Smrg        if (s)
4306747b715Smrg          {
4316747b715Smrg            g_winInfo.xkb.rules = NULL_IF_EMPTY (s);
4326747b715Smrg            winMsg (from, "XKB: rules: \"%s\"\n", s);
4336747b715Smrg	  }
43405b261ecSmrg
4356747b715Smrg        s = NULL;
4366747b715Smrg        if (g_cmdline.xkbModel)
4376747b715Smrg          {
4386747b715Smrg            s = g_cmdline.xkbModel;
4396747b715Smrg            from = X_CMDLINE;
4406747b715Smrg          }
44105b261ecSmrg#ifdef XWIN_XF86CONFIG
4426747b715Smrg        else
4436747b715Smrg          {
4446747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbModel", NULL);
4456747b715Smrg            from = X_CONFIG;
4466747b715Smrg          }
44705b261ecSmrg#endif
4486747b715Smrg        if (s)
4496747b715Smrg	  {
4506747b715Smrg	    g_winInfo.xkb.model = NULL_IF_EMPTY (s);
4516747b715Smrg	    winMsg (from, "XKB: model: \"%s\"\n", s);
4526747b715Smrg	  }
45305b261ecSmrg
4546747b715Smrg        s = NULL;
4556747b715Smrg        if (g_cmdline.xkbLayout)
4566747b715Smrg          {
4576747b715Smrg            s = g_cmdline.xkbLayout;
4586747b715Smrg            from = X_CMDLINE;
4596747b715Smrg          }
46005b261ecSmrg#ifdef XWIN_XF86CONFIG
4616747b715Smrg        else
4626747b715Smrg          {
4636747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbLayout", NULL);
4646747b715Smrg            from = X_CONFIG;
4656747b715Smrg          }
46605b261ecSmrg#endif
4676747b715Smrg        if (s)
4686747b715Smrg          {
4696747b715Smrg	    g_winInfo.xkb.layout = NULL_IF_EMPTY (s);
4706747b715Smrg	    winMsg (from, "XKB: layout: \"%s\"\n", s);
4716747b715Smrg	  }
47205b261ecSmrg
4736747b715Smrg        s = NULL;
4746747b715Smrg        if (g_cmdline.xkbVariant)
4756747b715Smrg          {
4766747b715Smrg            s = g_cmdline.xkbVariant;
4776747b715Smrg            from = X_CMDLINE;
4786747b715Smrg          }
47905b261ecSmrg#ifdef XWIN_XF86CONFIG
4806747b715Smrg        else
4816747b715Smrg          {
4826747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbVariant", NULL);
4836747b715Smrg            from = X_CONFIG;
4846747b715Smrg          }
48505b261ecSmrg#endif
4866747b715Smrg	if (s)
4876747b715Smrg	  {
4886747b715Smrg	    g_winInfo.xkb.variant = NULL_IF_EMPTY (s);
4896747b715Smrg	    winMsg (from, "XKB: variant: \"%s\"\n", s);
4906747b715Smrg	  }
49105b261ecSmrg
4926747b715Smrg        s = NULL;
4936747b715Smrg        if (g_cmdline.xkbOptions)
4946747b715Smrg          {
4956747b715Smrg            s = g_cmdline.xkbOptions;
4966747b715Smrg            from = X_CMDLINE;
4976747b715Smrg          }
49805b261ecSmrg#ifdef XWIN_XF86CONFIG
4996747b715Smrg        else
5006747b715Smrg          {
5016747b715Smrg            s = winSetStrOption (kbd->inp_option_lst, "XkbOptions", NULL);
5026747b715Smrg            from = X_CONFIG;
5036747b715Smrg          }
50405b261ecSmrg#endif
5056747b715Smrg        if (s)
5066747b715Smrg	  {
5076747b715Smrg	    g_winInfo.xkb.options = NULL_IF_EMPTY (s);
5086747b715Smrg	    winMsg (from, "XKB: options: \"%s\"\n", s);
5096747b715Smrg	  }
51005b261ecSmrg
51105b261ecSmrg#ifdef XWIN_XF86CONFIG
51205b261ecSmrg    }
51305b261ecSmrg#endif
51405b261ecSmrg
51505b261ecSmrg  return TRUE;
51605b261ecSmrg}
51705b261ecSmrg
51805b261ecSmrg
51905b261ecSmrg#ifdef XWIN_XF86CONFIG
52005b261ecSmrgBool
52105b261ecSmrgwinConfigMouse (DeviceIntPtr pDevice)
52205b261ecSmrg{
52305b261ecSmrg  MessageType			mousefrom = X_CONFIG;
52405b261ecSmrg
52505b261ecSmrg  XF86ConfInputPtr		mouse = NULL;
52605b261ecSmrg  XF86ConfInputPtr		input_list = NULL;
52705b261ecSmrg
52805b261ecSmrg  if (g_cmdline.mouse)
52905b261ecSmrg    mousefrom = X_CMDLINE;
53005b261ecSmrg
53105b261ecSmrg  if (g_xf86configptr != NULL)
53205b261ecSmrg    input_list = g_xf86configptr->conf_input_lst;
53305b261ecSmrg
53405b261ecSmrg  while (input_list != NULL)
53505b261ecSmrg    {
53605b261ecSmrg      if (winNameCompare (input_list->inp_driver, "mouse") == 0)
53705b261ecSmrg	{
53805b261ecSmrg	  /* Check if device name matches requested name */
53905b261ecSmrg	  if (g_cmdline.mouse && winNameCompare (input_list->inp_identifier,
54005b261ecSmrg						 g_cmdline.mouse))
54105b261ecSmrg	    continue;
54205b261ecSmrg	  mouse = input_list;
54305b261ecSmrg	}
54405b261ecSmrg      input_list = input_list->list.next;
54505b261ecSmrg    }
54605b261ecSmrg
54705b261ecSmrg  if (mouse != NULL)
54805b261ecSmrg    {
54905b261ecSmrg      if (mouse->inp_identifier)
55005b261ecSmrg	winMsg (mousefrom, "Using pointer \"%s\" as primary pointer\n",
55105b261ecSmrg		mouse->inp_identifier);
55205b261ecSmrg
55305b261ecSmrg      g_winInfo.pointer.emulate3Buttons =
55405b261ecSmrg	winSetBoolOption (mouse->inp_option_lst, "Emulate3Buttons", FALSE);
55505b261ecSmrg      if (g_cmdline.emulate3buttons)
55605b261ecSmrg	g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons;
55705b261ecSmrg
55805b261ecSmrg      g_winInfo.pointer.emulate3Timeout =
55905b261ecSmrg	winSetIntOption (mouse->inp_option_lst, "Emulate3Timeout", 50);
56005b261ecSmrg      if (g_cmdline.emulate3timeout)
56105b261ecSmrg	g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout;
56205b261ecSmrg    }
56305b261ecSmrg  else
56405b261ecSmrg    {
56505b261ecSmrg      winMsg (X_ERROR, "No primary pointer configured\n");
56605b261ecSmrg      winMsg (X_DEFAULT, "Using compiletime defaults for pointer\n");
56705b261ecSmrg    }
56805b261ecSmrg
56905b261ecSmrg  return TRUE;
57005b261ecSmrg}
57105b261ecSmrg
57205b261ecSmrg
57305b261ecSmrgBool
57405b261ecSmrgwinConfigFiles ()
57505b261ecSmrg{
57605b261ecSmrg  MessageType from;
57705b261ecSmrg  XF86ConfFilesPtr filesptr = NULL;
57805b261ecSmrg
57905b261ecSmrg  /* set some shortcuts */
58005b261ecSmrg  if (g_xf86configptr != NULL)
58105b261ecSmrg    {
58205b261ecSmrg      filesptr = g_xf86configptr->conf_files;
58305b261ecSmrg    }
58405b261ecSmrg
58505b261ecSmrg
58605b261ecSmrg  /* Fontpath */
58705b261ecSmrg  from = X_DEFAULT;
58805b261ecSmrg
58905b261ecSmrg  if (g_cmdline.fontPath)
59005b261ecSmrg    {
59105b261ecSmrg      from = X_CMDLINE;
59205b261ecSmrg      defaultFontPath = g_cmdline.fontPath;
59305b261ecSmrg    }
59405b261ecSmrg  else if (filesptr != NULL && filesptr->file_fontpath)
59505b261ecSmrg    {
59605b261ecSmrg      from = X_CONFIG;
5976747b715Smrg      defaultFontPath = strdup (filesptr->file_fontpath);
59805b261ecSmrg    }
59905b261ecSmrg  winMsg (from, "FontPath set to \"%s\"\n", defaultFontPath);
60005b261ecSmrg
60105b261ecSmrg  return TRUE;
60205b261ecSmrg}
60305b261ecSmrg#else
60405b261ecSmrgBool
6056747b715SmrgwinConfigFiles (void)
60605b261ecSmrg{
60705b261ecSmrg  /* Fontpath */
60805b261ecSmrg  if (g_cmdline.fontPath)
60905b261ecSmrg    {
61005b261ecSmrg      defaultFontPath = g_cmdline.fontPath;
61105b261ecSmrg      winMsg (X_CMDLINE, "FontPath set to \"%s\"\n", defaultFontPath);
61205b261ecSmrg    }
61305b261ecSmrg
61405b261ecSmrg  return TRUE;
61505b261ecSmrg}
61605b261ecSmrg#endif
61705b261ecSmrg
61805b261ecSmrg
61905b261ecSmrgBool
6206747b715SmrgwinConfigOptions (void)
62105b261ecSmrg{
62205b261ecSmrg  return TRUE;
62305b261ecSmrg}
62405b261ecSmrg
62505b261ecSmrg
62605b261ecSmrgBool
6276747b715SmrgwinConfigScreens (void)
62805b261ecSmrg{
62905b261ecSmrg  return TRUE;
63005b261ecSmrg}
63105b261ecSmrg
63205b261ecSmrg
63305b261ecSmrg#ifdef XWIN_XF86CONFIG
63405b261ecSmrgchar *
63505b261ecSmrgwinSetStrOption (pointer optlist, const char *name, char *deflt)
63605b261ecSmrg{
63705b261ecSmrg  OptionInfoRec o;
63805b261ecSmrg
63905b261ecSmrg  o.name = name;
64005b261ecSmrg  o.type = OPTV_STRING;
64105b261ecSmrg  if (ParseOptionValue (-1, optlist, &o))
64205b261ecSmrg    deflt = o.value.str;
64305b261ecSmrg  if (deflt)
6446747b715Smrg    return strdup (deflt);
64505b261ecSmrg  else
64605b261ecSmrg    return NULL;
64705b261ecSmrg}
64805b261ecSmrg
64905b261ecSmrg
65005b261ecSmrgint
65105b261ecSmrgwinSetBoolOption (pointer optlist, const char *name, int deflt)
65205b261ecSmrg{
65305b261ecSmrg  OptionInfoRec o;
65405b261ecSmrg
65505b261ecSmrg  o.name = name;
65605b261ecSmrg  o.type = OPTV_BOOLEAN;
65705b261ecSmrg  if (ParseOptionValue (-1, optlist, &o))
65805b261ecSmrg    deflt = o.value.bool;
65905b261ecSmrg  return deflt;
66005b261ecSmrg}
66105b261ecSmrg
66205b261ecSmrg
66305b261ecSmrgint
66405b261ecSmrgwinSetIntOption (pointer optlist, const char *name, int deflt)
66505b261ecSmrg{
66605b261ecSmrg  OptionInfoRec o;
66705b261ecSmrg
66805b261ecSmrg  o.name = name;
66905b261ecSmrg  o.type = OPTV_INTEGER;
67005b261ecSmrg  if (ParseOptionValue (-1, optlist, &o))
67105b261ecSmrg    deflt = o.value.num;
67205b261ecSmrg  return deflt;
67305b261ecSmrg}
67405b261ecSmrg
67505b261ecSmrg
67605b261ecSmrgdouble
67705b261ecSmrgwinSetRealOption (pointer optlist, const char *name, double deflt)
67805b261ecSmrg{
67905b261ecSmrg  OptionInfoRec o;
68005b261ecSmrg
68105b261ecSmrg  o.name = name;
68205b261ecSmrg  o.type = OPTV_REAL;
68305b261ecSmrg  if (ParseOptionValue (-1, optlist, &o))
68405b261ecSmrg    deflt = o.value.realnum;
68505b261ecSmrg  return deflt;
68605b261ecSmrg}
6876747b715Smrg
6886747b715Smrgdouble
6896747b715SmrgwinSetPercentOption (pointer optlist, const char *name, double deflt)
6906747b715Smrg{
6916747b715Smrg  OptionInfoRec o;
6926747b715Smrg
6936747b715Smrg  o.name = name;
6946747b715Smrg  o.type = OPTV_PERCENT;
6956747b715Smrg  if (ParseOptionValue (-1, optlist, &o))
6966747b715Smrg    deflt = o.value.realnum;
6976747b715Smrg  return deflt;
6986747b715Smrg}
69905b261ecSmrg#endif
70005b261ecSmrg
70105b261ecSmrg
70205b261ecSmrg/*
70305b261ecSmrg * Compare two strings for equality. This is caseinsensitive  and
70405b261ecSmrg * The characters '_', ' ' (space) and '\t' (tab) are treated as
70505b261ecSmrg * not existing.
70605b261ecSmrg */
70705b261ecSmrg
70805b261ecSmrgint
70905b261ecSmrgwinNameCompare (const char *s1, const char *s2)
71005b261ecSmrg{
71105b261ecSmrg  char c1, c2;
71205b261ecSmrg
71305b261ecSmrg  if (!s1 || *s1 == 0)
71405b261ecSmrg    {
71505b261ecSmrg      if (!s2 || *s2 == 0)
71605b261ecSmrg	return 0;
71705b261ecSmrg      else
71805b261ecSmrg	return 1;
71905b261ecSmrg    }
72005b261ecSmrg
72105b261ecSmrg  while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
72205b261ecSmrg    s1++;
72305b261ecSmrg  while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
72405b261ecSmrg    s2++;
72505b261ecSmrg
7269ace9065Smrg  c1 = (isupper ((int)*s1) ? tolower ((int)*s1) : *s1);
7279ace9065Smrg  c2 = (isupper ((int)*s2) ? tolower ((int)*s2) : *s2);
72805b261ecSmrg
72905b261ecSmrg  while (c1 == c2)
73005b261ecSmrg    {
73105b261ecSmrg      if (c1 == 0)
73205b261ecSmrg	return 0;
73305b261ecSmrg      s1++;
73405b261ecSmrg      s2++;
73505b261ecSmrg
73605b261ecSmrg      while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
73705b261ecSmrg	s1++;
73805b261ecSmrg      while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
73905b261ecSmrg	s2++;
74005b261ecSmrg
7419ace9065Smrg      c1 = (isupper ((int)*s1) ? tolower ((int)*s1) : *s1);
7429ace9065Smrg      c2 = (isupper ((int)*s2) ? tolower ((int)*s2) : *s2);
74305b261ecSmrg    }
7446747b715Smrg  return c1 - c2;
74505b261ecSmrg}
74605b261ecSmrg
74705b261ecSmrg
74805b261ecSmrg#ifdef XWIN_XF86CONFIG
74905b261ecSmrg/*
75005b261ecSmrg * Find the named option in the list.
75105b261ecSmrg * @return the pointer to the option record, or NULL if not found.
75205b261ecSmrg */
75305b261ecSmrg
75405b261ecSmrgXF86OptionPtr
75505b261ecSmrgwinFindOption (XF86OptionPtr list, const char *name)
75605b261ecSmrg{
75705b261ecSmrg  while (list)
75805b261ecSmrg    {
75905b261ecSmrg      if (winNameCompare (list->opt_name, name) == 0)
76005b261ecSmrg	return list;
76105b261ecSmrg      list = list->list.next;
76205b261ecSmrg    }
76305b261ecSmrg  return NULL;
76405b261ecSmrg}
76505b261ecSmrg
76605b261ecSmrg
76705b261ecSmrg/*
76805b261ecSmrg * Find the Value of an named option.
76905b261ecSmrg * @return The option value or NULL if not found.
77005b261ecSmrg */
77105b261ecSmrg
77205b261ecSmrgchar *
77305b261ecSmrgwinFindOptionValue (XF86OptionPtr list, const char *name)
77405b261ecSmrg{
77505b261ecSmrg  list = winFindOption (list, name);
77605b261ecSmrg  if (list)
77705b261ecSmrg    {
77805b261ecSmrg      if (list->opt_val)
7796747b715Smrg	return list->opt_val;
78005b261ecSmrg      else
78105b261ecSmrg	return "";
78205b261ecSmrg    }
7836747b715Smrg  return NULL;
78405b261ecSmrg}
78505b261ecSmrg
78605b261ecSmrg
78705b261ecSmrg/*
78805b261ecSmrg * Parse the option.
78905b261ecSmrg */
79005b261ecSmrg
79105b261ecSmrgstatic Bool
79205b261ecSmrgParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p)
79305b261ecSmrg{
79405b261ecSmrg  char *s, *end;
79505b261ecSmrg
79605b261ecSmrg  if ((s = winFindOptionValue (options, p->name)) != NULL)
79705b261ecSmrg    {
79805b261ecSmrg      switch (p->type)
79905b261ecSmrg	{
80005b261ecSmrg	case OPTV_INTEGER:
80105b261ecSmrg	  if (*s == '\0')
80205b261ecSmrg	    {
80305b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
80405b261ecSmrg			 "Option \"%s\" requires an integer value\n",
80505b261ecSmrg			 p->name);
80605b261ecSmrg	      p->found = FALSE;
80705b261ecSmrg	    }
80805b261ecSmrg	  else
80905b261ecSmrg	    {
81005b261ecSmrg	      p->value.num = strtoul (s, &end, 0);
81105b261ecSmrg	      if (*end == '\0')
81205b261ecSmrg		{
81305b261ecSmrg		  p->found = TRUE;
81405b261ecSmrg		}
81505b261ecSmrg	      else
81605b261ecSmrg		{
81705b261ecSmrg		  winDrvMsg (scrnIndex, X_WARNING,
81805b261ecSmrg			     "Option \"%s\" requires an integer value\n",
81905b261ecSmrg			     p->name);
82005b261ecSmrg		  p->found = FALSE;
82105b261ecSmrg		}
82205b261ecSmrg	    }
82305b261ecSmrg	  break;
82405b261ecSmrg	case OPTV_STRING:
82505b261ecSmrg	  if (*s == '\0')
82605b261ecSmrg	    {
82705b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
82805b261ecSmrg			 "Option \"%s\" requires an string value\n", p->name);
82905b261ecSmrg	      p->found = FALSE;
83005b261ecSmrg	    }
83105b261ecSmrg	  else
83205b261ecSmrg	    {
83305b261ecSmrg	      p->value.str = s;
83405b261ecSmrg	      p->found = TRUE;
83505b261ecSmrg	    }
83605b261ecSmrg	  break;
83705b261ecSmrg	case OPTV_ANYSTR:
83805b261ecSmrg	  p->value.str = s;
83905b261ecSmrg	  p->found = TRUE;
84005b261ecSmrg	  break;
84105b261ecSmrg	case OPTV_REAL:
84205b261ecSmrg	  if (*s == '\0')
84305b261ecSmrg	    {
84405b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
84505b261ecSmrg			 "Option \"%s\" requires a floating point value\n",
84605b261ecSmrg			 p->name);
84705b261ecSmrg	      p->found = FALSE;
84805b261ecSmrg	    }
84905b261ecSmrg	  else
85005b261ecSmrg	    {
85105b261ecSmrg	      p->value.realnum = strtod (s, &end);
85205b261ecSmrg	      if (*end == '\0')
85305b261ecSmrg		{
85405b261ecSmrg		  p->found = TRUE;
85505b261ecSmrg		}
85605b261ecSmrg	      else
85705b261ecSmrg		{
85805b261ecSmrg		  winDrvMsg (scrnIndex, X_WARNING,
85905b261ecSmrg			     "Option \"%s\" requires a floating point value\n",
86005b261ecSmrg			     p->name);
86105b261ecSmrg		  p->found = FALSE;
86205b261ecSmrg		}
86305b261ecSmrg	    }
86405b261ecSmrg	  break;
86505b261ecSmrg	case OPTV_BOOLEAN:
86605b261ecSmrg	  if (GetBoolValue (p, s))
86705b261ecSmrg	    {
86805b261ecSmrg	      p->found = TRUE;
86905b261ecSmrg	    }
87005b261ecSmrg	  else
87105b261ecSmrg	    {
87205b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
87305b261ecSmrg			 "Option \"%s\" requires a boolean value\n", p->name);
87405b261ecSmrg	      p->found = FALSE;
87505b261ecSmrg	    }
87605b261ecSmrg	  break;
8776747b715Smrg	case OPTV_PERCENT:
8786747b715Smrg	  if (*s == '\0')
8796747b715Smrg	    {
8806747b715Smrg	      winDrvMsg (scrnIndex, X_WARNING,
8816747b715Smrg			 "Option \"%s\" requires a percent value\n",
8826747b715Smrg			 p->name);
8836747b715Smrg	      p->found = FALSE;
8846747b715Smrg	    }
8856747b715Smrg	  else
8866747b715Smrg	    {
8876747b715Smrg	       double percent = strtod (s, &end);
8886747b715Smrg
8896747b715Smrg	       if (end != s && winNameCompare (end, "%"))
8906747b715Smrg		 {
8916747b715Smrg		   p->found = TRUE;
8926747b715Smrg		   p->value.realnum = percent;
8936747b715Smrg		 }
8946747b715Smrg	       else
8956747b715Smrg		 {
8966747b715Smrg		   winDrvMsg (scrnIndex, X_WARNING,
8976747b715Smrg			      "Option \"%s\" requires a frequency value\n",
8986747b715Smrg			       p->name);
8996747b715Smrg		   p->found = FALSE;
9006747b715Smrg		 }
9016747b715Smrg	    }
90205b261ecSmrg	case OPTV_FREQ:
90305b261ecSmrg	  if (*s == '\0')
90405b261ecSmrg	    {
90505b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
90605b261ecSmrg			 "Option \"%s\" requires a frequency value\n",
90705b261ecSmrg			 p->name);
90805b261ecSmrg	      p->found = FALSE;
90905b261ecSmrg	    }
91005b261ecSmrg	  else
91105b261ecSmrg	    {
91205b261ecSmrg	      double freq = strtod (s, &end);
91305b261ecSmrg	      int units = 0;
91405b261ecSmrg
91505b261ecSmrg	      if (end != s)
91605b261ecSmrg		{
91705b261ecSmrg		  p->found = TRUE;
91805b261ecSmrg		  if (!winNameCompare (end, "Hz"))
91905b261ecSmrg		    units = 1;
92005b261ecSmrg		  else if (!winNameCompare (end, "kHz") ||
92105b261ecSmrg			   !winNameCompare (end, "k"))
92205b261ecSmrg		    units = 1000;
92305b261ecSmrg		  else if (!winNameCompare (end, "MHz") ||
92405b261ecSmrg			   !winNameCompare (end, "M"))
92505b261ecSmrg		    units = 1000000;
92605b261ecSmrg		  else
92705b261ecSmrg		    {
92805b261ecSmrg		      winDrvMsg (scrnIndex, X_WARNING,
92905b261ecSmrg				 "Option \"%s\" requires a frequency value\n",
93005b261ecSmrg				 p->name);
93105b261ecSmrg		      p->found = FALSE;
93205b261ecSmrg		    }
93305b261ecSmrg		  if (p->found)
93405b261ecSmrg		    freq *= (double) units;
93505b261ecSmrg		}
93605b261ecSmrg	      else
93705b261ecSmrg		{
93805b261ecSmrg		  winDrvMsg (scrnIndex, X_WARNING,
93905b261ecSmrg			     "Option \"%s\" requires a frequency value\n",
94005b261ecSmrg			     p->name);
94105b261ecSmrg		  p->found = FALSE;
94205b261ecSmrg		}
94305b261ecSmrg	      if (p->found)
94405b261ecSmrg		{
94505b261ecSmrg		  p->value.freq.freq = freq;
94605b261ecSmrg		  p->value.freq.units = units;
94705b261ecSmrg		}
94805b261ecSmrg	    }
94905b261ecSmrg	  break;
95005b261ecSmrg	case OPTV_NONE:
95105b261ecSmrg	  /* Should never get here */
95205b261ecSmrg	  p->found = FALSE;
95305b261ecSmrg	  break;
95405b261ecSmrg	}
95505b261ecSmrg      if (p->found)
95605b261ecSmrg	{
95705b261ecSmrg	  winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", p->name);
95805b261ecSmrg	  if (!(p->type == OPTV_BOOLEAN && *s == 0))
95905b261ecSmrg	    {
96005b261ecSmrg	      winErrorFVerb (2, " \"%s\"", s);
96105b261ecSmrg	    }
96205b261ecSmrg	  winErrorFVerb (2, "\n");
96305b261ecSmrg	}
96405b261ecSmrg    }
96505b261ecSmrg  else if (p->type == OPTV_BOOLEAN)
96605b261ecSmrg    {
96705b261ecSmrg      /* Look for matches with options with or without a "No" prefix. */
96805b261ecSmrg      char *n, *newn;
96905b261ecSmrg      OptionInfoRec opt;
97005b261ecSmrg
97105b261ecSmrg      n = winNormalizeName (p->name);
97205b261ecSmrg      if (!n)
97305b261ecSmrg	{
97405b261ecSmrg	  p->found = FALSE;
97505b261ecSmrg	  return FALSE;
97605b261ecSmrg	}
97705b261ecSmrg      if (strncmp (n, "no", 2) == 0)
97805b261ecSmrg	{
97905b261ecSmrg	  newn = n + 2;
98005b261ecSmrg	}
98105b261ecSmrg      else
98205b261ecSmrg	{
98305b261ecSmrg	  free (n);
98405b261ecSmrg	  n = malloc (strlen (p->name) + 2 + 1);
98505b261ecSmrg	  if (!n)
98605b261ecSmrg	    {
98705b261ecSmrg	      p->found = FALSE;
98805b261ecSmrg	      return FALSE;
98905b261ecSmrg	    }
99005b261ecSmrg	  strcpy (n, "No");
99105b261ecSmrg	  strcat (n, p->name);
99205b261ecSmrg	  newn = n;
99305b261ecSmrg	}
99405b261ecSmrg      if ((s = winFindOptionValue (options, newn)) != NULL)
99505b261ecSmrg	{
99605b261ecSmrg	  if (GetBoolValue (&opt, s))
99705b261ecSmrg	    {
99805b261ecSmrg	      p->value.bool = !opt.value.bool;
99905b261ecSmrg	      p->found = TRUE;
100005b261ecSmrg	    }
100105b261ecSmrg	  else
100205b261ecSmrg	    {
100305b261ecSmrg	      winDrvMsg (scrnIndex, X_WARNING,
100405b261ecSmrg			 "Option \"%s\" requires a boolean value\n", newn);
100505b261ecSmrg	      p->found = FALSE;
100605b261ecSmrg	    }
100705b261ecSmrg	}
100805b261ecSmrg      else
100905b261ecSmrg	{
101005b261ecSmrg	  p->found = FALSE;
101105b261ecSmrg	}
101205b261ecSmrg      if (p->found)
101305b261ecSmrg	{
101405b261ecSmrg	  winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
101505b261ecSmrg	  if (*s != 0)
101605b261ecSmrg	    {
101705b261ecSmrg	      winErrorFVerb (2, " \"%s\"", s);
101805b261ecSmrg	    }
101905b261ecSmrg	  winErrorFVerb (2, "\n");
102005b261ecSmrg	}
102105b261ecSmrg      free (n);
102205b261ecSmrg    }
102305b261ecSmrg  else
102405b261ecSmrg    {
102505b261ecSmrg      p->found = FALSE;
102605b261ecSmrg    }
102705b261ecSmrg  return p->found;
102805b261ecSmrg}
102905b261ecSmrg
103005b261ecSmrg
103105b261ecSmrgstatic Bool
103205b261ecSmrgconfigLayout (serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
103305b261ecSmrg	      char *default_layout)
103405b261ecSmrg{
103505b261ecSmrg#if 0
103605b261ecSmrg#pragma warn UNIMPLEMENTED
103705b261ecSmrg#endif
103805b261ecSmrg  return TRUE;
103905b261ecSmrg}
104005b261ecSmrg
104105b261ecSmrg
104205b261ecSmrgstatic Bool
104305b261ecSmrgconfigImpliedLayout (serverLayoutPtr servlayoutp,
104405b261ecSmrg		     XF86ConfScreenPtr conf_screen)
104505b261ecSmrg{
104605b261ecSmrg#if 0
104705b261ecSmrg#pragma warn UNIMPLEMENTED
104805b261ecSmrg#endif
104905b261ecSmrg  return TRUE;
105005b261ecSmrg}
105105b261ecSmrg
105205b261ecSmrg
105305b261ecSmrgstatic Bool
105405b261ecSmrgGetBoolValue (OptionInfoPtr p, const char *s)
105505b261ecSmrg{
105605b261ecSmrg  if (*s == 0)
105705b261ecSmrg    {
105805b261ecSmrg      p->value.bool = TRUE;
105905b261ecSmrg    }
106005b261ecSmrg  else
106105b261ecSmrg    {
106205b261ecSmrg      if (winNameCompare (s, "1") == 0)
106305b261ecSmrg	p->value.bool = TRUE;
106405b261ecSmrg      else if (winNameCompare (s, "on") == 0)
106505b261ecSmrg	p->value.bool = TRUE;
106605b261ecSmrg      else if (winNameCompare (s, "true") == 0)
106705b261ecSmrg	p->value.bool = TRUE;
106805b261ecSmrg      else if (winNameCompare (s, "yes") == 0)
106905b261ecSmrg	p->value.bool = TRUE;
107005b261ecSmrg      else if (winNameCompare (s, "0") == 0)
107105b261ecSmrg	p->value.bool = FALSE;
107205b261ecSmrg      else if (winNameCompare (s, "off") == 0)
107305b261ecSmrg	p->value.bool = FALSE;
107405b261ecSmrg      else if (winNameCompare (s, "false") == 0)
107505b261ecSmrg	p->value.bool = FALSE;
107605b261ecSmrg      else if (winNameCompare (s, "no") == 0)
107705b261ecSmrg	p->value.bool = FALSE;
107805b261ecSmrg    }
107905b261ecSmrg  return TRUE;
108005b261ecSmrg}
108105b261ecSmrg#endif
108205b261ecSmrg
108305b261ecSmrg
108405b261ecSmrgchar *
108505b261ecSmrgwinNormalizeName (const char *s)
108605b261ecSmrg{
108705b261ecSmrg  char *ret, *q;
108805b261ecSmrg  const char *p;
108905b261ecSmrg
109005b261ecSmrg  if (s == NULL)
109105b261ecSmrg    return NULL;
109205b261ecSmrg
109305b261ecSmrg  ret = malloc (strlen (s) + 1);
109405b261ecSmrg  for (p = s, q = ret; *p != 0; p++)
109505b261ecSmrg    {
109605b261ecSmrg      switch (*p)
109705b261ecSmrg	{
109805b261ecSmrg	case '_':
109905b261ecSmrg	case ' ':
110005b261ecSmrg	case '\t':
110105b261ecSmrg	  continue;
110205b261ecSmrg	default:
11039ace9065Smrg	  if (isupper ((int)*p))
11049ace9065Smrg	    *q++ = tolower ((int)*p);
110505b261ecSmrg	  else
110605b261ecSmrg	    *q++ = *p;
110705b261ecSmrg	}
110805b261ecSmrg    }
110905b261ecSmrg  *q = '\0';
111005b261ecSmrg  return ret;
111105b261ecSmrg}
111205b261ecSmrg
1113