Screen.c revision 6747b715
1/*
2 *
3 * Copyright (c) 1997  Metro Link Incorporated
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Except as contained in this notice, the name of the Metro Link shall not be
24 * used in advertising or otherwise to promote the sale, use or other dealings
25 * in this Software without prior written authorization from Metro Link.
26 *
27 */
28/*
29 * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
30 *
31 * Permission is hereby granted, free of charge, to any person obtaining a
32 * copy of this software and associated documentation files (the "Software"),
33 * to deal in the Software without restriction, including without limitation
34 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35 * and/or sell copies of the Software, and to permit persons to whom the
36 * Software is furnished to do so, subject to the following conditions:
37 *
38 * The above copyright notice and this permission notice shall be included in
39 * all copies or substantial portions of the Software.
40 *
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
44 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
45 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
46 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
47 * OTHER DEALINGS IN THE SOFTWARE.
48 *
49 * Except as contained in this notice, the name of the copyright holder(s)
50 * and author(s) shall not be used in advertising or otherwise to promote
51 * the sale, use or other dealings in this Software without prior written
52 * authorization from the copyright holder(s) and author(s).
53 */
54
55
56/* View/edit this file with tab stops set to 4 */
57
58#ifdef HAVE_XORG_CONFIG_H
59#include <xorg-config.h>
60#endif
61
62#include "xf86Parser.h"
63#include "xf86tokens.h"
64#include "Configint.h"
65
66extern LexRec val;
67
68static xf86ConfigSymTabRec DisplayTab[] =
69{
70	{ENDSUBSECTION, "endsubsection"},
71	{MODES, "modes"},
72	{VIEWPORT, "viewport"},
73	{VIRTUAL, "virtual"},
74	{VISUAL, "visual"},
75	{BLACK_TOK, "black"},
76	{WHITE_TOK, "white"},
77	{DEPTH, "depth"},
78	{BPP, "fbbpp"},
79	{WEIGHT, "weight"},
80	{OPTION, "option"},
81	{-1, ""},
82};
83
84#define CLEANUP xf86freeDisplayList
85
86static XF86ConfDisplayPtr
87xf86parseDisplaySubSection (void)
88{
89	int token;
90	parsePrologue (XF86ConfDisplayPtr, XF86ConfDisplayRec)
91
92	ptr->disp_black.red = ptr->disp_black.green = ptr->disp_black.blue = -1;
93	ptr->disp_white.red = ptr->disp_white.green = ptr->disp_white.blue = -1;
94	ptr->disp_frameX0 = ptr->disp_frameY0 = -1;
95	while ((token = xf86getToken (DisplayTab)) != ENDSUBSECTION)
96	{
97		switch (token)
98		{
99		case COMMENT:
100			ptr->disp_comment = xf86addComment(ptr->disp_comment, val.str);
101			break;
102		case VIEWPORT:
103			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
104				Error (VIEWPORT_MSG, NULL);
105			ptr->disp_frameX0 = val.num;
106			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
107				Error (VIEWPORT_MSG, NULL);
108			ptr->disp_frameY0 = val.num;
109			break;
110		case VIRTUAL:
111			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
112				Error (VIRTUAL_MSG, NULL);
113			ptr->disp_virtualX = val.num;
114			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
115				Error (VIRTUAL_MSG, NULL);
116			ptr->disp_virtualY = val.num;
117			break;
118		case DEPTH:
119			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
120				Error (NUMBER_MSG, "Display");
121			ptr->disp_depth = val.num;
122			break;
123		case BPP:
124			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
125				Error (NUMBER_MSG, "Display");
126			ptr->disp_bpp = val.num;
127			break;
128		case VISUAL:
129			if (xf86getSubToken (&(ptr->disp_comment)) != STRING)
130				Error (QUOTE_MSG, "Display");
131			ptr->disp_visual = val.str;
132			break;
133		case WEIGHT:
134			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
135				Error (WEIGHT_MSG, NULL);
136			ptr->disp_weight.red = val.num;
137			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
138				Error (WEIGHT_MSG, NULL);
139			ptr->disp_weight.green = val.num;
140			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
141				Error (WEIGHT_MSG, NULL);
142			ptr->disp_weight.blue = val.num;
143			break;
144		case BLACK_TOK:
145			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
146				Error (BLACK_MSG, NULL);
147			ptr->disp_black.red = val.num;
148			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
149				Error (BLACK_MSG, NULL);
150			ptr->disp_black.green = val.num;
151			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
152				Error (BLACK_MSG, NULL);
153			ptr->disp_black.blue = val.num;
154			break;
155		case WHITE_TOK:
156			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
157				Error (WHITE_MSG, NULL);
158			ptr->disp_white.red = val.num;
159			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
160				Error (WHITE_MSG, NULL);
161			ptr->disp_white.green = val.num;
162			if (xf86getSubToken (&(ptr->disp_comment)) != NUMBER)
163				Error (WHITE_MSG, NULL);
164			ptr->disp_white.blue = val.num;
165			break;
166		case MODES:
167			{
168				XF86ModePtr mptr;
169
170				while ((token = xf86getSubTokenWithTab (&(ptr->disp_comment), DisplayTab)) == STRING)
171				{
172					mptr = calloc (1, sizeof (XF86ModeRec));
173					mptr->mode_name = val.str;
174					mptr->list.next = NULL;
175					ptr->disp_mode_lst = (XF86ModePtr)
176						xf86addListItem ((glp) ptr->disp_mode_lst, (glp) mptr);
177				}
178				xf86unGetToken (token);
179			}
180			break;
181		case OPTION:
182			ptr->disp_option_lst = xf86parseOption(ptr->disp_option_lst);
183			break;
184
185		case EOF_TOKEN:
186			Error (UNEXPECTED_EOF_MSG, NULL);
187			break;
188		default:
189			Error (INVALID_KEYWORD_MSG, xf86tokenString ());
190			break;
191		}
192	}
193
194#ifdef DEBUG
195	printf ("Display subsection parsed\n");
196#endif
197
198	return ptr;
199}
200
201#undef CLEANUP
202
203static xf86ConfigSymTabRec ScreenTab[] =
204{
205	{ENDSECTION, "endsection"},
206	{IDENTIFIER, "identifier"},
207	{OBSDRIVER, "driver"},
208	{MDEVICE, "device"},
209	{MONITOR, "monitor"},
210	{VIDEOADAPTOR, "videoadaptor"},
211	{SCREENNO, "screenno"},
212	{SUBSECTION, "subsection"},
213	{DEFAULTDEPTH, "defaultcolordepth"},
214	{DEFAULTDEPTH, "defaultdepth"},
215	{DEFAULTBPP, "defaultbpp"},
216	{DEFAULTFBBPP, "defaultfbbpp"},
217	{VIRTUAL, "virtual"},
218	{OPTION, "option"},
219	{-1, ""},
220};
221
222#define CLEANUP xf86freeScreenList
223XF86ConfScreenPtr
224xf86parseScreenSection (void)
225{
226	int has_ident = FALSE;
227	int has_driver= FALSE;
228	int token;
229
230	parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
231
232		while ((token = xf86getToken (ScreenTab)) != ENDSECTION)
233	{
234		switch (token)
235		{
236		case COMMENT:
237			ptr->scrn_comment = xf86addComment(ptr->scrn_comment, val.str);
238			break;
239		case IDENTIFIER:
240			if (xf86getSubToken (&(ptr->scrn_comment)) != STRING)
241				Error (QUOTE_MSG, "Identifier");
242			ptr->scrn_identifier = val.str;
243			if (has_ident || has_driver)
244				Error (ONLY_ONE_MSG,"Identifier or Driver");
245			has_ident = TRUE;
246			break;
247		case OBSDRIVER:
248			if (xf86getSubToken (&(ptr->scrn_comment)) != STRING)
249				Error (QUOTE_MSG, "Driver");
250			ptr->scrn_obso_driver = val.str;
251			if (has_ident || has_driver)
252				Error (ONLY_ONE_MSG,"Identifier or Driver");
253			has_driver = TRUE;
254			break;
255		case DEFAULTDEPTH:
256			if (xf86getSubToken (&(ptr->scrn_comment)) != NUMBER)
257				Error (NUMBER_MSG, "DefaultDepth");
258			ptr->scrn_defaultdepth = val.num;
259			break;
260		case DEFAULTBPP:
261			if (xf86getSubToken (&(ptr->scrn_comment)) != NUMBER)
262				Error (NUMBER_MSG, "DefaultBPP");
263			ptr->scrn_defaultbpp = val.num;
264			break;
265		case DEFAULTFBBPP:
266			if (xf86getSubToken (&(ptr->scrn_comment)) != NUMBER)
267				Error (NUMBER_MSG, "DefaultFbBPP");
268			ptr->scrn_defaultfbbpp = val.num;
269			break;
270		case MDEVICE:
271			if (xf86getSubToken (&(ptr->scrn_comment)) != STRING)
272				Error (QUOTE_MSG, "Device");
273			ptr->scrn_device_str = val.str;
274			break;
275		case MONITOR:
276			if (xf86getSubToken (&(ptr->scrn_comment)) != STRING)
277				Error (QUOTE_MSG, "Monitor");
278			ptr->scrn_monitor_str = val.str;
279			break;
280		case VIDEOADAPTOR:
281			{
282				XF86ConfAdaptorLinkPtr aptr;
283
284				if (xf86getSubToken (&(ptr->scrn_comment)) != STRING)
285					Error (QUOTE_MSG, "VideoAdaptor");
286
287				/* Don't allow duplicates */
288				for (aptr = ptr->scrn_adaptor_lst; aptr;
289					aptr = (XF86ConfAdaptorLinkPtr) aptr->list.next)
290					if (xf86nameCompare (val.str, aptr->al_adaptor_str) == 0)
291						break;
292
293				if (aptr == NULL)
294				{
295					aptr = calloc (1, sizeof (XF86ConfAdaptorLinkRec));
296					aptr->list.next = NULL;
297					aptr->al_adaptor_str = val.str;
298					ptr->scrn_adaptor_lst = (XF86ConfAdaptorLinkPtr)
299						xf86addListItem ((glp) ptr->scrn_adaptor_lst, (glp) aptr);
300				}
301			}
302			break;
303		case VIRTUAL:
304			if (xf86getSubToken (&(ptr->scrn_comment)) != NUMBER)
305				Error (VIRTUAL_MSG, NULL);
306			ptr->scrn_virtualX = val.num;
307			if (xf86getSubToken (&(ptr->scrn_comment)) != NUMBER)
308				Error (VIRTUAL_MSG, NULL);
309			ptr->scrn_virtualY = val.num;
310			break;
311		case OPTION:
312			ptr->scrn_option_lst = xf86parseOption(ptr->scrn_option_lst);
313			break;
314		case SUBSECTION:
315			if (xf86getSubToken (&(ptr->scrn_comment)) != STRING)
316				Error (QUOTE_MSG, "SubSection");
317			{
318				free(val.str);
319				HANDLE_LIST (scrn_display_lst, xf86parseDisplaySubSection,
320							 XF86ConfDisplayPtr);
321			}
322			break;
323		case EOF_TOKEN:
324			Error (UNEXPECTED_EOF_MSG, NULL);
325			break;
326		default:
327			Error (INVALID_KEYWORD_MSG, xf86tokenString ());
328			break;
329		}
330	}
331
332	if (!has_ident && !has_driver)
333		Error (NO_IDENT_MSG, NULL);
334
335#ifdef DEBUG
336	printf ("Screen section parsed\n");
337#endif
338
339	return ptr;
340}
341
342void
343xf86printScreenSection (FILE * cf, XF86ConfScreenPtr ptr)
344{
345	XF86ConfAdaptorLinkPtr aptr;
346	XF86ConfDisplayPtr dptr;
347	XF86ModePtr mptr;
348
349	while (ptr)
350	{
351		fprintf (cf, "Section \"Screen\"\n");
352		if (ptr->scrn_comment)
353			fprintf (cf, "%s", ptr->scrn_comment);
354		if (ptr->scrn_identifier)
355			fprintf (cf, "\tIdentifier \"%s\"\n", ptr->scrn_identifier);
356		if (ptr->scrn_obso_driver)
357			fprintf (cf, "\tDriver     \"%s\"\n", ptr->scrn_obso_driver);
358		if (ptr->scrn_device_str)
359			fprintf (cf, "\tDevice     \"%s\"\n", ptr->scrn_device_str);
360		if (ptr->scrn_monitor_str)
361			fprintf (cf, "\tMonitor    \"%s\"\n", ptr->scrn_monitor_str);
362		if (ptr->scrn_defaultdepth)
363			fprintf (cf, "\tDefaultDepth     %d\n",
364					 ptr->scrn_defaultdepth);
365		if (ptr->scrn_defaultbpp)
366			fprintf (cf, "\tDefaultBPP     %d\n",
367					 ptr->scrn_defaultbpp);
368		if (ptr->scrn_defaultfbbpp)
369			fprintf (cf, "\tDefaultFbBPP     %d\n",
370					 ptr->scrn_defaultfbbpp);
371		xf86printOptionList(cf, ptr->scrn_option_lst, 1);
372		for (aptr = ptr->scrn_adaptor_lst; aptr; aptr = aptr->list.next)
373		{
374			fprintf (cf, "\tVideoAdaptor \"%s\"\n", aptr->al_adaptor_str);
375		}
376		if (ptr->scrn_virtualX && ptr->scrn_virtualY)
377			fprintf (cf, "\tVirtual     %d %d\n",
378				 ptr->scrn_virtualX,
379				 ptr->scrn_virtualY);
380		for (dptr = ptr->scrn_display_lst; dptr; dptr = dptr->list.next)
381		{
382			fprintf (cf, "\tSubSection \"Display\"\n");
383			if (dptr->disp_comment)
384				fprintf (cf, "%s", dptr->disp_comment);
385			if (dptr->disp_frameX0 >= 0 || dptr->disp_frameY0 >= 0)
386			{
387				fprintf (cf, "\t\tViewport   %d %d\n",
388						 dptr->disp_frameX0, dptr->disp_frameY0);
389			}
390			if (dptr->disp_virtualX != 0 || dptr->disp_virtualY != 0)
391			{
392				fprintf (cf, "\t\tVirtual   %d %d\n",
393						 dptr->disp_virtualX, dptr->disp_virtualY);
394			}
395			if (dptr->disp_depth)
396			{
397				fprintf (cf, "\t\tDepth     %d\n", dptr->disp_depth);
398			}
399			if (dptr->disp_bpp)
400			{
401				fprintf (cf, "\t\tFbBPP     %d\n", dptr->disp_bpp);
402			}
403			if (dptr->disp_visual)
404			{
405				fprintf (cf, "\t\tVisual    \"%s\"\n", dptr->disp_visual);
406			}
407			if (dptr->disp_weight.red != 0)
408			{
409				fprintf (cf, "\t\tWeight    %d %d %d\n",
410					 dptr->disp_weight.red, dptr->disp_weight.green, dptr->disp_weight.blue);
411			}
412			if (dptr->disp_black.red != -1)
413			{
414				fprintf (cf, "\t\tBlack     0x%04x 0x%04x 0x%04x\n",
415					  dptr->disp_black.red, dptr->disp_black.green, dptr->disp_black.blue);
416			}
417			if (dptr->disp_white.red != -1)
418			{
419				fprintf (cf, "\t\tWhite     0x%04x 0x%04x 0x%04x\n",
420					  dptr->disp_white.red, dptr->disp_white.green, dptr->disp_white.blue);
421			}
422			if (dptr->disp_mode_lst)
423			{
424				fprintf (cf, "\t\tModes   ");
425			}
426			for (mptr = dptr->disp_mode_lst; mptr; mptr = mptr->list.next)
427			{
428				fprintf (cf, " \"%s\"", mptr->mode_name);
429			}
430			if (dptr->disp_mode_lst)
431			{
432				fprintf (cf, "\n");
433			}
434			xf86printOptionList(cf, dptr->disp_option_lst, 2);
435			fprintf (cf, "\tEndSubSection\n");
436		}
437		fprintf (cf, "EndSection\n\n");
438		ptr = ptr->list.next;
439	}
440
441}
442
443void
444xf86freeScreenList (XF86ConfScreenPtr ptr)
445{
446	XF86ConfScreenPtr prev;
447
448	while (ptr)
449	{
450		TestFree (ptr->scrn_identifier);
451		TestFree (ptr->scrn_monitor_str);
452		TestFree (ptr->scrn_device_str);
453		TestFree (ptr->scrn_comment);
454		xf86optionListFree (ptr->scrn_option_lst);
455		xf86freeAdaptorLinkList (ptr->scrn_adaptor_lst);
456		xf86freeDisplayList (ptr->scrn_display_lst);
457		prev = ptr;
458		ptr = ptr->list.next;
459		free (prev);
460	}
461}
462
463void
464xf86freeAdaptorLinkList (XF86ConfAdaptorLinkPtr ptr)
465{
466	XF86ConfAdaptorLinkPtr prev;
467
468	while (ptr)
469	{
470		TestFree (ptr->al_adaptor_str);
471		prev = ptr;
472		ptr = ptr->list.next;
473		free (prev);
474	}
475}
476
477void
478xf86freeDisplayList (XF86ConfDisplayPtr ptr)
479{
480	XF86ConfDisplayPtr prev;
481
482	while (ptr)
483	{
484		xf86freeModeList (ptr->disp_mode_lst);
485		xf86optionListFree (ptr->disp_option_lst);
486		prev = ptr;
487		ptr = ptr->list.next;
488		free (prev);
489	}
490}
491
492void
493xf86freeModeList (XF86ModePtr ptr)
494{
495	XF86ModePtr prev;
496
497	while (ptr)
498	{
499		TestFree (ptr->mode_name);
500		prev = ptr;
501		ptr = ptr->list.next;
502		free (prev);
503	}
504}
505
506int
507xf86validateScreen (XF86ConfigPtr p)
508{
509	XF86ConfScreenPtr screen = p->conf_screen_lst;
510	XF86ConfMonitorPtr monitor;
511	XF86ConfAdaptorLinkPtr adaptor;
512
513	while (screen)
514	{
515		if (screen->scrn_obso_driver && !screen->scrn_identifier)
516			screen->scrn_identifier = screen->scrn_obso_driver;
517
518		monitor = xf86findMonitor (screen->scrn_monitor_str, p->conf_monitor_lst);
519		if (screen->scrn_monitor_str)
520		{
521			if (monitor)
522			{
523				screen->scrn_monitor = monitor;
524				if (!xf86validateMonitor(p, screen))
525					return FALSE;
526			}
527		}
528
529		screen->scrn_device= xf86findDevice (screen->scrn_device_str, p->conf_device_lst);
530
531		adaptor = screen->scrn_adaptor_lst;
532		while (adaptor)
533		{
534			adaptor->al_adaptor = xf86findVideoAdaptor (adaptor->al_adaptor_str, p->conf_videoadaptor_lst);
535			if (!adaptor->al_adaptor)
536			{
537				xf86validationError (UNDEFINED_ADAPTOR_MSG, adaptor->al_adaptor_str, screen->scrn_identifier);
538				return FALSE;
539			}
540			else if (adaptor->al_adaptor->va_fwdref)
541			{
542				xf86validationError (ADAPTOR_REF_TWICE_MSG, adaptor->al_adaptor_str,
543						     adaptor->al_adaptor->va_fwdref);
544				return FALSE;
545			}
546
547			adaptor->al_adaptor->va_fwdref = strdup(screen->scrn_identifier);
548			adaptor = adaptor->list.next;
549		}
550
551		screen = screen->list.next;
552	}
553
554	return TRUE;
555}
556
557XF86ConfScreenPtr
558xf86findScreen (const char *ident, XF86ConfScreenPtr p)
559{
560	while (p)
561	{
562		if (xf86nameCompare (ident, p->scrn_identifier) == 0)
563			return p;
564
565		p = p->list.next;
566	}
567	return NULL;
568}
569
570