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