1706f2543Smrg/*
2706f2543Smrg *
3706f2543Smrg * Copyright (c) 1997  Metro Link Incorporated
4706f2543Smrg *
5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6706f2543Smrg * copy of this software and associated documentation files (the "Software"),
7706f2543Smrg * to deal in the Software without restriction, including without limitation
8706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
10706f2543Smrg * Software is furnished to do so, subject to the following conditions:
11706f2543Smrg *
12706f2543Smrg * The above copyright notice and this permission notice shall be included in
13706f2543Smrg * all copies or substantial portions of the Software.
14706f2543Smrg *
15706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18706f2543Smrg * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20706f2543Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21706f2543Smrg * SOFTWARE.
22706f2543Smrg *
23706f2543Smrg * Except as contained in this notice, the name of the Metro Link shall not be
24706f2543Smrg * used in advertising or otherwise to promote the sale, use or other dealings
25706f2543Smrg * in this Software without prior written authorization from Metro Link.
26706f2543Smrg *
27706f2543Smrg */
28706f2543Smrg/*
29706f2543Smrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
30706f2543Smrg *
31706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
32706f2543Smrg * copy of this software and associated documentation files (the "Software"),
33706f2543Smrg * to deal in the Software without restriction, including without limitation
34706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
36706f2543Smrg * Software is furnished to do so, subject to the following conditions:
37706f2543Smrg *
38706f2543Smrg * The above copyright notice and this permission notice shall be included in
39706f2543Smrg * all copies or substantial portions of the Software.
40706f2543Smrg *
41706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
44706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
45706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
46706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
47706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE.
48706f2543Smrg *
49706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s)
50706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote
51706f2543Smrg * the sale, use or other dealings in this Software without prior written
52706f2543Smrg * authorization from the copyright holder(s) and author(s).
53706f2543Smrg */
54706f2543Smrg
55706f2543Smrg
56706f2543Smrg/* View/edit this file with tab stops set to 4 */
57706f2543Smrg
58706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
59706f2543Smrg#include <xorg-config.h>
60706f2543Smrg#endif
61706f2543Smrg
62706f2543Smrg#include "xf86Parser.h"
63706f2543Smrg#include "xf86tokens.h"
64706f2543Smrg#include "Configint.h"
65706f2543Smrg#include <string.h>
66706f2543Smrg
67706f2543Smrg
68706f2543Smrg/* Needed for auto server layout */
69706f2543Smrgextern int xf86CheckBoolOption(void* optlist, const char *name, int deflt);
70706f2543Smrg
71706f2543Smrgextern LexRec val;
72706f2543Smrg
73706f2543Smrgstatic xf86ConfigSymTabRec LayoutTab[] =
74706f2543Smrg{
75706f2543Smrg	{ENDSECTION, "endsection"},
76706f2543Smrg	{SCREEN, "screen"},
77706f2543Smrg	{IDENTIFIER, "identifier"},
78706f2543Smrg	{INACTIVE, "inactive"},
79706f2543Smrg	{INPUTDEVICE, "inputdevice"},
80706f2543Smrg	{OPTION, "option"},
81706f2543Smrg	{-1, ""},
82706f2543Smrg};
83706f2543Smrg
84706f2543Smrgstatic xf86ConfigSymTabRec AdjTab[] =
85706f2543Smrg{
86706f2543Smrg	{RIGHTOF, "rightof"},
87706f2543Smrg	{LEFTOF, "leftof"},
88706f2543Smrg	{ABOVE, "above"},
89706f2543Smrg	{BELOW, "below"},
90706f2543Smrg	{RELATIVE, "relative"},
91706f2543Smrg	{ABSOLUTE, "absolute"},
92706f2543Smrg	{-1, ""},
93706f2543Smrg};
94706f2543Smrg
95706f2543Smrg#define CLEANUP xf86freeLayoutList
96706f2543Smrg
97706f2543SmrgXF86ConfLayoutPtr
98706f2543Smrgxf86parseLayoutSection (void)
99706f2543Smrg{
100706f2543Smrg	int has_ident = FALSE;
101706f2543Smrg	int token;
102706f2543Smrg	parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
103706f2543Smrg
104706f2543Smrg	while ((token = xf86getToken (LayoutTab)) != ENDSECTION)
105706f2543Smrg	{
106706f2543Smrg		switch (token)
107706f2543Smrg		{
108706f2543Smrg		case COMMENT:
109706f2543Smrg			ptr->lay_comment = xf86addComment(ptr->lay_comment, val.str);
110706f2543Smrg			break;
111706f2543Smrg		case IDENTIFIER:
112706f2543Smrg			if (xf86getSubToken (&(ptr->lay_comment)) != STRING)
113706f2543Smrg				Error (QUOTE_MSG, "Identifier");
114706f2543Smrg			if (has_ident == TRUE)
115706f2543Smrg				Error (MULTIPLE_MSG, "Identifier");
116706f2543Smrg			ptr->lay_identifier = val.str;
117706f2543Smrg			has_ident = TRUE;
118706f2543Smrg			break;
119706f2543Smrg		case INACTIVE:
120706f2543Smrg			{
121706f2543Smrg				XF86ConfInactivePtr iptr;
122706f2543Smrg
123706f2543Smrg				iptr = calloc (1, sizeof (XF86ConfInactiveRec));
124706f2543Smrg				iptr->list.next = NULL;
125706f2543Smrg				if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
126706f2543Smrg					free (iptr);
127706f2543Smrg					Error (INACTIVE_MSG, NULL);
128706f2543Smrg				}
129706f2543Smrg				iptr->inactive_device_str = val.str;
130706f2543Smrg				ptr->lay_inactive_lst = (XF86ConfInactivePtr)
131706f2543Smrg					xf86addListItem ((glp) ptr->lay_inactive_lst, (glp) iptr);
132706f2543Smrg			}
133706f2543Smrg			break;
134706f2543Smrg		case SCREEN:
135706f2543Smrg			{
136706f2543Smrg				XF86ConfAdjacencyPtr aptr;
137706f2543Smrg				int absKeyword = 0;
138706f2543Smrg
139706f2543Smrg				aptr = calloc (1, sizeof (XF86ConfAdjacencyRec));
140706f2543Smrg				aptr->list.next = NULL;
141706f2543Smrg				aptr->adj_scrnum = -1;
142706f2543Smrg				aptr->adj_where = CONF_ADJ_OBSOLETE;
143706f2543Smrg				aptr->adj_x = 0;
144706f2543Smrg				aptr->adj_y = 0;
145706f2543Smrg				aptr->adj_refscreen = NULL;
146706f2543Smrg				if ((token = xf86getSubToken (&(ptr->lay_comment))) == NUMBER)
147706f2543Smrg					aptr->adj_scrnum = val.num;
148706f2543Smrg				else
149706f2543Smrg					xf86unGetToken (token);
150706f2543Smrg				token = xf86getSubToken(&(ptr->lay_comment));
151706f2543Smrg				if (token != STRING) {
152706f2543Smrg					free(aptr);
153706f2543Smrg					Error (SCREEN_MSG, NULL);
154706f2543Smrg				}
155706f2543Smrg				aptr->adj_screen_str = val.str;
156706f2543Smrg
157706f2543Smrg				token = xf86getSubTokenWithTab(&(ptr->lay_comment), AdjTab);
158706f2543Smrg				switch (token)
159706f2543Smrg				{
160706f2543Smrg				case RIGHTOF:
161706f2543Smrg					aptr->adj_where = CONF_ADJ_RIGHTOF;
162706f2543Smrg					break;
163706f2543Smrg				case LEFTOF:
164706f2543Smrg					aptr->adj_where = CONF_ADJ_LEFTOF;
165706f2543Smrg					break;
166706f2543Smrg				case ABOVE:
167706f2543Smrg					aptr->adj_where = CONF_ADJ_ABOVE;
168706f2543Smrg					break;
169706f2543Smrg				case BELOW:
170706f2543Smrg					aptr->adj_where = CONF_ADJ_BELOW;
171706f2543Smrg					break;
172706f2543Smrg				case RELATIVE:
173706f2543Smrg					aptr->adj_where = CONF_ADJ_RELATIVE;
174706f2543Smrg					break;
175706f2543Smrg				case ABSOLUTE:
176706f2543Smrg					aptr->adj_where = CONF_ADJ_ABSOLUTE;
177706f2543Smrg					absKeyword = 1;
178706f2543Smrg					break;
179706f2543Smrg				case EOF_TOKEN:
180706f2543Smrg					free(aptr);
181706f2543Smrg					Error (UNEXPECTED_EOF_MSG, NULL);
182706f2543Smrg					break;
183706f2543Smrg				default:
184706f2543Smrg					xf86unGetToken (token);
185706f2543Smrg					token = xf86getSubToken(&(ptr->lay_comment));
186706f2543Smrg					if (token == STRING)
187706f2543Smrg						aptr->adj_where = CONF_ADJ_OBSOLETE;
188706f2543Smrg					else
189706f2543Smrg						aptr->adj_where = CONF_ADJ_ABSOLUTE;
190706f2543Smrg				}
191706f2543Smrg				switch (aptr->adj_where)
192706f2543Smrg				{
193706f2543Smrg				case CONF_ADJ_ABSOLUTE:
194706f2543Smrg					if (absKeyword)
195706f2543Smrg						token = xf86getSubToken(&(ptr->lay_comment));
196706f2543Smrg					if (token == NUMBER)
197706f2543Smrg					{
198706f2543Smrg						aptr->adj_x = val.num;
199706f2543Smrg						token = xf86getSubToken(&(ptr->lay_comment));
200706f2543Smrg						if (token != NUMBER) {
201706f2543Smrg							free(aptr);
202706f2543Smrg							Error(INVALID_SCR_MSG, NULL);
203706f2543Smrg						}
204706f2543Smrg						aptr->adj_y = val.num;
205706f2543Smrg					} else {
206706f2543Smrg						if (absKeyword) {
207706f2543Smrg							free(aptr);
208706f2543Smrg							Error(INVALID_SCR_MSG, NULL);
209706f2543Smrg						} else
210706f2543Smrg							xf86unGetToken (token);
211706f2543Smrg					}
212706f2543Smrg					break;
213706f2543Smrg				case CONF_ADJ_RIGHTOF:
214706f2543Smrg				case CONF_ADJ_LEFTOF:
215706f2543Smrg				case CONF_ADJ_ABOVE:
216706f2543Smrg				case CONF_ADJ_BELOW:
217706f2543Smrg				case CONF_ADJ_RELATIVE:
218706f2543Smrg					token = xf86getSubToken(&(ptr->lay_comment));
219706f2543Smrg					if (token != STRING) {
220706f2543Smrg						free(aptr);
221706f2543Smrg						Error(INVALID_SCR_MSG, NULL);
222706f2543Smrg					}
223706f2543Smrg					aptr->adj_refscreen = val.str;
224706f2543Smrg					if (aptr->adj_where == CONF_ADJ_RELATIVE)
225706f2543Smrg					{
226706f2543Smrg						token = xf86getSubToken(&(ptr->lay_comment));
227706f2543Smrg						if (token != NUMBER) {
228706f2543Smrg							free(aptr);
229706f2543Smrg							Error(INVALID_SCR_MSG, NULL);
230706f2543Smrg						}
231706f2543Smrg						aptr->adj_x = val.num;
232706f2543Smrg						token = xf86getSubToken(&(ptr->lay_comment));
233706f2543Smrg						if (token != NUMBER) {
234706f2543Smrg							free(aptr);
235706f2543Smrg							Error(INVALID_SCR_MSG, NULL);
236706f2543Smrg						}
237706f2543Smrg						aptr->adj_y = val.num;
238706f2543Smrg					}
239706f2543Smrg					break;
240706f2543Smrg				case CONF_ADJ_OBSOLETE:
241706f2543Smrg					/* top */
242706f2543Smrg					aptr->adj_top_str = val.str;
243706f2543Smrg
244706f2543Smrg					/* bottom */
245706f2543Smrg					if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
246706f2543Smrg						free(aptr);
247706f2543Smrg						Error (SCREEN_MSG, NULL);
248706f2543Smrg					}
249706f2543Smrg					aptr->adj_bottom_str = val.str;
250706f2543Smrg
251706f2543Smrg					/* left */
252706f2543Smrg					if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
253706f2543Smrg						free(aptr);
254706f2543Smrg						Error (SCREEN_MSG, NULL);
255706f2543Smrg					}
256706f2543Smrg					aptr->adj_left_str = val.str;
257706f2543Smrg
258706f2543Smrg					/* right */
259706f2543Smrg					if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
260706f2543Smrg						free(aptr);
261706f2543Smrg						Error (SCREEN_MSG, NULL);
262706f2543Smrg					}
263706f2543Smrg					aptr->adj_right_str = val.str;
264706f2543Smrg
265706f2543Smrg				}
266706f2543Smrg				ptr->lay_adjacency_lst = (XF86ConfAdjacencyPtr)
267706f2543Smrg					xf86addListItem ((glp) ptr->lay_adjacency_lst, (glp) aptr);
268706f2543Smrg			}
269706f2543Smrg			break;
270706f2543Smrg		case INPUTDEVICE:
271706f2543Smrg			{
272706f2543Smrg				XF86ConfInputrefPtr iptr;
273706f2543Smrg
274706f2543Smrg				iptr = calloc (1, sizeof (XF86ConfInputrefRec));
275706f2543Smrg				iptr->list.next = NULL;
276706f2543Smrg				iptr->iref_option_lst = NULL;
277706f2543Smrg				if (xf86getSubToken (&(ptr->lay_comment)) != STRING) {
278706f2543Smrg					free(iptr);
279706f2543Smrg					Error (INPUTDEV_MSG, NULL);
280706f2543Smrg				}
281706f2543Smrg				iptr->iref_inputdev_str = val.str;
282706f2543Smrg				while ((token = xf86getSubToken (&(ptr->lay_comment))) == STRING)
283706f2543Smrg				{
284706f2543Smrg					iptr->iref_option_lst =
285706f2543Smrg						xf86addNewOption (iptr->iref_option_lst, val.str, NULL);
286706f2543Smrg				}
287706f2543Smrg				xf86unGetToken (token);
288706f2543Smrg				ptr->lay_input_lst = (XF86ConfInputrefPtr)
289706f2543Smrg					xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
290706f2543Smrg			}
291706f2543Smrg			break;
292706f2543Smrg		case OPTION:
293706f2543Smrg			ptr->lay_option_lst = xf86parseOption(ptr->lay_option_lst);
294706f2543Smrg			break;
295706f2543Smrg		case EOF_TOKEN:
296706f2543Smrg			Error (UNEXPECTED_EOF_MSG, NULL);
297706f2543Smrg			break;
298706f2543Smrg		default:
299706f2543Smrg			Error (INVALID_KEYWORD_MSG, xf86tokenString ());
300706f2543Smrg			break;
301706f2543Smrg		}
302706f2543Smrg	}
303706f2543Smrg
304706f2543Smrg	if (!has_ident)
305706f2543Smrg		Error (NO_IDENT_MSG, NULL);
306706f2543Smrg
307706f2543Smrg#ifdef DEBUG
308706f2543Smrg	printf ("Layout section parsed\n");
309706f2543Smrg#endif
310706f2543Smrg
311706f2543Smrg	return ptr;
312706f2543Smrg}
313706f2543Smrg
314706f2543Smrg#undef CLEANUP
315706f2543Smrg
316706f2543Smrgvoid
317706f2543Smrgxf86printLayoutSection (FILE * cf, XF86ConfLayoutPtr ptr)
318706f2543Smrg{
319706f2543Smrg	XF86ConfAdjacencyPtr aptr;
320706f2543Smrg	XF86ConfInactivePtr iptr;
321706f2543Smrg	XF86ConfInputrefPtr inptr;
322706f2543Smrg	XF86OptionPtr optr;
323706f2543Smrg
324706f2543Smrg	while (ptr)
325706f2543Smrg	{
326706f2543Smrg		fprintf (cf, "Section \"ServerLayout\"\n");
327706f2543Smrg		if (ptr->lay_comment)
328706f2543Smrg			fprintf (cf, "%s", ptr->lay_comment);
329706f2543Smrg		if (ptr->lay_identifier)
330706f2543Smrg			fprintf (cf, "\tIdentifier     \"%s\"\n", ptr->lay_identifier);
331706f2543Smrg
332706f2543Smrg		for (aptr = ptr->lay_adjacency_lst; aptr; aptr = aptr->list.next)
333706f2543Smrg		{
334706f2543Smrg			fprintf (cf, "\tScreen     ");
335706f2543Smrg			if (aptr->adj_scrnum >= 0)
336706f2543Smrg				fprintf (cf, "%2d", aptr->adj_scrnum);
337706f2543Smrg			else
338706f2543Smrg				fprintf (cf, "  ");
339706f2543Smrg			fprintf (cf, "  \"%s\"", aptr->adj_screen_str);
340706f2543Smrg			switch(aptr->adj_where)
341706f2543Smrg			{
342706f2543Smrg			case CONF_ADJ_OBSOLETE:
343706f2543Smrg				fprintf (cf, " \"%s\"", aptr->adj_top_str);
344706f2543Smrg				fprintf (cf, " \"%s\"", aptr->adj_bottom_str);
345706f2543Smrg				fprintf (cf, " \"%s\"", aptr->adj_right_str);
346706f2543Smrg				fprintf (cf, " \"%s\"\n", aptr->adj_left_str);
347706f2543Smrg				break;
348706f2543Smrg			case CONF_ADJ_ABSOLUTE:
349706f2543Smrg				if (aptr->adj_x != -1)
350706f2543Smrg					fprintf (cf, " %d %d\n", aptr->adj_x, aptr->adj_y);
351706f2543Smrg				else
352706f2543Smrg					fprintf (cf, "\n");
353706f2543Smrg				break;
354706f2543Smrg			case CONF_ADJ_RIGHTOF:
355706f2543Smrg				fprintf (cf, " RightOf \"%s\"\n", aptr->adj_refscreen);
356706f2543Smrg				break;
357706f2543Smrg			case CONF_ADJ_LEFTOF:
358706f2543Smrg				fprintf (cf, " LeftOf \"%s\"\n", aptr->adj_refscreen);
359706f2543Smrg				break;
360706f2543Smrg			case CONF_ADJ_ABOVE:
361706f2543Smrg				fprintf (cf, " Above \"%s\"\n", aptr->adj_refscreen);
362706f2543Smrg				break;
363706f2543Smrg			case CONF_ADJ_BELOW:
364706f2543Smrg				fprintf (cf, " Below \"%s\"\n", aptr->adj_refscreen);
365706f2543Smrg				break;
366706f2543Smrg			case CONF_ADJ_RELATIVE:
367706f2543Smrg				fprintf (cf, " Relative \"%s\" %d %d\n", aptr->adj_refscreen,
368706f2543Smrg						 aptr->adj_x, aptr->adj_y);
369706f2543Smrg				break;
370706f2543Smrg			}
371706f2543Smrg		}
372706f2543Smrg		for (iptr = ptr->lay_inactive_lst; iptr; iptr = iptr->list.next)
373706f2543Smrg			fprintf (cf, "\tInactive       \"%s\"\n", iptr->inactive_device_str);
374706f2543Smrg		for (inptr = ptr->lay_input_lst; inptr; inptr = inptr->list.next)
375706f2543Smrg		{
376706f2543Smrg			fprintf (cf, "\tInputDevice    \"%s\"", inptr->iref_inputdev_str);
377706f2543Smrg			for (optr = inptr->iref_option_lst; optr; optr = optr->list.next)
378706f2543Smrg			{
379706f2543Smrg				fprintf(cf, " \"%s\"", optr->opt_name);
380706f2543Smrg			}
381706f2543Smrg			fprintf(cf, "\n");
382706f2543Smrg		}
383706f2543Smrg		xf86printOptionList(cf, ptr->lay_option_lst, 1);
384706f2543Smrg		fprintf (cf, "EndSection\n\n");
385706f2543Smrg		ptr = ptr->list.next;
386706f2543Smrg	}
387706f2543Smrg}
388706f2543Smrg
389706f2543Smrgstatic void
390706f2543Smrgxf86freeAdjacencyList (XF86ConfAdjacencyPtr ptr)
391706f2543Smrg{
392706f2543Smrg	XF86ConfAdjacencyPtr prev;
393706f2543Smrg
394706f2543Smrg	while (ptr)
395706f2543Smrg	{
396706f2543Smrg		TestFree (ptr->adj_screen_str);
397706f2543Smrg		TestFree (ptr->adj_top_str);
398706f2543Smrg		TestFree (ptr->adj_bottom_str);
399706f2543Smrg		TestFree (ptr->adj_left_str);
400706f2543Smrg		TestFree (ptr->adj_right_str);
401706f2543Smrg
402706f2543Smrg		prev = ptr;
403706f2543Smrg		ptr = ptr->list.next;
404706f2543Smrg		free (prev);
405706f2543Smrg	}
406706f2543Smrg
407706f2543Smrg}
408706f2543Smrg
409706f2543Smrgstatic void
410706f2543Smrgxf86freeInputrefList (XF86ConfInputrefPtr ptr)
411706f2543Smrg{
412706f2543Smrg	XF86ConfInputrefPtr prev;
413706f2543Smrg
414706f2543Smrg	while (ptr)
415706f2543Smrg	{
416706f2543Smrg		TestFree (ptr->iref_inputdev_str);
417706f2543Smrg		xf86optionListFree (ptr->iref_option_lst);
418706f2543Smrg		prev = ptr;
419706f2543Smrg		ptr = ptr->list.next;
420706f2543Smrg		free (prev);
421706f2543Smrg	}
422706f2543Smrg
423706f2543Smrg}
424706f2543Smrg
425706f2543Smrgvoid
426706f2543Smrgxf86freeLayoutList (XF86ConfLayoutPtr ptr)
427706f2543Smrg{
428706f2543Smrg	XF86ConfLayoutPtr prev;
429706f2543Smrg
430706f2543Smrg	while (ptr)
431706f2543Smrg	{
432706f2543Smrg		TestFree (ptr->lay_identifier);
433706f2543Smrg		TestFree (ptr->lay_comment);
434706f2543Smrg		xf86freeAdjacencyList (ptr->lay_adjacency_lst);
435706f2543Smrg		xf86freeInputrefList (ptr->lay_input_lst);
436706f2543Smrg		prev = ptr;
437706f2543Smrg		ptr = ptr->list.next;
438706f2543Smrg		free (prev);
439706f2543Smrg	}
440706f2543Smrg}
441706f2543Smrg
442706f2543Smrgint
443706f2543Smrgxf86layoutAddInputDevices(XF86ConfigPtr config, XF86ConfLayoutPtr layout)
444706f2543Smrg{
445706f2543Smrg    int count = 0;
446706f2543Smrg    XF86ConfInputPtr input = config->conf_input_lst;
447706f2543Smrg    XF86ConfInputrefPtr inptr;
448706f2543Smrg
449706f2543Smrg    /* add all AutoServerLayout devices to the server layout */
450706f2543Smrg    while (input)
451706f2543Smrg    {
452706f2543Smrg	if (xf86CheckBoolOption(input->inp_option_lst, "AutoServerLayout", FALSE))
453706f2543Smrg	{
454706f2543Smrg	    XF86ConfInputrefPtr iref = layout->lay_input_lst;
455706f2543Smrg
456706f2543Smrg	    /* avoid duplicates if referenced but lists AutoServerLayout too */
457706f2543Smrg	    while (iref)
458706f2543Smrg	    {
459706f2543Smrg		if (strcmp(iref->iref_inputdev_str, input->inp_identifier) == 0)
460706f2543Smrg		    break;
461706f2543Smrg		iref = iref->list.next;
462706f2543Smrg	    }
463706f2543Smrg
464706f2543Smrg	    if (!iref)
465706f2543Smrg	    {
466706f2543Smrg		XF86ConfInputrefPtr iptr;
467706f2543Smrg		iptr = calloc(1, sizeof(XF86ConfInputrefRec));
468706f2543Smrg		iptr->iref_inputdev_str = input->inp_identifier;
469706f2543Smrg		layout->lay_input_lst = (XF86ConfInputrefPtr)
470706f2543Smrg		    xf86addListItem((glp)layout->lay_input_lst, (glp)iptr);
471706f2543Smrg		count++;
472706f2543Smrg	    }
473706f2543Smrg	}
474706f2543Smrg	input = input->list.next;
475706f2543Smrg    }
476706f2543Smrg
477706f2543Smrg    inptr = layout->lay_input_lst;
478706f2543Smrg    while (inptr)
479706f2543Smrg    {
480706f2543Smrg	input = xf86findInput (inptr->iref_inputdev_str,
481706f2543Smrg		config->conf_input_lst);
482706f2543Smrg	if (!input)
483706f2543Smrg	{
484706f2543Smrg	    xf86validationError (UNDEFINED_INPUT_MSG,
485706f2543Smrg		    inptr->iref_inputdev_str, layout->lay_identifier);
486706f2543Smrg	    return -1;
487706f2543Smrg	}
488706f2543Smrg	else
489706f2543Smrg	    inptr->iref_inputdev = input;
490706f2543Smrg	inptr = inptr->list.next;
491706f2543Smrg    }
492706f2543Smrg
493706f2543Smrg    return count;
494706f2543Smrg}
495706f2543Smrg
496706f2543Smrgint
497706f2543Smrgxf86validateLayout (XF86ConfigPtr p)
498706f2543Smrg{
499706f2543Smrg	XF86ConfLayoutPtr layout = p->conf_layout_lst;
500706f2543Smrg	XF86ConfAdjacencyPtr adj;
501706f2543Smrg	XF86ConfInactivePtr iptr;
502706f2543Smrg	XF86ConfScreenPtr screen;
503706f2543Smrg	XF86ConfDevicePtr device;
504706f2543Smrg
505706f2543Smrg	while (layout)
506706f2543Smrg	{
507706f2543Smrg		adj = layout->lay_adjacency_lst;
508706f2543Smrg		while (adj)
509706f2543Smrg		{
510706f2543Smrg			/* the first one can't be "" but all others can */
511706f2543Smrg			screen = xf86findScreen (adj->adj_screen_str, p->conf_screen_lst);
512706f2543Smrg			if (!screen)
513706f2543Smrg			{
514706f2543Smrg				xf86validationError (UNDEFINED_SCREEN_MSG,
515706f2543Smrg							   adj->adj_screen_str, layout->lay_identifier);
516706f2543Smrg				return FALSE;
517706f2543Smrg			}
518706f2543Smrg			else
519706f2543Smrg				adj->adj_screen = screen;
520706f2543Smrg
521706f2543Smrg			adj = adj->list.next;
522706f2543Smrg		}
523706f2543Smrg		iptr = layout->lay_inactive_lst;
524706f2543Smrg		while (iptr)
525706f2543Smrg		{
526706f2543Smrg			device = xf86findDevice (iptr->inactive_device_str,
527706f2543Smrg									p->conf_device_lst);
528706f2543Smrg			if (!device)
529706f2543Smrg			{
530706f2543Smrg				xf86validationError (UNDEFINED_DEVICE_LAY_MSG,
531706f2543Smrg						iptr->inactive_device_str, layout->lay_identifier);
532706f2543Smrg				return FALSE;
533706f2543Smrg			}
534706f2543Smrg			else
535706f2543Smrg				iptr->inactive_device = device;
536706f2543Smrg			iptr = iptr->list.next;
537706f2543Smrg		}
538706f2543Smrg
539706f2543Smrg		if (xf86layoutAddInputDevices(p, layout) == -1)
540706f2543Smrg		    return FALSE;
541706f2543Smrg
542706f2543Smrg		layout = layout->list.next;
543706f2543Smrg	}
544706f2543Smrg	return TRUE;
545706f2543Smrg}
546706f2543Smrg
547706f2543SmrgXF86ConfLayoutPtr
548706f2543Smrgxf86findLayout (const char *name, XF86ConfLayoutPtr list)
549706f2543Smrg{
550706f2543Smrg	while (list)
551706f2543Smrg	{
552706f2543Smrg		if (xf86nameCompare (list->lay_identifier, name) == 0)
553706f2543Smrg			return list;
554706f2543Smrg		list = list->list.next;
555706f2543Smrg	}
556706f2543Smrg	return NULL;
557706f2543Smrg}
558706f2543Smrg
559