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