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, ®key))
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