Screen.c revision 58cf2af7
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#ifdef HAVE_XORG_CONFIG_H
56#include <xorg-config.h>
57#endif
58
59#include "xf86Parser.h"
60#include "xf86tokens.h"
61#include "Configint.h"
62
63
64static const xf86ConfigSymTabRec DisplayTab[] = {
65    {ENDSUBSECTION, "endsubsection"},
66    {MODES, "modes"},
67    {VIEWPORT, "viewport"},
68    {VIRTUAL, "virtual"},
69    {VISUAL, "visual"},
70    {BLACK_TOK, "black"},
71    {WHITE_TOK, "white"},
72    {DEPTH, "depth"},
73    {BPP, "fbbpp"},
74    {WEIGHT, "weight"},
75    {OPTION, "option"},
76    {-1, ""},
77};
78
79static void
80xf86freeModeList(XF86ModePtr ptr)
81{
82    XF86ModePtr prev;
83
84    while (ptr) {
85        TestFree(ptr->mode_name);
86        prev = ptr;
87        ptr = ptr->list.next;
88        free(prev);
89    }
90}
91
92static void
93xf86freeDisplayList(XF86ConfDisplayPtr ptr)
94{
95    XF86ConfDisplayPtr prev;
96
97    while (ptr) {
98        xf86freeModeList(ptr->disp_mode_lst);
99        xf86optionListFree(ptr->disp_option_lst);
100        prev = ptr;
101        ptr = ptr->list.next;
102        free(prev);
103    }
104}
105
106#define CLEANUP xf86freeDisplayList
107
108static XF86ConfDisplayPtr
109xf86parseDisplaySubSection(void)
110{
111    int token;
112
113    parsePrologue(XF86ConfDisplayPtr, XF86ConfDisplayRec)
114
115        ptr->disp_black.red = ptr->disp_black.green = ptr->disp_black.blue = -1;
116    ptr->disp_white.red = ptr->disp_white.green = ptr->disp_white.blue = -1;
117    ptr->disp_frameX0 = ptr->disp_frameY0 = -1;
118    while ((token = xf86getToken(DisplayTab)) != ENDSUBSECTION) {
119        switch (token) {
120        case COMMENT:
121            ptr->disp_comment = xf86addComment(ptr->disp_comment, xf86_lex_val.str);
122            free(xf86_lex_val.str);
123            xf86_lex_val.str = NULL;
124            break;
125        case VIEWPORT:
126            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
127                Error(VIEWPORT_MSG);
128            ptr->disp_frameX0 = xf86_lex_val.num;
129            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
130                Error(VIEWPORT_MSG);
131            ptr->disp_frameY0 = xf86_lex_val.num;
132            break;
133        case VIRTUAL:
134            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
135                Error(VIRTUAL_MSG);
136            ptr->disp_virtualX = xf86_lex_val.num;
137            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
138                Error(VIRTUAL_MSG);
139            ptr->disp_virtualY = xf86_lex_val.num;
140            break;
141        case DEPTH:
142            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
143                Error(NUMBER_MSG, "Display");
144            ptr->disp_depth = xf86_lex_val.num;
145            break;
146        case BPP:
147            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
148                Error(NUMBER_MSG, "Display");
149            ptr->disp_bpp = xf86_lex_val.num;
150            break;
151        case VISUAL:
152            if (xf86getSubToken(&(ptr->disp_comment)) != STRING)
153                Error(QUOTE_MSG, "Display");
154            ptr->disp_visual = xf86_lex_val.str;
155            break;
156        case WEIGHT:
157            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
158                Error(WEIGHT_MSG);
159            ptr->disp_weight.red = xf86_lex_val.num;
160            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
161                Error(WEIGHT_MSG);
162            ptr->disp_weight.green = xf86_lex_val.num;
163            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
164                Error(WEIGHT_MSG);
165            ptr->disp_weight.blue = xf86_lex_val.num;
166            break;
167        case BLACK_TOK:
168            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
169                Error(BLACK_MSG);
170            ptr->disp_black.red = xf86_lex_val.num;
171            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
172                Error(BLACK_MSG);
173            ptr->disp_black.green = xf86_lex_val.num;
174            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
175                Error(BLACK_MSG);
176            ptr->disp_black.blue = xf86_lex_val.num;
177            break;
178        case WHITE_TOK:
179            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
180                Error(WHITE_MSG);
181            ptr->disp_white.red = xf86_lex_val.num;
182            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
183                Error(WHITE_MSG);
184            ptr->disp_white.green = xf86_lex_val.num;
185            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
186                Error(WHITE_MSG);
187            ptr->disp_white.blue = xf86_lex_val.num;
188            break;
189        case MODES:
190        {
191            XF86ModePtr mptr;
192
193            while ((token =
194                    xf86getSubTokenWithTab(&(ptr->disp_comment),
195                                           DisplayTab)) == STRING) {
196                mptr = calloc(1, sizeof(XF86ModeRec));
197                mptr->mode_name = xf86_lex_val.str;
198                mptr->list.next = NULL;
199                ptr->disp_mode_lst = (XF86ModePtr)
200                    xf86addListItem((glp) ptr->disp_mode_lst, (glp) mptr);
201            }
202            xf86unGetToken(token);
203        }
204            break;
205        case OPTION:
206            ptr->disp_option_lst = xf86parseOption(ptr->disp_option_lst);
207            break;
208
209        case EOF_TOKEN:
210            Error(UNEXPECTED_EOF_MSG);
211            break;
212        default:
213            Error(INVALID_KEYWORD_MSG, xf86tokenString());
214            break;
215        }
216    }
217
218#ifdef DEBUG
219    printf("Display subsection parsed\n");
220#endif
221
222    return ptr;
223}
224
225#undef CLEANUP
226
227static const xf86ConfigSymTabRec ScreenTab[] = {
228    {ENDSECTION, "endsection"},
229    {IDENTIFIER, "identifier"},
230    {MATCHSEAT, "matchseat"},
231    {OBSDRIVER, "driver"},
232    {MDEVICE, "device"},
233    {MONITOR, "monitor"},
234    {VIDEOADAPTOR, "videoadaptor"},
235    {SCREENNO, "screenno"},
236    {SUBSECTION, "subsection"},
237    {DEFAULTDEPTH, "defaultcolordepth"},
238    {DEFAULTDEPTH, "defaultdepth"},
239    {DEFAULTBPP, "defaultbpp"},
240    {DEFAULTFBBPP, "defaultfbbpp"},
241    {VIRTUAL, "virtual"},
242    {OPTION, "option"},
243    {GDEVICE, "gpudevice"},
244    {-1, ""},
245};
246
247#define CLEANUP xf86freeScreenList
248XF86ConfScreenPtr
249xf86parseScreenSection(void)
250{
251    int has_ident = FALSE;
252    int has_driver = FALSE;
253    int token;
254
255    parsePrologue(XF86ConfScreenPtr, XF86ConfScreenRec)
256
257        while ((token = xf86getToken(ScreenTab)) != ENDSECTION) {
258        switch (token) {
259        case COMMENT:
260            ptr->scrn_comment = xf86addComment(ptr->scrn_comment, xf86_lex_val.str);
261            free(xf86_lex_val.str);
262            xf86_lex_val.str = NULL;
263            break;
264        case IDENTIFIER:
265            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
266                Error(QUOTE_MSG, "Identifier");
267            ptr->scrn_identifier = xf86_lex_val.str;
268            if (has_ident || has_driver)
269                Error(ONLY_ONE_MSG, "Identifier or Driver");
270            has_ident = TRUE;
271            break;
272        case MATCHSEAT:
273            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
274                Error(QUOTE_MSG, "MatchSeat");
275            ptr->match_seat = xf86_lex_val.str;
276            break;
277        case OBSDRIVER:
278            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
279                Error(QUOTE_MSG, "Driver");
280            ptr->scrn_obso_driver = xf86_lex_val.str;
281            if (has_ident || has_driver)
282                Error(ONLY_ONE_MSG, "Identifier or Driver");
283            has_driver = TRUE;
284            break;
285        case DEFAULTDEPTH:
286            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
287                Error(NUMBER_MSG, "DefaultDepth");
288            ptr->scrn_defaultdepth = xf86_lex_val.num;
289            break;
290        case DEFAULTBPP:
291            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
292                Error(NUMBER_MSG, "DefaultBPP");
293            ptr->scrn_defaultbpp = xf86_lex_val.num;
294            break;
295        case DEFAULTFBBPP:
296            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
297                Error(NUMBER_MSG, "DefaultFbBPP");
298            ptr->scrn_defaultfbbpp = xf86_lex_val.num;
299            break;
300        case MDEVICE:
301            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
302                Error(QUOTE_MSG, "Device");
303            ptr->scrn_device_str = xf86_lex_val.str;
304            break;
305        case GDEVICE:
306            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
307                Error(QUOTE_MSG, "GPUDevice");
308            if (ptr->num_gpu_devices == CONF_MAXGPUDEVICES)
309                Error(GPU_DEVICE_TOO_MANY, CONF_MAXGPUDEVICES);
310            ptr->scrn_gpu_device_str[ptr->num_gpu_devices++] = xf86_lex_val.str;
311            break;
312        case MONITOR:
313            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
314                Error(QUOTE_MSG, "Monitor");
315            ptr->scrn_monitor_str = xf86_lex_val.str;
316            break;
317        case VIDEOADAPTOR:
318        {
319            XF86ConfAdaptorLinkPtr aptr;
320
321            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
322                Error(QUOTE_MSG, "VideoAdaptor");
323
324            /* Don't allow duplicates */
325            for (aptr = ptr->scrn_adaptor_lst; aptr;
326                 aptr = (XF86ConfAdaptorLinkPtr) aptr->list.next)
327                if (xf86nameCompare(xf86_lex_val.str, aptr->al_adaptor_str) == 0)
328                    break;
329
330            if (aptr == NULL) {
331                aptr = calloc(1, sizeof(XF86ConfAdaptorLinkRec));
332                aptr->list.next = NULL;
333                aptr->al_adaptor_str = xf86_lex_val.str;
334                ptr->scrn_adaptor_lst = (XF86ConfAdaptorLinkPtr)
335                    xf86addListItem((glp) ptr->scrn_adaptor_lst, (glp) aptr);
336            }
337        }
338            break;
339        case VIRTUAL:
340            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
341                Error(VIRTUAL_MSG);
342            ptr->scrn_virtualX = xf86_lex_val.num;
343            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
344                Error(VIRTUAL_MSG);
345            ptr->scrn_virtualY = xf86_lex_val.num;
346            break;
347        case OPTION:
348            ptr->scrn_option_lst = xf86parseOption(ptr->scrn_option_lst);
349            break;
350        case SUBSECTION:
351            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
352                Error(QUOTE_MSG, "SubSection");
353            {
354                free(xf86_lex_val.str);
355                HANDLE_LIST(scrn_display_lst, xf86parseDisplaySubSection,
356                            XF86ConfDisplayPtr);
357            }
358            break;
359        case EOF_TOKEN:
360            Error(UNEXPECTED_EOF_MSG);
361            break;
362        default:
363            Error(INVALID_KEYWORD_MSG, xf86tokenString());
364            break;
365        }
366    }
367
368    if (!has_ident && !has_driver)
369        Error(NO_IDENT_MSG);
370
371#ifdef DEBUG
372    printf("Screen section parsed\n");
373#endif
374
375    return ptr;
376}
377
378void
379xf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr)
380{
381    XF86ConfAdaptorLinkPtr aptr;
382    XF86ConfDisplayPtr dptr;
383    XF86ModePtr mptr;
384    int i;
385    while (ptr) {
386        fprintf(cf, "Section \"Screen\"\n");
387        if (ptr->scrn_comment)
388            fprintf(cf, "%s", ptr->scrn_comment);
389        if (ptr->scrn_identifier)
390            fprintf(cf, "\tIdentifier \"%s\"\n", ptr->scrn_identifier);
391        if (ptr->scrn_obso_driver)
392            fprintf(cf, "\tDriver     \"%s\"\n", ptr->scrn_obso_driver);
393        if (ptr->scrn_device_str)
394            fprintf(cf, "\tDevice     \"%s\"\n", ptr->scrn_device_str);
395        for (i = 0; i < ptr->num_gpu_devices; i++)
396            if (ptr->scrn_gpu_device_str[i])
397                fprintf(cf, "\tGPUDevice     \"%s\"\n", ptr->scrn_gpu_device_str[i]);
398        if (ptr->scrn_monitor_str)
399            fprintf(cf, "\tMonitor    \"%s\"\n", ptr->scrn_monitor_str);
400        if (ptr->scrn_defaultdepth)
401            fprintf(cf, "\tDefaultDepth     %d\n", ptr->scrn_defaultdepth);
402        if (ptr->scrn_defaultbpp)
403            fprintf(cf, "\tDefaultBPP     %d\n", ptr->scrn_defaultbpp);
404        if (ptr->scrn_defaultfbbpp)
405            fprintf(cf, "\tDefaultFbBPP     %d\n", ptr->scrn_defaultfbbpp);
406        xf86printOptionList(cf, ptr->scrn_option_lst, 1);
407        for (aptr = ptr->scrn_adaptor_lst; aptr; aptr = aptr->list.next) {
408            fprintf(cf, "\tVideoAdaptor \"%s\"\n", aptr->al_adaptor_str);
409        }
410        if (ptr->scrn_virtualX && ptr->scrn_virtualY)
411            fprintf(cf, "\tVirtual     %d %d\n",
412                    ptr->scrn_virtualX, ptr->scrn_virtualY);
413        for (dptr = ptr->scrn_display_lst; dptr; dptr = dptr->list.next) {
414            fprintf(cf, "\tSubSection \"Display\"\n");
415            if (dptr->disp_comment)
416                fprintf(cf, "%s", dptr->disp_comment);
417            if (dptr->disp_frameX0 >= 0 || dptr->disp_frameY0 >= 0) {
418                fprintf(cf, "\t\tViewport   %d %d\n",
419                        dptr->disp_frameX0, dptr->disp_frameY0);
420            }
421            if (dptr->disp_virtualX != 0 || dptr->disp_virtualY != 0) {
422                fprintf(cf, "\t\tVirtual   %d %d\n",
423                        dptr->disp_virtualX, dptr->disp_virtualY);
424            }
425            if (dptr->disp_depth) {
426                fprintf(cf, "\t\tDepth     %d\n", dptr->disp_depth);
427            }
428            if (dptr->disp_bpp) {
429                fprintf(cf, "\t\tFbBPP     %d\n", dptr->disp_bpp);
430            }
431            if (dptr->disp_visual) {
432                fprintf(cf, "\t\tVisual    \"%s\"\n", dptr->disp_visual);
433            }
434            if (dptr->disp_weight.red != 0) {
435                fprintf(cf, "\t\tWeight    %d %d %d\n",
436                        dptr->disp_weight.red, dptr->disp_weight.green,
437                        dptr->disp_weight.blue);
438            }
439            if (dptr->disp_black.red != -1) {
440                fprintf(cf, "\t\tBlack     0x%04x 0x%04x 0x%04x\n",
441                        dptr->disp_black.red, dptr->disp_black.green,
442                        dptr->disp_black.blue);
443            }
444            if (dptr->disp_white.red != -1) {
445                fprintf(cf, "\t\tWhite     0x%04x 0x%04x 0x%04x\n",
446                        dptr->disp_white.red, dptr->disp_white.green,
447                        dptr->disp_white.blue);
448            }
449            if (dptr->disp_mode_lst) {
450                fprintf(cf, "\t\tModes   ");
451            }
452            for (mptr = dptr->disp_mode_lst; mptr; mptr = mptr->list.next) {
453                fprintf(cf, " \"%s\"", mptr->mode_name);
454            }
455            if (dptr->disp_mode_lst) {
456                fprintf(cf, "\n");
457            }
458            xf86printOptionList(cf, dptr->disp_option_lst, 2);
459            fprintf(cf, "\tEndSubSection\n");
460        }
461        fprintf(cf, "EndSection\n\n");
462        ptr = ptr->list.next;
463    }
464
465}
466
467static void
468xf86freeAdaptorLinkList(XF86ConfAdaptorLinkPtr ptr)
469{
470    XF86ConfAdaptorLinkPtr prev;
471
472    while (ptr) {
473        TestFree(ptr->al_adaptor_str);
474        prev = ptr;
475        ptr = ptr->list.next;
476        free(prev);
477    }
478}
479
480void
481xf86freeScreenList(XF86ConfScreenPtr ptr)
482{
483    XF86ConfScreenPtr prev;
484    int i;
485    while (ptr) {
486        TestFree(ptr->scrn_identifier);
487        TestFree(ptr->scrn_monitor_str);
488        TestFree(ptr->scrn_device_str);
489        for (i = 0; i < ptr->num_gpu_devices; i++)
490            TestFree(ptr->scrn_gpu_device_str[i]);
491        TestFree(ptr->scrn_comment);
492        xf86optionListFree(ptr->scrn_option_lst);
493        xf86freeAdaptorLinkList(ptr->scrn_adaptor_lst);
494        xf86freeDisplayList(ptr->scrn_display_lst);
495        prev = ptr;
496        ptr = ptr->list.next;
497        free(prev);
498    }
499}
500
501int
502xf86validateScreen(XF86ConfigPtr p)
503{
504    XF86ConfScreenPtr screen = p->conf_screen_lst;
505    XF86ConfMonitorPtr monitor;
506    XF86ConfAdaptorLinkPtr adaptor;
507    int i;
508
509    while (screen) {
510        if (screen->scrn_obso_driver && !screen->scrn_identifier)
511            screen->scrn_identifier = screen->scrn_obso_driver;
512
513        monitor =
514            xf86findMonitor(screen->scrn_monitor_str, p->conf_monitor_lst);
515        if (screen->scrn_monitor_str) {
516            if (monitor) {
517                screen->scrn_monitor = monitor;
518                if (!xf86validateMonitor(p, screen))
519                    return FALSE;
520            }
521        }
522
523        screen->scrn_device =
524            xf86findDevice(screen->scrn_device_str, p->conf_device_lst);
525
526        for (i = 0; i < screen->num_gpu_devices; i++) {
527            screen->scrn_gpu_devices[i] =
528                xf86findDevice(screen->scrn_gpu_device_str[i], p->conf_device_lst);
529        }
530        adaptor = screen->scrn_adaptor_lst;
531        while (adaptor) {
532            adaptor->al_adaptor =
533                xf86findVideoAdaptor(adaptor->al_adaptor_str,
534                                     p->conf_videoadaptor_lst);
535            if (!adaptor->al_adaptor) {
536                xf86validationError(UNDEFINED_ADAPTOR_MSG,
537                                    adaptor->al_adaptor_str,
538                                    screen->scrn_identifier);
539                return FALSE;
540            }
541            else if (adaptor->al_adaptor->va_fwdref) {
542                xf86validationError(ADAPTOR_REF_TWICE_MSG,
543                                    adaptor->al_adaptor_str,
544                                    adaptor->al_adaptor->va_fwdref);
545                return FALSE;
546            }
547
548            adaptor->al_adaptor->va_fwdref = strdup(screen->scrn_identifier);
549            adaptor = adaptor->list.next;
550        }
551
552        screen = screen->list.next;
553    }
554
555    return TRUE;
556}
557
558XF86ConfScreenPtr
559xf86findScreen(const char *ident, XF86ConfScreenPtr p)
560{
561    while (p) {
562        if (xf86nameCompare(ident, p->scrn_identifier) == 0)
563            return p;
564
565        p = p->list.next;
566    }
567    return NULL;
568}
569