xref: /OK3568_Linux_fs/external/xserver/hw/xwin/winconfig.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  *Permission is hereby granted, free of charge, to any person obtaining
5*4882a593Smuzhiyun  * a copy of this software and associated documentation files (the
6*4882a593Smuzhiyun  *"Software"), to deal in the Software without restriction, including
7*4882a593Smuzhiyun  *without limitation the rights to use, copy, modify, merge, publish,
8*4882a593Smuzhiyun  *distribute, sublicense, and/or sell copies of the Software, and to
9*4882a593Smuzhiyun  *permit persons to whom the Software is furnished to do so, subject to
10*4882a593Smuzhiyun  *the following conditions:
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  *The above copyright notice and this permission notice shall be
13*4882a593Smuzhiyun  *included in all copies or substantial portions of the Software.
14*4882a593Smuzhiyun  *
15*4882a593Smuzhiyun  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*4882a593Smuzhiyun  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*4882a593Smuzhiyun  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*4882a593Smuzhiyun  *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19*4882a593Smuzhiyun  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20*4882a593Smuzhiyun  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21*4882a593Smuzhiyun  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  *Except as contained in this notice, the name of the XFree86 Project
24*4882a593Smuzhiyun  *shall not be used in advertising or otherwise to promote the sale, use
25*4882a593Smuzhiyun  *or other dealings in this Software without prior written authorization
26*4882a593Smuzhiyun  *from the XFree86 Project.
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * Authors: Alexander Gottwald
29*4882a593Smuzhiyun  */
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #ifdef HAVE_XWIN_CONFIG_H
32*4882a593Smuzhiyun #include <xwin-config.h>
33*4882a593Smuzhiyun #endif
34*4882a593Smuzhiyun #include "win.h"
35*4882a593Smuzhiyun #include "winconfig.h"
36*4882a593Smuzhiyun #include "winmsg.h"
37*4882a593Smuzhiyun #include "globals.h"
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #include "xkbsrv.h"
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
42*4882a593Smuzhiyun #ifndef CONFIGPATH
43*4882a593Smuzhiyun #define CONFIGPATH  "%A," "%R," \
44*4882a593Smuzhiyun                     "/etc/X11/%R," "%P/etc/X11/%R," \
45*4882a593Smuzhiyun                     "%E," "%F," \
46*4882a593Smuzhiyun                     "/etc/X11/%F," "%P/etc/X11/%F," \
47*4882a593Smuzhiyun                     "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
48*4882a593Smuzhiyun                     "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
49*4882a593Smuzhiyun                     "%P/etc/X11/%X," \
50*4882a593Smuzhiyun                     "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
51*4882a593Smuzhiyun                     "%P/lib/X11/%X"
52*4882a593Smuzhiyun #endif
53*4882a593Smuzhiyun #ifndef CONFIGDIRPATH
54*4882a593Smuzhiyun #define CONFIGDIRPATH  "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
55*4882a593Smuzhiyun                        "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
56*4882a593Smuzhiyun                        "%P/etc/X11/%X," \
57*4882a593Smuzhiyun                        "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
58*4882a593Smuzhiyun                        "%P/lib/X11/%X"
59*4882a593Smuzhiyun #endif
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun XF86ConfigPtr g_xf86configptr = NULL;
62*4882a593Smuzhiyun #endif
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun WinCmdlineRec g_cmdline = {
65*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
66*4882a593Smuzhiyun     NULL,                       /* configFile */
67*4882a593Smuzhiyun     NULL,                       /* configDir */
68*4882a593Smuzhiyun #endif
69*4882a593Smuzhiyun     NULL,                       /* fontPath */
70*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
71*4882a593Smuzhiyun     NULL,                       /* keyboard */
72*4882a593Smuzhiyun #endif
73*4882a593Smuzhiyun     NULL,                       /* xkbRules */
74*4882a593Smuzhiyun     NULL,                       /* xkbModel */
75*4882a593Smuzhiyun     NULL,                       /* xkbLayout */
76*4882a593Smuzhiyun     NULL,                       /* xkbVariant */
77*4882a593Smuzhiyun     NULL,                       /* xkbOptions */
78*4882a593Smuzhiyun     NULL,                       /* screenname */
79*4882a593Smuzhiyun     NULL,                       /* mousename */
80*4882a593Smuzhiyun     FALSE,                      /* emulate3Buttons */
81*4882a593Smuzhiyun     0                           /* emulate3Timeout */
82*4882a593Smuzhiyun };
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun winInfoRec g_winInfo = {
85*4882a593Smuzhiyun     {                           /* keyboard */
86*4882a593Smuzhiyun      0,                         /* leds */
87*4882a593Smuzhiyun      500,                       /* delay */
88*4882a593Smuzhiyun      30                         /* rate */
89*4882a593Smuzhiyun      }
90*4882a593Smuzhiyun     ,
91*4882a593Smuzhiyun     {                           /* xkb */
92*4882a593Smuzhiyun      NULL,                      /* rules */
93*4882a593Smuzhiyun      NULL,                      /* model */
94*4882a593Smuzhiyun      NULL,                      /* layout */
95*4882a593Smuzhiyun      NULL,                      /* variant */
96*4882a593Smuzhiyun      NULL,                      /* options */
97*4882a593Smuzhiyun      }
98*4882a593Smuzhiyun     ,
99*4882a593Smuzhiyun     {
100*4882a593Smuzhiyun      FALSE,
101*4882a593Smuzhiyun      50}
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun #define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL)
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
107*4882a593Smuzhiyun serverLayoutRec g_winConfigLayout;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun static Bool ParseOptionValue(int scrnIndex, void *options, OptionInfoPtr p);
110*4882a593Smuzhiyun static Bool configLayout(serverLayoutPtr, XF86ConfLayoutPtr, char *);
111*4882a593Smuzhiyun static Bool configImpliedLayout(serverLayoutPtr, XF86ConfScreenPtr);
112*4882a593Smuzhiyun static Bool GetBoolValue(OptionInfoPtr p, const char *s);
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun Bool
winReadConfigfile()115*4882a593Smuzhiyun winReadConfigfile()
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun     Bool retval = TRUE;
118*4882a593Smuzhiyun     char *filename, *dirname;
119*4882a593Smuzhiyun     MessageType filefrom = X_DEFAULT;
120*4882a593Smuzhiyun     MessageType dirfrom = X_DEFAULT;
121*4882a593Smuzhiyun     char *xf86ConfigFile = NULL;
122*4882a593Smuzhiyun     char *xf86ConfigDir = NULL;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun     if (g_cmdline.configFile) {
125*4882a593Smuzhiyun         filefrom = X_CMDLINE;
126*4882a593Smuzhiyun         xf86ConfigFile = g_cmdline.configFile;
127*4882a593Smuzhiyun     }
128*4882a593Smuzhiyun     if (g_cmdline.configDir) {
129*4882a593Smuzhiyun         dirfrom = X_CMDLINE;
130*4882a593Smuzhiyun         xf86ConfigDir = g_cmdline.configDir;
131*4882a593Smuzhiyun     }
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun     /* Parse config file into data structure */
134*4882a593Smuzhiyun     xf86initConfigFiles();
135*4882a593Smuzhiyun     dirname = xf86openConfigDirFiles(CONFIGDIRPATH, xf86ConfigDir, PROJECTROOT);
136*4882a593Smuzhiyun     filename = xf86openConfigFile(CONFIGPATH, xf86ConfigFile, PROJECTROOT);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun     /* Hack for backward compatibility */
139*4882a593Smuzhiyun     if (!filename && from == X_DEFAULT)
140*4882a593Smuzhiyun         filename = xf86openConfigFile(CONFIGPATH, "XF86Config", PROJECTROOT);
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun     if (filename) {
143*4882a593Smuzhiyun         winMsg(from, "Using config file: \"%s\"\n", filename);
144*4882a593Smuzhiyun     }
145*4882a593Smuzhiyun     else {
146*4882a593Smuzhiyun         winMsg(X_ERROR, "Unable to locate/open config file");
147*4882a593Smuzhiyun         if (xf86ConfigFile)
148*4882a593Smuzhiyun             ErrorF(": \"%s\"", xf86ConfigFile);
149*4882a593Smuzhiyun         ErrorF("\n");
150*4882a593Smuzhiyun     }
151*4882a593Smuzhiyun     if (dirname) {
152*4882a593Smuzhiyun         winMsg(from, "Using config directory: \"%s\"\n", dirname);
153*4882a593Smuzhiyun     }
154*4882a593Smuzhiyun     else {
155*4882a593Smuzhiyun         winMsg(X_ERROR, "Unable to locate/open config directory");
156*4882a593Smuzhiyun         if (xf86ConfigDir)
157*4882a593Smuzhiyun             ErrorF(": \"%s\"", xf86ConfigDir);
158*4882a593Smuzhiyun         ErrorF("\n");
159*4882a593Smuzhiyun     }
160*4882a593Smuzhiyun     if (!filename && !dirname) {
161*4882a593Smuzhiyun         return FALSE;
162*4882a593Smuzhiyun     }
163*4882a593Smuzhiyun     free(filename);
164*4882a593Smuzhiyun     free(dirname);
165*4882a593Smuzhiyun     if ((g_xf86configptr = xf86readConfigFile()) == NULL) {
166*4882a593Smuzhiyun         winMsg(X_ERROR, "Problem parsing the config file\n");
167*4882a593Smuzhiyun         return FALSE;
168*4882a593Smuzhiyun     }
169*4882a593Smuzhiyun     xf86closeConfigFile();
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun     LogPrintMarkers();
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun     /* set options from data structure */
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun     if (g_xf86configptr->conf_layout_lst == NULL ||
176*4882a593Smuzhiyun         g_cmdline.screenname != NULL) {
177*4882a593Smuzhiyun         if (g_cmdline.screenname == NULL) {
178*4882a593Smuzhiyun             winMsg(X_WARNING,
179*4882a593Smuzhiyun                    "No Layout section. Using the first Screen section.\n");
180*4882a593Smuzhiyun         }
181*4882a593Smuzhiyun         if (!configImpliedLayout(&g_winConfigLayout,
182*4882a593Smuzhiyun                                  g_xf86configptr->conf_screen_lst)) {
183*4882a593Smuzhiyun             winMsg(X_ERROR, "Unable to determine the screen layout\n");
184*4882a593Smuzhiyun             return FALSE;
185*4882a593Smuzhiyun         }
186*4882a593Smuzhiyun     }
187*4882a593Smuzhiyun     else {
188*4882a593Smuzhiyun         /* Check if layout is given in the config file */
189*4882a593Smuzhiyun         if (g_xf86configptr->conf_flags != NULL) {
190*4882a593Smuzhiyun             char *dfltlayout = NULL;
191*4882a593Smuzhiyun             void *optlist = g_xf86configptr->conf_flags->flg_option_lst;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun             if (optlist && winFindOption(optlist, "defaultserverlayout"))
194*4882a593Smuzhiyun                 dfltlayout =
195*4882a593Smuzhiyun                     winSetStrOption(optlist, "defaultserverlayout", NULL);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun             if (!configLayout(&g_winConfigLayout,
198*4882a593Smuzhiyun                               g_xf86configptr->conf_layout_lst, dfltlayout)) {
199*4882a593Smuzhiyun                 winMsg(X_ERROR, "Unable to determine the screen layout\n");
200*4882a593Smuzhiyun                 return FALSE;
201*4882a593Smuzhiyun             }
202*4882a593Smuzhiyun         }
203*4882a593Smuzhiyun         else {
204*4882a593Smuzhiyun             if (!configLayout(&g_winConfigLayout,
205*4882a593Smuzhiyun                               g_xf86configptr->conf_layout_lst, NULL)) {
206*4882a593Smuzhiyun                 winMsg(X_ERROR, "Unable to determine the screen layout\n");
207*4882a593Smuzhiyun                 return FALSE;
208*4882a593Smuzhiyun             }
209*4882a593Smuzhiyun         }
210*4882a593Smuzhiyun     }
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun     /* setup special config files */
213*4882a593Smuzhiyun     winConfigFiles();
214*4882a593Smuzhiyun     return retval;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun #endif
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun /* load layout definitions */
219*4882a593Smuzhiyun #include "winlayouts.h"
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun /* Set the keyboard configuration */
222*4882a593Smuzhiyun Bool
winConfigKeyboard(DeviceIntPtr pDevice)223*4882a593Smuzhiyun winConfigKeyboard(DeviceIntPtr pDevice)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun     char layoutName[KL_NAMELENGTH];
226*4882a593Smuzhiyun     unsigned char layoutFriendlyName[256];
227*4882a593Smuzhiyun     unsigned int layoutNum = 0;
228*4882a593Smuzhiyun     unsigned int deviceIdentifier = 0;
229*4882a593Smuzhiyun     int keyboardType;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
232*4882a593Smuzhiyun     XF86ConfInputPtr kbd = NULL;
233*4882a593Smuzhiyun     XF86ConfInputPtr input_list = NULL;
234*4882a593Smuzhiyun     MessageType kbdfrom = X_CONFIG;
235*4882a593Smuzhiyun #endif
236*4882a593Smuzhiyun     MessageType from = X_DEFAULT;
237*4882a593Smuzhiyun     char *s = NULL;
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun     /* Setup defaults */
240*4882a593Smuzhiyun     XkbGetRulesDflts(&g_winInfo.xkb);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun     /*
243*4882a593Smuzhiyun      * Query the windows autorepeat settings and change the xserver defaults.
244*4882a593Smuzhiyun      */
245*4882a593Smuzhiyun     {
246*4882a593Smuzhiyun         int kbd_delay;
247*4882a593Smuzhiyun         DWORD kbd_speed;
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun         if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) &&
250*4882a593Smuzhiyun             SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0)) {
251*4882a593Smuzhiyun             switch (kbd_delay) {
252*4882a593Smuzhiyun             case 0:
253*4882a593Smuzhiyun                 g_winInfo.keyboard.delay = 250;
254*4882a593Smuzhiyun                 break;
255*4882a593Smuzhiyun             case 1:
256*4882a593Smuzhiyun                 g_winInfo.keyboard.delay = 500;
257*4882a593Smuzhiyun                 break;
258*4882a593Smuzhiyun             case 2:
259*4882a593Smuzhiyun                 g_winInfo.keyboard.delay = 750;
260*4882a593Smuzhiyun                 break;
261*4882a593Smuzhiyun             default:
262*4882a593Smuzhiyun             case 3:
263*4882a593Smuzhiyun                 g_winInfo.keyboard.delay = 1000;
264*4882a593Smuzhiyun                 break;
265*4882a593Smuzhiyun             }
266*4882a593Smuzhiyun             g_winInfo.keyboard.rate = (kbd_speed > 0) ? kbd_speed : 1;
267*4882a593Smuzhiyun             winMsg(X_PROBED, "Setting autorepeat to delay=%ld, rate=%ld\n",
268*4882a593Smuzhiyun                    g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun         }
271*4882a593Smuzhiyun     }
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun     keyboardType = GetKeyboardType(0);
274*4882a593Smuzhiyun     if (keyboardType > 0 && GetKeyboardLayoutName(layoutName)) {
275*4882a593Smuzhiyun         WinKBLayoutPtr pLayout;
276*4882a593Smuzhiyun         Bool bfound = FALSE;
277*4882a593Smuzhiyun         int pass;
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun         layoutNum = strtoul(layoutName, (char **) NULL, 16);
280*4882a593Smuzhiyun         if ((layoutNum & 0xffff) == 0x411) {
281*4882a593Smuzhiyun             if (keyboardType == 7) {
282*4882a593Smuzhiyun                 /* Japanese layouts have problems with key event messages
283*4882a593Smuzhiyun                    such as the lack of WM_KEYUP for Caps Lock key.
284*4882a593Smuzhiyun                    Loading US layout fixes this problem. */
285*4882a593Smuzhiyun                 if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL)
286*4882a593Smuzhiyun                     winMsg(X_INFO, "Loading US keyboard layout.\n");
287*4882a593Smuzhiyun                 else
288*4882a593Smuzhiyun                     winMsg(X_ERROR, "LoadKeyboardLayout failed.\n");
289*4882a593Smuzhiyun             }
290*4882a593Smuzhiyun         }
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun         /* Discover the friendly name of the current layout */
293*4882a593Smuzhiyun         {
294*4882a593Smuzhiyun             HKEY regkey = NULL;
295*4882a593Smuzhiyun             const char regtempl[] =
296*4882a593Smuzhiyun                 "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
297*4882a593Smuzhiyun             char *regpath;
298*4882a593Smuzhiyun             DWORD namesize = sizeof(layoutFriendlyName);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun             regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
301*4882a593Smuzhiyun             strcpy(regpath, regtempl);
302*4882a593Smuzhiyun             strcat(regpath, layoutName);
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun             if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, &regkey))
305*4882a593Smuzhiyun                 RegQueryValueEx(regkey, "Layout Text", 0, NULL,
306*4882a593Smuzhiyun                                 layoutFriendlyName, &namesize);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun             /* Close registry key */
309*4882a593Smuzhiyun             if (regkey)
310*4882a593Smuzhiyun                 RegCloseKey(regkey);
311*4882a593Smuzhiyun             free(regpath);
312*4882a593Smuzhiyun         }
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun         winMsg(X_PROBED,
315*4882a593Smuzhiyun                "Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n",
316*4882a593Smuzhiyun                layoutName, layoutNum, layoutFriendlyName, keyboardType);
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun         deviceIdentifier = layoutNum >> 16;
319*4882a593Smuzhiyun         for (pass = 0; pass < 2; pass++) {
320*4882a593Smuzhiyun             /* If we didn't find an exact match for the input locale identifer,
321*4882a593Smuzhiyun                try to find an match on the language identifier part only  */
322*4882a593Smuzhiyun             if (pass == 1)
323*4882a593Smuzhiyun                 layoutNum = (layoutNum & 0xffff);
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun             for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) {
326*4882a593Smuzhiyun                 if (pLayout->winlayout != layoutNum)
327*4882a593Smuzhiyun                     continue;
328*4882a593Smuzhiyun                 if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
329*4882a593Smuzhiyun                     continue;
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun                 bfound = TRUE;
332*4882a593Smuzhiyun                 winMsg(X_PROBED,
333*4882a593Smuzhiyun                        "Found matching XKB configuration \"%s\"\n",
334*4882a593Smuzhiyun                        pLayout->layoutname);
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun                 winMsg(X_PROBED,
337*4882a593Smuzhiyun                        "Model = \"%s\" Layout = \"%s\""
338*4882a593Smuzhiyun                        " Variant = \"%s\" Options = \"%s\"\n",
339*4882a593Smuzhiyun                        pLayout->xkbmodel ? pLayout->xkbmodel : "none",
340*4882a593Smuzhiyun                        pLayout->xkblayout ? pLayout->xkblayout : "none",
341*4882a593Smuzhiyun                        pLayout->xkbvariant ? pLayout->xkbvariant : "none",
342*4882a593Smuzhiyun                        pLayout->xkboptions ? pLayout->xkboptions : "none");
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun                 g_winInfo.xkb.model = pLayout->xkbmodel;
345*4882a593Smuzhiyun                 g_winInfo.xkb.layout = pLayout->xkblayout;
346*4882a593Smuzhiyun                 g_winInfo.xkb.variant = pLayout->xkbvariant;
347*4882a593Smuzhiyun                 g_winInfo.xkb.options = pLayout->xkboptions;
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun                 if (deviceIdentifier == 0xa000) {
350*4882a593Smuzhiyun                     winMsg(X_PROBED, "Windows keyboard layout device identifier indicates Macintosh, setting Model = \"macintosh\"");
351*4882a593Smuzhiyun                     g_winInfo.xkb.model = "macintosh";
352*4882a593Smuzhiyun                 }
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun                 break;
355*4882a593Smuzhiyun             }
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun             if (bfound)
358*4882a593Smuzhiyun                 break;
359*4882a593Smuzhiyun         }
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun         if (!bfound) {
362*4882a593Smuzhiyun             winMsg(X_ERROR,
363*4882a593Smuzhiyun                    "Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n",
364*4882a593Smuzhiyun                    layoutFriendlyName, layoutName);
365*4882a593Smuzhiyun         }
366*4882a593Smuzhiyun     }
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun     /* parse the configuration */
369*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
370*4882a593Smuzhiyun     if (g_cmdline.keyboard)
371*4882a593Smuzhiyun         kbdfrom = X_CMDLINE;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun     /*
374*4882a593Smuzhiyun      * Until the layout code is finished, I search for the keyboard
375*4882a593Smuzhiyun      * device and configure the server with it.
376*4882a593Smuzhiyun      */
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun     if (g_xf86configptr != NULL)
379*4882a593Smuzhiyun         input_list = g_xf86configptr->conf_input_lst;
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun     while (input_list != NULL) {
382*4882a593Smuzhiyun         if (winNameCompare(input_list->inp_driver, "keyboard") == 0) {
383*4882a593Smuzhiyun             /* Check if device name matches requested name */
384*4882a593Smuzhiyun             if (g_cmdline.keyboard && winNameCompare(input_list->inp_identifier,
385*4882a593Smuzhiyun                                                      g_cmdline.keyboard))
386*4882a593Smuzhiyun                 continue;
387*4882a593Smuzhiyun             kbd = input_list;
388*4882a593Smuzhiyun         }
389*4882a593Smuzhiyun         input_list = input_list->list.next;
390*4882a593Smuzhiyun     }
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun     if (kbd != NULL) {
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun         if (kbd->inp_identifier)
395*4882a593Smuzhiyun             winMsg(kbdfrom, "Using keyboard \"%s\" as primary keyboard\n",
396*4882a593Smuzhiyun                    kbd->inp_identifier);
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun         if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL))) {
399*4882a593Smuzhiyun             if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay,
400*4882a593Smuzhiyun                         &g_winInfo.keyboard.rate) != 2) ||
401*4882a593Smuzhiyun                 (g_winInfo.keyboard.delay < 1) ||
402*4882a593Smuzhiyun                 (g_winInfo.keyboard.rate == 0) ||
403*4882a593Smuzhiyun                 (1000 / g_winInfo.keyboard.rate) < 1) {
404*4882a593Smuzhiyun                 winErrorFVerb(2, "\"%s\" is not a valid AutoRepeat value", s);
405*4882a593Smuzhiyun                 free(s);
406*4882a593Smuzhiyun                 return FALSE;
407*4882a593Smuzhiyun             }
408*4882a593Smuzhiyun             free(s);
409*4882a593Smuzhiyun             winMsg(X_CONFIG, "AutoRepeat: %ld %ld\n",
410*4882a593Smuzhiyun                    g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
411*4882a593Smuzhiyun         }
412*4882a593Smuzhiyun #endif
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun         s = NULL;
415*4882a593Smuzhiyun         if (g_cmdline.xkbRules) {
416*4882a593Smuzhiyun             s = g_cmdline.xkbRules;
417*4882a593Smuzhiyun             from = X_CMDLINE;
418*4882a593Smuzhiyun         }
419*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
420*4882a593Smuzhiyun         else {
421*4882a593Smuzhiyun             s = winSetStrOption(kbd->inp_option_lst, "XkbRules", NULL);
422*4882a593Smuzhiyun             from = X_CONFIG;
423*4882a593Smuzhiyun         }
424*4882a593Smuzhiyun #endif
425*4882a593Smuzhiyun         if (s) {
426*4882a593Smuzhiyun             g_winInfo.xkb.rules = NULL_IF_EMPTY(s);
427*4882a593Smuzhiyun             winMsg(from, "XKB: rules: \"%s\"\n", s);
428*4882a593Smuzhiyun         }
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun         s = NULL;
431*4882a593Smuzhiyun         if (g_cmdline.xkbModel) {
432*4882a593Smuzhiyun             s = g_cmdline.xkbModel;
433*4882a593Smuzhiyun             from = X_CMDLINE;
434*4882a593Smuzhiyun         }
435*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
436*4882a593Smuzhiyun         else {
437*4882a593Smuzhiyun             s = winSetStrOption(kbd->inp_option_lst, "XkbModel", NULL);
438*4882a593Smuzhiyun             from = X_CONFIG;
439*4882a593Smuzhiyun         }
440*4882a593Smuzhiyun #endif
441*4882a593Smuzhiyun         if (s) {
442*4882a593Smuzhiyun             g_winInfo.xkb.model = NULL_IF_EMPTY(s);
443*4882a593Smuzhiyun             winMsg(from, "XKB: model: \"%s\"\n", s);
444*4882a593Smuzhiyun         }
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun         s = NULL;
447*4882a593Smuzhiyun         if (g_cmdline.xkbLayout) {
448*4882a593Smuzhiyun             s = g_cmdline.xkbLayout;
449*4882a593Smuzhiyun             from = X_CMDLINE;
450*4882a593Smuzhiyun         }
451*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
452*4882a593Smuzhiyun         else {
453*4882a593Smuzhiyun             s = winSetStrOption(kbd->inp_option_lst, "XkbLayout", NULL);
454*4882a593Smuzhiyun             from = X_CONFIG;
455*4882a593Smuzhiyun         }
456*4882a593Smuzhiyun #endif
457*4882a593Smuzhiyun         if (s) {
458*4882a593Smuzhiyun             g_winInfo.xkb.layout = NULL_IF_EMPTY(s);
459*4882a593Smuzhiyun             winMsg(from, "XKB: layout: \"%s\"\n", s);
460*4882a593Smuzhiyun         }
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun         s = NULL;
463*4882a593Smuzhiyun         if (g_cmdline.xkbVariant) {
464*4882a593Smuzhiyun             s = g_cmdline.xkbVariant;
465*4882a593Smuzhiyun             from = X_CMDLINE;
466*4882a593Smuzhiyun         }
467*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
468*4882a593Smuzhiyun         else {
469*4882a593Smuzhiyun             s = winSetStrOption(kbd->inp_option_lst, "XkbVariant", NULL);
470*4882a593Smuzhiyun             from = X_CONFIG;
471*4882a593Smuzhiyun         }
472*4882a593Smuzhiyun #endif
473*4882a593Smuzhiyun         if (s) {
474*4882a593Smuzhiyun             g_winInfo.xkb.variant = NULL_IF_EMPTY(s);
475*4882a593Smuzhiyun             winMsg(from, "XKB: variant: \"%s\"\n", s);
476*4882a593Smuzhiyun         }
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun         s = NULL;
479*4882a593Smuzhiyun         if (g_cmdline.xkbOptions) {
480*4882a593Smuzhiyun             s = g_cmdline.xkbOptions;
481*4882a593Smuzhiyun             from = X_CMDLINE;
482*4882a593Smuzhiyun         }
483*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
484*4882a593Smuzhiyun         else {
485*4882a593Smuzhiyun             s = winSetStrOption(kbd->inp_option_lst, "XkbOptions", NULL);
486*4882a593Smuzhiyun             from = X_CONFIG;
487*4882a593Smuzhiyun         }
488*4882a593Smuzhiyun #endif
489*4882a593Smuzhiyun         if (s) {
490*4882a593Smuzhiyun             g_winInfo.xkb.options = NULL_IF_EMPTY(s);
491*4882a593Smuzhiyun             winMsg(from, "XKB: options: \"%s\"\n", s);
492*4882a593Smuzhiyun         }
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
495*4882a593Smuzhiyun     }
496*4882a593Smuzhiyun #endif
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun     return TRUE;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
502*4882a593Smuzhiyun Bool
winConfigMouse(DeviceIntPtr pDevice)503*4882a593Smuzhiyun winConfigMouse(DeviceIntPtr pDevice)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun     MessageType mousefrom = X_CONFIG;
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun     XF86ConfInputPtr mouse = NULL;
508*4882a593Smuzhiyun     XF86ConfInputPtr input_list = NULL;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun     if (g_cmdline.mouse)
511*4882a593Smuzhiyun         mousefrom = X_CMDLINE;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun     if (g_xf86configptr != NULL)
514*4882a593Smuzhiyun         input_list = g_xf86configptr->conf_input_lst;
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun     while (input_list != NULL) {
517*4882a593Smuzhiyun         if (winNameCompare(input_list->inp_driver, "mouse") == 0) {
518*4882a593Smuzhiyun             /* Check if device name matches requested name */
519*4882a593Smuzhiyun             if (g_cmdline.mouse && winNameCompare(input_list->inp_identifier,
520*4882a593Smuzhiyun                                                   g_cmdline.mouse))
521*4882a593Smuzhiyun                 continue;
522*4882a593Smuzhiyun             mouse = input_list;
523*4882a593Smuzhiyun         }
524*4882a593Smuzhiyun         input_list = input_list->list.next;
525*4882a593Smuzhiyun     }
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun     if (mouse != NULL) {
528*4882a593Smuzhiyun         if (mouse->inp_identifier)
529*4882a593Smuzhiyun             winMsg(mousefrom, "Using pointer \"%s\" as primary pointer\n",
530*4882a593Smuzhiyun                    mouse->inp_identifier);
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun         g_winInfo.pointer.emulate3Buttons =
533*4882a593Smuzhiyun             winSetBoolOption(mouse->inp_option_lst, "Emulate3Buttons", FALSE);
534*4882a593Smuzhiyun         if (g_cmdline.emulate3buttons)
535*4882a593Smuzhiyun             g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons;
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun         g_winInfo.pointer.emulate3Timeout =
538*4882a593Smuzhiyun             winSetIntOption(mouse->inp_option_lst, "Emulate3Timeout", 50);
539*4882a593Smuzhiyun         if (g_cmdline.emulate3timeout)
540*4882a593Smuzhiyun             g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout;
541*4882a593Smuzhiyun     }
542*4882a593Smuzhiyun     else {
543*4882a593Smuzhiyun         winMsg(X_ERROR, "No primary pointer configured\n");
544*4882a593Smuzhiyun         winMsg(X_DEFAULT, "Using compiletime defaults for pointer\n");
545*4882a593Smuzhiyun     }
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun     return TRUE;
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun Bool
winConfigFiles()551*4882a593Smuzhiyun winConfigFiles()
552*4882a593Smuzhiyun {
553*4882a593Smuzhiyun     MessageType from;
554*4882a593Smuzhiyun     XF86ConfFilesPtr filesptr = NULL;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun     /* set some shortcuts */
557*4882a593Smuzhiyun     if (g_xf86configptr != NULL) {
558*4882a593Smuzhiyun         filesptr = g_xf86configptr->conf_files;
559*4882a593Smuzhiyun     }
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun     /* Fontpath */
562*4882a593Smuzhiyun     from = X_DEFAULT;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun     if (g_cmdline.fontPath) {
565*4882a593Smuzhiyun         from = X_CMDLINE;
566*4882a593Smuzhiyun         defaultFontPath = g_cmdline.fontPath;
567*4882a593Smuzhiyun     }
568*4882a593Smuzhiyun     else if (filesptr != NULL && filesptr->file_fontpath) {
569*4882a593Smuzhiyun         from = X_CONFIG;
570*4882a593Smuzhiyun         defaultFontPath = strdup(filesptr->file_fontpath);
571*4882a593Smuzhiyun     }
572*4882a593Smuzhiyun     winMsg(from, "FontPath set to \"%s\"\n", defaultFontPath);
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun     return TRUE;
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun #else
577*4882a593Smuzhiyun Bool
winConfigFiles(void)578*4882a593Smuzhiyun winConfigFiles(void)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun     /* Fontpath */
581*4882a593Smuzhiyun     if (g_cmdline.fontPath) {
582*4882a593Smuzhiyun         defaultFontPath = g_cmdline.fontPath;
583*4882a593Smuzhiyun         winMsg(X_CMDLINE, "FontPath set to \"%s\"\n", defaultFontPath);
584*4882a593Smuzhiyun     }
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun     return TRUE;
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun #endif
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun Bool
winConfigOptions(void)591*4882a593Smuzhiyun winConfigOptions(void)
592*4882a593Smuzhiyun {
593*4882a593Smuzhiyun     return TRUE;
594*4882a593Smuzhiyun }
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun Bool
winConfigScreens(void)597*4882a593Smuzhiyun winConfigScreens(void)
598*4882a593Smuzhiyun {
599*4882a593Smuzhiyun     return TRUE;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
603*4882a593Smuzhiyun char *
winSetStrOption(void * optlist,const char * name,char * deflt)604*4882a593Smuzhiyun winSetStrOption(void *optlist, const char *name, char *deflt)
605*4882a593Smuzhiyun {
606*4882a593Smuzhiyun     OptionInfoRec o;
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun     o.name = name;
609*4882a593Smuzhiyun     o.type = OPTV_STRING;
610*4882a593Smuzhiyun     if (ParseOptionValue(-1, optlist, &o))
611*4882a593Smuzhiyun         deflt = o.value.str;
612*4882a593Smuzhiyun     if (deflt)
613*4882a593Smuzhiyun         return strdup(deflt);
614*4882a593Smuzhiyun     else
615*4882a593Smuzhiyun         return NULL;
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun int
winSetBoolOption(void * optlist,const char * name,int deflt)619*4882a593Smuzhiyun winSetBoolOption(void *optlist, const char *name, int deflt)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun     OptionInfoRec o;
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun     o.name = name;
624*4882a593Smuzhiyun     o.type = OPTV_BOOLEAN;
625*4882a593Smuzhiyun     if (ParseOptionValue(-1, optlist, &o))
626*4882a593Smuzhiyun         deflt = o.value.bool;
627*4882a593Smuzhiyun     return deflt;
628*4882a593Smuzhiyun }
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun int
winSetIntOption(void * optlist,const char * name,int deflt)631*4882a593Smuzhiyun winSetIntOption(void *optlist, const char *name, int deflt)
632*4882a593Smuzhiyun {
633*4882a593Smuzhiyun     OptionInfoRec o;
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun     o.name = name;
636*4882a593Smuzhiyun     o.type = OPTV_INTEGER;
637*4882a593Smuzhiyun     if (ParseOptionValue(-1, optlist, &o))
638*4882a593Smuzhiyun         deflt = o.value.num;
639*4882a593Smuzhiyun     return deflt;
640*4882a593Smuzhiyun }
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun double
winSetRealOption(void * optlist,const char * name,double deflt)643*4882a593Smuzhiyun winSetRealOption(void *optlist, const char *name, double deflt)
644*4882a593Smuzhiyun {
645*4882a593Smuzhiyun     OptionInfoRec o;
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun     o.name = name;
648*4882a593Smuzhiyun     o.type = OPTV_REAL;
649*4882a593Smuzhiyun     if (ParseOptionValue(-1, optlist, &o))
650*4882a593Smuzhiyun         deflt = o.value.realnum;
651*4882a593Smuzhiyun     return deflt;
652*4882a593Smuzhiyun }
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun double
winSetPercentOption(void * optlist,const char * name,double deflt)655*4882a593Smuzhiyun winSetPercentOption(void *optlist, const char *name, double deflt)
656*4882a593Smuzhiyun {
657*4882a593Smuzhiyun     OptionInfoRec o;
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun     o.name = name;
660*4882a593Smuzhiyun     o.type = OPTV_PERCENT;
661*4882a593Smuzhiyun     if (ParseOptionValue(-1, optlist, &o))
662*4882a593Smuzhiyun         deflt = o.value.realnum;
663*4882a593Smuzhiyun     return deflt;
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun #endif
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun /*
668*4882a593Smuzhiyun  * Compare two strings for equality. This is caseinsensitive  and
669*4882a593Smuzhiyun  * The characters '_', ' ' (space) and '\t' (tab) are treated as
670*4882a593Smuzhiyun  * not existing.
671*4882a593Smuzhiyun  */
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun int
winNameCompare(const char * s1,const char * s2)674*4882a593Smuzhiyun winNameCompare(const char *s1, const char *s2)
675*4882a593Smuzhiyun {
676*4882a593Smuzhiyun     char c1, c2;
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun     if (!s1 || *s1 == 0) {
679*4882a593Smuzhiyun         if (!s2 || *s2 == 0)
680*4882a593Smuzhiyun             return 0;
681*4882a593Smuzhiyun         else
682*4882a593Smuzhiyun             return 1;
683*4882a593Smuzhiyun     }
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun     while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
686*4882a593Smuzhiyun         s1++;
687*4882a593Smuzhiyun     while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
688*4882a593Smuzhiyun         s2++;
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun     c1 = (isupper((int) *s1) ? tolower((int) *s1) : *s1);
691*4882a593Smuzhiyun     c2 = (isupper((int) *s2) ? tolower((int) *s2) : *s2);
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun     while (c1 == c2) {
694*4882a593Smuzhiyun         if (c1 == 0)
695*4882a593Smuzhiyun             return 0;
696*4882a593Smuzhiyun         s1++;
697*4882a593Smuzhiyun         s2++;
698*4882a593Smuzhiyun 
699*4882a593Smuzhiyun         while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
700*4882a593Smuzhiyun             s1++;
701*4882a593Smuzhiyun         while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
702*4882a593Smuzhiyun             s2++;
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun         c1 = (isupper((int) *s1) ? tolower((int) *s1) : *s1);
705*4882a593Smuzhiyun         c2 = (isupper((int) *s2) ? tolower((int) *s2) : *s2);
706*4882a593Smuzhiyun     }
707*4882a593Smuzhiyun     return c1 - c2;
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun #ifdef XWIN_XF86CONFIG
711*4882a593Smuzhiyun /*
712*4882a593Smuzhiyun  * Find the named option in the list.
713*4882a593Smuzhiyun  * @return the pointer to the option record, or NULL if not found.
714*4882a593Smuzhiyun  */
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun XF86OptionPtr
winFindOption(XF86OptionPtr list,const char * name)717*4882a593Smuzhiyun winFindOption(XF86OptionPtr list, const char *name)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun     while (list) {
720*4882a593Smuzhiyun         if (winNameCompare(list->opt_name, name) == 0)
721*4882a593Smuzhiyun             return list;
722*4882a593Smuzhiyun         list = list->list.next;
723*4882a593Smuzhiyun     }
724*4882a593Smuzhiyun     return NULL;
725*4882a593Smuzhiyun }
726*4882a593Smuzhiyun 
727*4882a593Smuzhiyun /*
728*4882a593Smuzhiyun  * Find the Value of an named option.
729*4882a593Smuzhiyun  * @return The option value or NULL if not found.
730*4882a593Smuzhiyun  */
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun char *
winFindOptionValue(XF86OptionPtr list,const char * name)733*4882a593Smuzhiyun winFindOptionValue(XF86OptionPtr list, const char *name)
734*4882a593Smuzhiyun {
735*4882a593Smuzhiyun     list = winFindOption(list, name);
736*4882a593Smuzhiyun     if (list) {
737*4882a593Smuzhiyun         if (list->opt_val)
738*4882a593Smuzhiyun             return list->opt_val;
739*4882a593Smuzhiyun         else
740*4882a593Smuzhiyun             return "";
741*4882a593Smuzhiyun     }
742*4882a593Smuzhiyun     return NULL;
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun /*
746*4882a593Smuzhiyun  * Parse the option.
747*4882a593Smuzhiyun  */
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun static Bool
ParseOptionValue(int scrnIndex,void * options,OptionInfoPtr p)750*4882a593Smuzhiyun ParseOptionValue(int scrnIndex, void *options, OptionInfoPtr p)
751*4882a593Smuzhiyun {
752*4882a593Smuzhiyun     char *s, *end;
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun     if ((s = winFindOptionValue(options, p->name)) != NULL) {
755*4882a593Smuzhiyun         switch (p->type) {
756*4882a593Smuzhiyun         case OPTV_INTEGER:
757*4882a593Smuzhiyun             if (*s == '\0') {
758*4882a593Smuzhiyun                 winDrvMsg(scrnIndex, X_WARNING,
759*4882a593Smuzhiyun                           "Option \"%s\" requires an integer value\n", p->name);
760*4882a593Smuzhiyun                 p->found = FALSE;
761*4882a593Smuzhiyun             }
762*4882a593Smuzhiyun             else {
763*4882a593Smuzhiyun                 p->value.num = strtoul(s, &end, 0);
764*4882a593Smuzhiyun                 if (*end == '\0') {
765*4882a593Smuzhiyun                     p->found = TRUE;
766*4882a593Smuzhiyun                 }
767*4882a593Smuzhiyun                 else {
768*4882a593Smuzhiyun                     winDrvMsg(scrnIndex, X_WARNING,
769*4882a593Smuzhiyun                               "Option \"%s\" requires an integer value\n",
770*4882a593Smuzhiyun                               p->name);
771*4882a593Smuzhiyun                     p->found = FALSE;
772*4882a593Smuzhiyun                 }
773*4882a593Smuzhiyun             }
774*4882a593Smuzhiyun             break;
775*4882a593Smuzhiyun         case OPTV_STRING:
776*4882a593Smuzhiyun             if (*s == '\0') {
777*4882a593Smuzhiyun                 winDrvMsg(scrnIndex, X_WARNING,
778*4882a593Smuzhiyun                           "Option \"%s\" requires a string value\n", p->name);
779*4882a593Smuzhiyun                 p->found = FALSE;
780*4882a593Smuzhiyun             }
781*4882a593Smuzhiyun             else {
782*4882a593Smuzhiyun                 p->value.str = s;
783*4882a593Smuzhiyun                 p->found = TRUE;
784*4882a593Smuzhiyun             }
785*4882a593Smuzhiyun             break;
786*4882a593Smuzhiyun         case OPTV_ANYSTR:
787*4882a593Smuzhiyun             p->value.str = s;
788*4882a593Smuzhiyun             p->found = TRUE;
789*4882a593Smuzhiyun             break;
790*4882a593Smuzhiyun         case OPTV_REAL:
791*4882a593Smuzhiyun             if (*s == '\0') {
792*4882a593Smuzhiyun                 winDrvMsg(scrnIndex, X_WARNING,
793*4882a593Smuzhiyun                           "Option \"%s\" requires a floating point value\n",
794*4882a593Smuzhiyun                           p->name);
795*4882a593Smuzhiyun                 p->found = FALSE;
796*4882a593Smuzhiyun             }
797*4882a593Smuzhiyun             else {
798*4882a593Smuzhiyun                 p->value.realnum = strtod(s, &end);
799*4882a593Smuzhiyun                 if (*end == '\0') {
800*4882a593Smuzhiyun                     p->found = TRUE;
801*4882a593Smuzhiyun                 }
802*4882a593Smuzhiyun                 else {
803*4882a593Smuzhiyun                     winDrvMsg(scrnIndex, X_WARNING,
804*4882a593Smuzhiyun                               "Option \"%s\" requires a floating point value\n",
805*4882a593Smuzhiyun                               p->name);
806*4882a593Smuzhiyun                     p->found = FALSE;
807*4882a593Smuzhiyun                 }
808*4882a593Smuzhiyun             }
809*4882a593Smuzhiyun             break;
810*4882a593Smuzhiyun         case OPTV_BOOLEAN:
811*4882a593Smuzhiyun             if (GetBoolValue(p, s)) {
812*4882a593Smuzhiyun                 p->found = TRUE;
813*4882a593Smuzhiyun             }
814*4882a593Smuzhiyun             else {
815*4882a593Smuzhiyun                 winDrvMsg(scrnIndex, X_WARNING,
816*4882a593Smuzhiyun                           "Option \"%s\" requires a boolean value\n", p->name);
817*4882a593Smuzhiyun                 p->found = FALSE;
818*4882a593Smuzhiyun             }
819*4882a593Smuzhiyun             break;
820*4882a593Smuzhiyun         case OPTV_PERCENT:
821*4882a593Smuzhiyun             if (*s == '\0') {
822*4882a593Smuzhiyun                 winDrvMsg(scrnIndex, X_WARNING,
823*4882a593Smuzhiyun                           "Option \"%s\" requires a percent value\n", p->name);
824*4882a593Smuzhiyun                 p->found = FALSE;
825*4882a593Smuzhiyun             }
826*4882a593Smuzhiyun             else {
827*4882a593Smuzhiyun                 double percent = strtod(s, &end);
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun                 if (end != s && winNameCompare(end, "%")) {
830*4882a593Smuzhiyun                     p->found = TRUE;
831*4882a593Smuzhiyun                     p->value.realnum = percent;
832*4882a593Smuzhiyun                 }
833*4882a593Smuzhiyun                 else {
834*4882a593Smuzhiyun                     winDrvMsg(scrnIndex, X_WARNING,
835*4882a593Smuzhiyun                               "Option \"%s\" requires a frequency value\n",
836*4882a593Smuzhiyun                               p->name);
837*4882a593Smuzhiyun                     p->found = FALSE;
838*4882a593Smuzhiyun                 }
839*4882a593Smuzhiyun             }
840*4882a593Smuzhiyun         case OPTV_FREQ:
841*4882a593Smuzhiyun             if (*s == '\0') {
842*4882a593Smuzhiyun                 winDrvMsg(scrnIndex, X_WARNING,
843*4882a593Smuzhiyun                           "Option \"%s\" requires a frequency value\n",
844*4882a593Smuzhiyun                           p->name);
845*4882a593Smuzhiyun                 p->found = FALSE;
846*4882a593Smuzhiyun             }
847*4882a593Smuzhiyun             else {
848*4882a593Smuzhiyun                 double freq = strtod(s, &end);
849*4882a593Smuzhiyun                 int units = 0;
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun                 if (end != s) {
852*4882a593Smuzhiyun                     p->found = TRUE;
853*4882a593Smuzhiyun                     if (!winNameCompare(end, "Hz"))
854*4882a593Smuzhiyun                         units = 1;
855*4882a593Smuzhiyun                     else if (!winNameCompare(end, "kHz") ||
856*4882a593Smuzhiyun                              !winNameCompare(end, "k"))
857*4882a593Smuzhiyun                         units = 1000;
858*4882a593Smuzhiyun                     else if (!winNameCompare(end, "MHz") ||
859*4882a593Smuzhiyun                              !winNameCompare(end, "M"))
860*4882a593Smuzhiyun                         units = 1000000;
861*4882a593Smuzhiyun                     else {
862*4882a593Smuzhiyun                         winDrvMsg(scrnIndex, X_WARNING,
863*4882a593Smuzhiyun                                   "Option \"%s\" requires a frequency value\n",
864*4882a593Smuzhiyun                                   p->name);
865*4882a593Smuzhiyun                         p->found = FALSE;
866*4882a593Smuzhiyun                     }
867*4882a593Smuzhiyun                     if (p->found)
868*4882a593Smuzhiyun                         freq *= (double) units;
869*4882a593Smuzhiyun                 }
870*4882a593Smuzhiyun                 else {
871*4882a593Smuzhiyun                     winDrvMsg(scrnIndex, X_WARNING,
872*4882a593Smuzhiyun                               "Option \"%s\" requires a frequency value\n",
873*4882a593Smuzhiyun                               p->name);
874*4882a593Smuzhiyun                     p->found = FALSE;
875*4882a593Smuzhiyun                 }
876*4882a593Smuzhiyun                 if (p->found) {
877*4882a593Smuzhiyun                     p->value.freq.freq = freq;
878*4882a593Smuzhiyun                     p->value.freq.units = units;
879*4882a593Smuzhiyun                 }
880*4882a593Smuzhiyun             }
881*4882a593Smuzhiyun             break;
882*4882a593Smuzhiyun         case OPTV_NONE:
883*4882a593Smuzhiyun             /* Should never get here */
884*4882a593Smuzhiyun             p->found = FALSE;
885*4882a593Smuzhiyun             break;
886*4882a593Smuzhiyun         }
887*4882a593Smuzhiyun         if (p->found) {
888*4882a593Smuzhiyun             winDrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", p->name);
889*4882a593Smuzhiyun             if (!(p->type == OPTV_BOOLEAN && *s == 0)) {
890*4882a593Smuzhiyun                 winErrorFVerb(2, " \"%s\"", s);
891*4882a593Smuzhiyun             }
892*4882a593Smuzhiyun             winErrorFVerb(2, "\n");
893*4882a593Smuzhiyun         }
894*4882a593Smuzhiyun     }
895*4882a593Smuzhiyun     else if (p->type == OPTV_BOOLEAN) {
896*4882a593Smuzhiyun         /* Look for matches with options with or without a "No" prefix. */
897*4882a593Smuzhiyun         char *n, *newn;
898*4882a593Smuzhiyun         OptionInfoRec opt;
899*4882a593Smuzhiyun 
900*4882a593Smuzhiyun         n = winNormalizeName(p->name);
901*4882a593Smuzhiyun         if (!n) {
902*4882a593Smuzhiyun             p->found = FALSE;
903*4882a593Smuzhiyun             return FALSE;
904*4882a593Smuzhiyun         }
905*4882a593Smuzhiyun         if (strncmp(n, "no", 2) == 0) {
906*4882a593Smuzhiyun             newn = n + 2;
907*4882a593Smuzhiyun         }
908*4882a593Smuzhiyun         else {
909*4882a593Smuzhiyun             free(n);
910*4882a593Smuzhiyun             n = malloc(strlen(p->name) + 2 + 1);
911*4882a593Smuzhiyun             if (!n) {
912*4882a593Smuzhiyun                 p->found = FALSE;
913*4882a593Smuzhiyun                 return FALSE;
914*4882a593Smuzhiyun             }
915*4882a593Smuzhiyun             strcpy(n, "No");
916*4882a593Smuzhiyun             strcat(n, p->name);
917*4882a593Smuzhiyun             newn = n;
918*4882a593Smuzhiyun         }
919*4882a593Smuzhiyun         if ((s = winFindOptionValue(options, newn)) != NULL) {
920*4882a593Smuzhiyun             if (GetBoolValue(&opt, s)) {
921*4882a593Smuzhiyun                 p->value.bool = !opt.value.bool;
922*4882a593Smuzhiyun                 p->found = TRUE;
923*4882a593Smuzhiyun             }
924*4882a593Smuzhiyun             else {
925*4882a593Smuzhiyun                 winDrvMsg(scrnIndex, X_WARNING,
926*4882a593Smuzhiyun                           "Option \"%s\" requires a boolean value\n", newn);
927*4882a593Smuzhiyun                 p->found = FALSE;
928*4882a593Smuzhiyun             }
929*4882a593Smuzhiyun         }
930*4882a593Smuzhiyun         else {
931*4882a593Smuzhiyun             p->found = FALSE;
932*4882a593Smuzhiyun         }
933*4882a593Smuzhiyun         if (p->found) {
934*4882a593Smuzhiyun             winDrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
935*4882a593Smuzhiyun             if (*s != 0) {
936*4882a593Smuzhiyun                 winErrorFVerb(2, " \"%s\"", s);
937*4882a593Smuzhiyun             }
938*4882a593Smuzhiyun             winErrorFVerb(2, "\n");
939*4882a593Smuzhiyun         }
940*4882a593Smuzhiyun         free(n);
941*4882a593Smuzhiyun     }
942*4882a593Smuzhiyun     else {
943*4882a593Smuzhiyun         p->found = FALSE;
944*4882a593Smuzhiyun     }
945*4882a593Smuzhiyun     return p->found;
946*4882a593Smuzhiyun }
947*4882a593Smuzhiyun 
948*4882a593Smuzhiyun static Bool
configLayout(serverLayoutPtr servlayoutp,XF86ConfLayoutPtr conf_layout,char * default_layout)949*4882a593Smuzhiyun configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
950*4882a593Smuzhiyun              char *default_layout)
951*4882a593Smuzhiyun {
952*4882a593Smuzhiyun #if 0
953*4882a593Smuzhiyun #pragma warn UNIMPLEMENTED
954*4882a593Smuzhiyun #endif
955*4882a593Smuzhiyun     return TRUE;
956*4882a593Smuzhiyun }
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun static Bool
configImpliedLayout(serverLayoutPtr servlayoutp,XF86ConfScreenPtr conf_screen)959*4882a593Smuzhiyun configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen)
960*4882a593Smuzhiyun {
961*4882a593Smuzhiyun #if 0
962*4882a593Smuzhiyun #pragma warn UNIMPLEMENTED
963*4882a593Smuzhiyun #endif
964*4882a593Smuzhiyun     return TRUE;
965*4882a593Smuzhiyun }
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun static Bool
GetBoolValue(OptionInfoPtr p,const char * s)968*4882a593Smuzhiyun GetBoolValue(OptionInfoPtr p, const char *s)
969*4882a593Smuzhiyun {
970*4882a593Smuzhiyun     if (*s == 0) {
971*4882a593Smuzhiyun         p->value.bool = TRUE;
972*4882a593Smuzhiyun     }
973*4882a593Smuzhiyun     else {
974*4882a593Smuzhiyun         if (winNameCompare(s, "1") == 0)
975*4882a593Smuzhiyun             p->value.bool = TRUE;
976*4882a593Smuzhiyun         else if (winNameCompare(s, "on") == 0)
977*4882a593Smuzhiyun             p->value.bool = TRUE;
978*4882a593Smuzhiyun         else if (winNameCompare(s, "true") == 0)
979*4882a593Smuzhiyun             p->value.bool = TRUE;
980*4882a593Smuzhiyun         else if (winNameCompare(s, "yes") == 0)
981*4882a593Smuzhiyun             p->value.bool = TRUE;
982*4882a593Smuzhiyun         else if (winNameCompare(s, "0") == 0)
983*4882a593Smuzhiyun             p->value.bool = FALSE;
984*4882a593Smuzhiyun         else if (winNameCompare(s, "off") == 0)
985*4882a593Smuzhiyun             p->value.bool = FALSE;
986*4882a593Smuzhiyun         else if (winNameCompare(s, "false") == 0)
987*4882a593Smuzhiyun             p->value.bool = FALSE;
988*4882a593Smuzhiyun         else if (winNameCompare(s, "no") == 0)
989*4882a593Smuzhiyun             p->value.bool = FALSE;
990*4882a593Smuzhiyun     }
991*4882a593Smuzhiyun     return TRUE;
992*4882a593Smuzhiyun }
993*4882a593Smuzhiyun #endif
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun char *
winNormalizeName(const char * s)996*4882a593Smuzhiyun winNormalizeName(const char *s)
997*4882a593Smuzhiyun {
998*4882a593Smuzhiyun     char *ret, *q;
999*4882a593Smuzhiyun     const char *p;
1000*4882a593Smuzhiyun 
1001*4882a593Smuzhiyun     if (s == NULL)
1002*4882a593Smuzhiyun         return NULL;
1003*4882a593Smuzhiyun 
1004*4882a593Smuzhiyun     ret = malloc(strlen(s) + 1);
1005*4882a593Smuzhiyun     for (p = s, q = ret; *p != 0; p++) {
1006*4882a593Smuzhiyun         switch (*p) {
1007*4882a593Smuzhiyun         case '_':
1008*4882a593Smuzhiyun         case ' ':
1009*4882a593Smuzhiyun         case '\t':
1010*4882a593Smuzhiyun             continue;
1011*4882a593Smuzhiyun         default:
1012*4882a593Smuzhiyun             if (isupper((int) *p))
1013*4882a593Smuzhiyun                 *q++ = tolower((int) *p);
1014*4882a593Smuzhiyun             else
1015*4882a593Smuzhiyun                 *q++ = *p;
1016*4882a593Smuzhiyun         }
1017*4882a593Smuzhiyun     }
1018*4882a593Smuzhiyun     *q = '\0';
1019*4882a593Smuzhiyun     return ret;
1020*4882a593Smuzhiyun }
1021