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