Commit | Line | Data |
---|---|---|
a09e091a JB |
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 | extern LexRec val; | |
64 | ||
65 | static xf86ConfigSymTabRec MonitorTab[] = { | |
66 | {ENDSECTION, "endsection"}, | |
67 | {IDENTIFIER, "identifier"}, | |
68 | {VENDOR, "vendorname"}, | |
69 | {MODEL, "modelname"}, | |
70 | {USEMODES, "usemodes"}, | |
71 | {MODELINE, "modeline"}, | |
72 | {DISPLAYSIZE, "displaysize"}, | |
73 | {HORIZSYNC, "horizsync"}, | |
74 | {VERTREFRESH, "vertrefresh"}, | |
75 | {MODE, "mode"}, | |
76 | {GAMMA, "gamma"}, | |
77 | {OPTION, "option"}, | |
78 | {-1, ""}, | |
79 | }; | |
80 | ||
81 | static xf86ConfigSymTabRec ModesTab[] = { | |
82 | {ENDSECTION, "endsection"}, | |
83 | {IDENTIFIER, "identifier"}, | |
84 | {MODELINE, "modeline"}, | |
85 | {MODE, "mode"}, | |
86 | {-1, ""}, | |
87 | }; | |
88 | ||
89 | static xf86ConfigSymTabRec TimingTab[] = { | |
90 | {TT_INTERLACE, "interlace"}, | |
91 | {TT_PHSYNC, "+hsync"}, | |
92 | {TT_NHSYNC, "-hsync"}, | |
93 | {TT_PVSYNC, "+vsync"}, | |
94 | {TT_NVSYNC, "-vsync"}, | |
95 | {TT_CSYNC, "composite"}, | |
96 | {TT_PCSYNC, "+csync"}, | |
97 | {TT_NCSYNC, "-csync"}, | |
98 | {TT_DBLSCAN, "doublescan"}, | |
99 | {TT_HSKEW, "hskew"}, | |
100 | {TT_BCAST, "bcast"}, | |
101 | {TT_VSCAN, "vscan"}, | |
102 | {-1, ""}, | |
103 | }; | |
104 | ||
105 | static xf86ConfigSymTabRec ModeTab[] = { | |
106 | {DOTCLOCK, "dotclock"}, | |
107 | {HTIMINGS, "htimings"}, | |
108 | {VTIMINGS, "vtimings"}, | |
109 | {FLAGS, "flags"}, | |
110 | {HSKEW, "hskew"}, | |
111 | {BCAST, "bcast"}, | |
112 | {VSCAN, "vscan"}, | |
113 | {ENDMODE, "endmode"}, | |
114 | {-1, ""}, | |
115 | }; | |
116 | ||
117 | #define CLEANUP xf86freeModeLineList | |
118 | ||
119 | static void | |
120 | xf86freeModeLineList(XF86ConfModeLinePtr ptr) | |
121 | { | |
122 | XF86ConfModeLinePtr prev; | |
123 | ||
124 | while (ptr) { | |
125 | TestFree(ptr->ml_identifier); | |
126 | TestFree(ptr->ml_comment); | |
127 | prev = ptr; | |
128 | ptr = ptr->list.next; | |
129 | free(prev); | |
130 | } | |
131 | } | |
132 | ||
133 | static XF86ConfModeLinePtr | |
134 | xf86parseModeLine(void) | |
135 | { | |
136 | int token; | |
137 | ||
138 | parsePrologue(XF86ConfModeLinePtr, XF86ConfModeLineRec) | |
139 | ||
140 | /* Identifier */ | |
141 | if (xf86getSubToken(&(ptr->ml_comment)) != STRING) | |
142 | Error("ModeLine identifier expected"); | |
143 | ptr->ml_identifier = val.str; | |
144 | ||
145 | /* DotClock */ | |
146 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
147 | Error("ModeLine dotclock expected"); | |
148 | ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5); | |
149 | ||
150 | /* HDisplay */ | |
151 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
152 | Error("ModeLine Hdisplay expected"); | |
153 | ptr->ml_hdisplay = val.num; | |
154 | ||
155 | /* HSyncStart */ | |
156 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
157 | Error("ModeLine HSyncStart expected"); | |
158 | ptr->ml_hsyncstart = val.num; | |
159 | ||
160 | /* HSyncEnd */ | |
161 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
162 | Error("ModeLine HSyncEnd expected"); | |
163 | ptr->ml_hsyncend = val.num; | |
164 | ||
165 | /* HTotal */ | |
166 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
167 | Error("ModeLine HTotal expected"); | |
168 | ptr->ml_htotal = val.num; | |
169 | ||
170 | /* VDisplay */ | |
171 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
172 | Error("ModeLine Vdisplay expected"); | |
173 | ptr->ml_vdisplay = val.num; | |
174 | ||
175 | /* VSyncStart */ | |
176 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
177 | Error("ModeLine VSyncStart expected"); | |
178 | ptr->ml_vsyncstart = val.num; | |
179 | ||
180 | /* VSyncEnd */ | |
181 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
182 | Error("ModeLine VSyncEnd expected"); | |
183 | ptr->ml_vsyncend = val.num; | |
184 | ||
185 | /* VTotal */ | |
186 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
187 | Error("ModeLine VTotal expected"); | |
188 | ptr->ml_vtotal = val.num; | |
189 | ||
190 | token = xf86getSubTokenWithTab(&(ptr->ml_comment), TimingTab); | |
191 | while ((token == TT_INTERLACE) || (token == TT_PHSYNC) || | |
192 | (token == TT_NHSYNC) || (token == TT_PVSYNC) || | |
193 | (token == TT_NVSYNC) || (token == TT_CSYNC) || | |
194 | (token == TT_PCSYNC) || (token == TT_NCSYNC) || | |
195 | (token == TT_DBLSCAN) || (token == TT_HSKEW) || | |
196 | (token == TT_VSCAN) || (token == TT_BCAST)) { | |
197 | switch (token) { | |
198 | ||
199 | case TT_INTERLACE: | |
200 | ptr->ml_flags |= XF86CONF_INTERLACE; | |
201 | break; | |
202 | case TT_PHSYNC: | |
203 | ptr->ml_flags |= XF86CONF_PHSYNC; | |
204 | break; | |
205 | case TT_NHSYNC: | |
206 | ptr->ml_flags |= XF86CONF_NHSYNC; | |
207 | break; | |
208 | case TT_PVSYNC: | |
209 | ptr->ml_flags |= XF86CONF_PVSYNC; | |
210 | break; | |
211 | case TT_NVSYNC: | |
212 | ptr->ml_flags |= XF86CONF_NVSYNC; | |
213 | break; | |
214 | case TT_CSYNC: | |
215 | ptr->ml_flags |= XF86CONF_CSYNC; | |
216 | break; | |
217 | case TT_PCSYNC: | |
218 | ptr->ml_flags |= XF86CONF_PCSYNC; | |
219 | break; | |
220 | case TT_NCSYNC: | |
221 | ptr->ml_flags |= XF86CONF_NCSYNC; | |
222 | break; | |
223 | case TT_DBLSCAN: | |
224 | ptr->ml_flags |= XF86CONF_DBLSCAN; | |
225 | break; | |
226 | case TT_HSKEW: | |
227 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
228 | Error(NUMBER_MSG, "Hskew"); | |
229 | ptr->ml_hskew = val.num; | |
230 | ptr->ml_flags |= XF86CONF_HSKEW; | |
231 | break; | |
232 | case TT_BCAST: | |
233 | ptr->ml_flags |= XF86CONF_BCAST; | |
234 | break; | |
235 | case TT_VSCAN: | |
236 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
237 | Error(NUMBER_MSG, "Vscan"); | |
238 | ptr->ml_vscan = val.num; | |
239 | ptr->ml_flags |= XF86CONF_VSCAN; | |
240 | break; | |
241 | case EOF_TOKEN: | |
242 | Error(UNEXPECTED_EOF_MSG); | |
243 | break; | |
244 | default: | |
245 | Error(INVALID_KEYWORD_MSG, xf86tokenString()); | |
246 | break; | |
247 | } | |
248 | token = xf86getSubTokenWithTab(&(ptr->ml_comment), TimingTab); | |
249 | } | |
250 | xf86unGetToken(token); | |
251 | ||
252 | #ifdef DEBUG | |
253 | printf("ModeLine parsed\n"); | |
254 | #endif | |
255 | return ptr; | |
256 | } | |
257 | ||
258 | static XF86ConfModeLinePtr | |
259 | xf86parseVerboseMode(void) | |
260 | { | |
261 | int token, token2; | |
262 | int had_dotclock = 0, had_htimings = 0, had_vtimings = 0; | |
263 | ||
264 | parsePrologue(XF86ConfModeLinePtr, XF86ConfModeLineRec) | |
265 | ||
266 | if (xf86getSubToken(&(ptr->ml_comment)) != STRING) | |
267 | Error("Mode name expected"); | |
268 | ptr->ml_identifier = val.str; | |
269 | while ((token = xf86getToken(ModeTab)) != ENDMODE) { | |
270 | switch (token) { | |
271 | case COMMENT: | |
272 | ptr->ml_comment = xf86addComment(ptr->ml_comment, val.str); | |
273 | break; | |
274 | case DOTCLOCK: | |
275 | if ((token = xf86getSubToken(&(ptr->ml_comment))) != NUMBER) | |
276 | Error(NUMBER_MSG, "DotClock"); | |
277 | ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5); | |
278 | had_dotclock = 1; | |
279 | break; | |
280 | case HTIMINGS: | |
281 | if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER) | |
282 | ptr->ml_hdisplay = val.num; | |
283 | else | |
284 | Error("Horizontal display expected"); | |
285 | ||
286 | if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER) | |
287 | ptr->ml_hsyncstart = val.num; | |
288 | else | |
289 | Error("Horizontal sync start expected"); | |
290 | ||
291 | if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER) | |
292 | ptr->ml_hsyncend = val.num; | |
293 | else | |
294 | Error("Horizontal sync end expected"); | |
295 | ||
296 | if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER) | |
297 | ptr->ml_htotal = val.num; | |
298 | else | |
299 | Error("Horizontal total expected"); | |
300 | had_htimings = 1; | |
301 | break; | |
302 | case VTIMINGS: | |
303 | if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER) | |
304 | ptr->ml_vdisplay = val.num; | |
305 | else | |
306 | Error("Vertical display expected"); | |
307 | ||
308 | if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER) | |
309 | ptr->ml_vsyncstart = val.num; | |
310 | else | |
311 | Error("Vertical sync start expected"); | |
312 | ||
313 | if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER) | |
314 | ptr->ml_vsyncend = val.num; | |
315 | else | |
316 | Error("Vertical sync end expected"); | |
317 | ||
318 | if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER) | |
319 | ptr->ml_vtotal = val.num; | |
320 | else | |
321 | Error("Vertical total expected"); | |
322 | had_vtimings = 1; | |
323 | break; | |
324 | case FLAGS: | |
325 | token = xf86getSubToken(&(ptr->ml_comment)); | |
326 | if (token != STRING) | |
327 | Error(QUOTE_MSG, "Flags"); | |
328 | while (token == STRING) { | |
329 | token2 = xf86getStringToken(TimingTab); | |
330 | switch (token2) { | |
331 | case TT_INTERLACE: | |
332 | ptr->ml_flags |= XF86CONF_INTERLACE; | |
333 | break; | |
334 | case TT_PHSYNC: | |
335 | ptr->ml_flags |= XF86CONF_PHSYNC; | |
336 | break; | |
337 | case TT_NHSYNC: | |
338 | ptr->ml_flags |= XF86CONF_NHSYNC; | |
339 | break; | |
340 | case TT_PVSYNC: | |
341 | ptr->ml_flags |= XF86CONF_PVSYNC; | |
342 | break; | |
343 | case TT_NVSYNC: | |
344 | ptr->ml_flags |= XF86CONF_NVSYNC; | |
345 | break; | |
346 | case TT_CSYNC: | |
347 | ptr->ml_flags |= XF86CONF_CSYNC; | |
348 | break; | |
349 | case TT_PCSYNC: | |
350 | ptr->ml_flags |= XF86CONF_PCSYNC; | |
351 | break; | |
352 | case TT_NCSYNC: | |
353 | ptr->ml_flags |= XF86CONF_NCSYNC; | |
354 | break; | |
355 | case TT_DBLSCAN: | |
356 | ptr->ml_flags |= XF86CONF_DBLSCAN; | |
357 | break; | |
358 | case EOF_TOKEN: | |
359 | Error(UNEXPECTED_EOF_MSG); | |
360 | break; | |
361 | default: | |
362 | Error("Unknown flag string"); | |
363 | break; | |
364 | } | |
365 | token = xf86getSubToken(&(ptr->ml_comment)); | |
366 | } | |
367 | xf86unGetToken(token); | |
368 | break; | |
369 | case HSKEW: | |
370 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
371 | Error("Horizontal skew expected"); | |
372 | ptr->ml_flags |= XF86CONF_HSKEW; | |
373 | ptr->ml_hskew = val.num; | |
374 | break; | |
375 | case VSCAN: | |
376 | if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER) | |
377 | Error("Vertical scan count expected"); | |
378 | ptr->ml_flags |= XF86CONF_VSCAN; | |
379 | ptr->ml_vscan = val.num; | |
380 | break; | |
381 | case EOF_TOKEN: | |
382 | Error(UNEXPECTED_EOF_MSG); | |
383 | break; | |
384 | default: | |
385 | Error("Unexepcted token in verbose \"Mode\" entry\n"); | |
386 | } | |
387 | } | |
388 | if (!had_dotclock) | |
389 | Error("the dotclock is missing"); | |
390 | if (!had_htimings) | |
391 | Error("the horizontal timings are missing"); | |
392 | if (!had_vtimings) | |
393 | Error("the vertical timings are missing"); | |
394 | ||
395 | #ifdef DEBUG | |
396 | printf("Verbose Mode parsed\n"); | |
397 | #endif | |
398 | return ptr; | |
399 | } | |
400 | ||
401 | #undef CLEANUP | |
402 | ||
403 | #define CLEANUP xf86freeMonitorList | |
404 | ||
405 | XF86ConfMonitorPtr | |
406 | xf86parseMonitorSection(void) | |
407 | { | |
408 | int has_ident = FALSE; | |
409 | int token; | |
410 | ||
411 | parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec) | |
412 | ||
413 | while ((token = xf86getToken(MonitorTab)) != ENDSECTION) { | |
414 | switch (token) { | |
415 | case COMMENT: | |
416 | ptr->mon_comment = xf86addComment(ptr->mon_comment, val.str); | |
417 | break; | |
418 | case IDENTIFIER: | |
419 | if (xf86getSubToken(&(ptr->mon_comment)) != STRING) | |
420 | Error(QUOTE_MSG, "Identifier"); | |
421 | if (has_ident == TRUE) | |
422 | Error(MULTIPLE_MSG, "Identifier"); | |
423 | ptr->mon_identifier = val.str; | |
424 | has_ident = TRUE; | |
425 | break; | |
426 | case VENDOR: | |
427 | if (xf86getSubToken(&(ptr->mon_comment)) != STRING) | |
428 | Error(QUOTE_MSG, "Vendor"); | |
429 | ptr->mon_vendor = val.str; | |
430 | break; | |
431 | case MODEL: | |
432 | if (xf86getSubToken(&(ptr->mon_comment)) != STRING) | |
433 | Error(QUOTE_MSG, "ModelName"); | |
434 | ptr->mon_modelname = val.str; | |
435 | break; | |
436 | case MODE: | |
437 | HANDLE_LIST(mon_modeline_lst, xf86parseVerboseMode, | |
438 | XF86ConfModeLinePtr); | |
439 | break; | |
440 | case MODELINE: | |
441 | HANDLE_LIST(mon_modeline_lst, xf86parseModeLine, | |
442 | XF86ConfModeLinePtr); | |
443 | break; | |
444 | case DISPLAYSIZE: | |
445 | if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER) | |
446 | Error(DISPLAYSIZE_MSG); | |
447 | ptr->mon_width = val.realnum; | |
448 | if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER) | |
449 | Error(DISPLAYSIZE_MSG); | |
450 | ptr->mon_height = val.realnum; | |
451 | break; | |
452 | ||
453 | case HORIZSYNC: | |
454 | if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER) | |
455 | Error(HORIZSYNC_MSG); | |
456 | do { | |
457 | if (ptr->mon_n_hsync >= CONF_MAX_HSYNC) | |
458 | Error("Sorry. Too many horizontal sync intervals."); | |
459 | ptr->mon_hsync[ptr->mon_n_hsync].lo = val.realnum; | |
460 | switch (token = xf86getSubToken(&(ptr->mon_comment))) { | |
461 | case COMMA: | |
462 | ptr->mon_hsync[ptr->mon_n_hsync].hi = | |
463 | ptr->mon_hsync[ptr->mon_n_hsync].lo; | |
464 | break; | |
465 | case DASH: | |
466 | if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER || | |
467 | (float) val.realnum < | |
468 | ptr->mon_hsync[ptr->mon_n_hsync].lo) | |
469 | Error(HORIZSYNC_MSG); | |
470 | ptr->mon_hsync[ptr->mon_n_hsync].hi = val.realnum; | |
471 | if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA) | |
472 | break; | |
473 | ptr->mon_n_hsync++; | |
474 | goto HorizDone; | |
475 | default: | |
476 | /* We cannot currently know if a '\n' was found, | |
477 | * or this is a real error | |
478 | */ | |
479 | ptr->mon_hsync[ptr->mon_n_hsync].hi = | |
480 | ptr->mon_hsync[ptr->mon_n_hsync].lo; | |
481 | ptr->mon_n_hsync++; | |
482 | goto HorizDone; | |
483 | } | |
484 | ptr->mon_n_hsync++; | |
485 | } while ((token = xf86getSubToken(&(ptr->mon_comment))) == NUMBER); | |
486 | HorizDone: | |
487 | xf86unGetToken(token); | |
488 | break; | |
489 | ||
490 | case VERTREFRESH: | |
491 | if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER) | |
492 | Error(VERTREFRESH_MSG); | |
493 | do { | |
494 | ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo = val.realnum; | |
495 | switch (token = xf86getSubToken(&(ptr->mon_comment))) { | |
496 | case COMMA: | |
497 | ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = | |
498 | ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo; | |
499 | break; | |
500 | case DASH: | |
501 | if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER || | |
502 | (float) val.realnum < | |
503 | ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo) | |
504 | Error(VERTREFRESH_MSG); | |
505 | ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = val.realnum; | |
506 | if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA) | |
507 | break; | |
508 | ptr->mon_n_vrefresh++; | |
509 | goto VertDone; | |
510 | default: | |
511 | /* We cannot currently know if a '\n' was found, | |
512 | * or this is a real error | |
513 | */ | |
514 | ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = | |
515 | ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo; | |
516 | ptr->mon_n_vrefresh++; | |
517 | goto VertDone; | |
518 | } | |
519 | if (ptr->mon_n_vrefresh >= CONF_MAX_VREFRESH) | |
520 | Error("Sorry. Too many vertical refresh intervals."); | |
521 | ptr->mon_n_vrefresh++; | |
522 | } while ((token = xf86getSubToken(&(ptr->mon_comment))) == NUMBER); | |
523 | VertDone: | |
524 | xf86unGetToken(token); | |
525 | break; | |
526 | ||
527 | case GAMMA: | |
528 | if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER) { | |
529 | Error(INVALID_GAMMA_MSG); | |
530 | } | |
531 | else { | |
532 | ptr->mon_gamma_red = ptr->mon_gamma_green = | |
533 | ptr->mon_gamma_blue = val.realnum; | |
534 | if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) { | |
535 | ptr->mon_gamma_green = val.realnum; | |
536 | if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) { | |
537 | ptr->mon_gamma_blue = val.realnum; | |
538 | } | |
539 | else { | |
540 | Error(INVALID_GAMMA_MSG); | |
541 | } | |
542 | } | |
543 | else | |
544 | xf86unGetToken(token); | |
545 | } | |
546 | break; | |
547 | case OPTION: | |
548 | ptr->mon_option_lst = xf86parseOption(ptr->mon_option_lst); | |
549 | break; | |
550 | case USEMODES: | |
551 | { | |
552 | XF86ConfModesLinkPtr mptr; | |
553 | ||
554 | if ((token = xf86getSubToken(&(ptr->mon_comment))) != STRING) | |
555 | Error(QUOTE_MSG, "UseModes"); | |
556 | ||
557 | /* add to the end of the list of modes sections | |
558 | referenced here */ | |
559 | mptr = calloc(1, sizeof(XF86ConfModesLinkRec)); | |
560 | mptr->list.next = NULL; | |
561 | mptr->ml_modes_str = val.str; | |
562 | mptr->ml_modes = NULL; | |
563 | ptr->mon_modes_sect_lst = (XF86ConfModesLinkPtr) | |
564 | xf86addListItem((GenericListPtr) ptr->mon_modes_sect_lst, | |
565 | (GenericListPtr) mptr); | |
566 | } | |
567 | break; | |
568 | case EOF_TOKEN: | |
569 | Error(UNEXPECTED_EOF_MSG); | |
570 | break; | |
571 | default: | |
572 | xf86parseError(INVALID_KEYWORD_MSG, xf86tokenString()); | |
573 | CLEANUP(ptr); | |
574 | return NULL; | |
575 | break; | |
576 | } | |
577 | } | |
578 | ||
579 | if (!has_ident) | |
580 | Error(NO_IDENT_MSG); | |
581 | ||
582 | #ifdef DEBUG | |
583 | printf("Monitor section parsed\n"); | |
584 | #endif | |
585 | return ptr; | |
586 | } | |
587 | ||
588 | #undef CLEANUP | |
589 | #define CLEANUP xf86freeModesList | |
590 | ||
591 | XF86ConfModesPtr | |
592 | xf86parseModesSection(void) | |
593 | { | |
594 | int has_ident = FALSE; | |
595 | int token; | |
596 | ||
597 | parsePrologue(XF86ConfModesPtr, XF86ConfModesRec) | |
598 | ||
599 | while ((token = xf86getToken(ModesTab)) != ENDSECTION) { | |
600 | switch (token) { | |
601 | case COMMENT: | |
602 | ptr->modes_comment = xf86addComment(ptr->modes_comment, val.str); | |
603 | break; | |
604 | case IDENTIFIER: | |
605 | if (xf86getSubToken(&(ptr->modes_comment)) != STRING) | |
606 | Error(QUOTE_MSG, "Identifier"); | |
607 | if (has_ident == TRUE) | |
608 | Error(MULTIPLE_MSG, "Identifier"); | |
609 | ptr->modes_identifier = val.str; | |
610 | has_ident = TRUE; | |
611 | break; | |
612 | case MODE: | |
613 | HANDLE_LIST(mon_modeline_lst, xf86parseVerboseMode, | |
614 | XF86ConfModeLinePtr); | |
615 | break; | |
616 | case MODELINE: | |
617 | HANDLE_LIST(mon_modeline_lst, xf86parseModeLine, | |
618 | XF86ConfModeLinePtr); | |
619 | break; | |
620 | default: | |
621 | xf86parseError(INVALID_KEYWORD_MSG, xf86tokenString()); | |
622 | CLEANUP(ptr); | |
623 | return NULL; | |
624 | break; | |
625 | } | |
626 | } | |
627 | ||
628 | if (!has_ident) | |
629 | Error(NO_IDENT_MSG); | |
630 | ||
631 | #ifdef DEBUG | |
632 | printf("Modes section parsed\n"); | |
633 | #endif | |
634 | return ptr; | |
635 | } | |
636 | ||
637 | #undef CLEANUP | |
638 | ||
639 | void | |
640 | xf86printMonitorSection(FILE * cf, XF86ConfMonitorPtr ptr) | |
641 | { | |
642 | int i; | |
643 | XF86ConfModeLinePtr mlptr; | |
644 | XF86ConfModesLinkPtr mptr; | |
645 | ||
646 | while (ptr) { | |
647 | mptr = ptr->mon_modes_sect_lst; | |
648 | fprintf(cf, "Section \"Monitor\"\n"); | |
649 | if (ptr->mon_comment) | |
650 | fprintf(cf, "%s", ptr->mon_comment); | |
651 | if (ptr->mon_identifier) | |
652 | fprintf(cf, "\tIdentifier \"%s\"\n", ptr->mon_identifier); | |
653 | if (ptr->mon_vendor) | |
654 | fprintf(cf, "\tVendorName \"%s\"\n", ptr->mon_vendor); | |
655 | if (ptr->mon_modelname) | |
656 | fprintf(cf, "\tModelName \"%s\"\n", ptr->mon_modelname); | |
657 | while (mptr) { | |
658 | fprintf(cf, "\tUseModes \"%s\"\n", mptr->ml_modes_str); | |
659 | mptr = mptr->list.next; | |
660 | } | |
661 | if (ptr->mon_width) | |
662 | fprintf(cf, "\tDisplaySize %d\t%d\n", | |
663 | ptr->mon_width, ptr->mon_height); | |
664 | for (i = 0; i < ptr->mon_n_hsync; i++) { | |
665 | fprintf(cf, "\tHorizSync %2.1f - %2.1f\n", | |
666 | ptr->mon_hsync[i].lo, ptr->mon_hsync[i].hi); | |
667 | } | |
668 | for (i = 0; i < ptr->mon_n_vrefresh; i++) { | |
669 | fprintf(cf, "\tVertRefresh %2.1f - %2.1f\n", | |
670 | ptr->mon_vrefresh[i].lo, ptr->mon_vrefresh[i].hi); | |
671 | } | |
672 | if (ptr->mon_gamma_red) { | |
673 | if (ptr->mon_gamma_red == ptr->mon_gamma_green | |
674 | && ptr->mon_gamma_red == ptr->mon_gamma_blue) { | |
675 | fprintf(cf, "\tGamma %.4g\n", ptr->mon_gamma_red); | |
676 | } | |
677 | else { | |
678 | fprintf(cf, "\tGamma %.4g %.4g %.4g\n", | |
679 | ptr->mon_gamma_red, | |
680 | ptr->mon_gamma_green, ptr->mon_gamma_blue); | |
681 | } | |
682 | } | |
683 | for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next) { | |
684 | fprintf(cf, "\tModeLine \"%s\" %2.1f ", | |
685 | mlptr->ml_identifier, mlptr->ml_clock / 1000.0); | |
686 | fprintf(cf, "%d %d %d %d %d %d %d %d", | |
687 | mlptr->ml_hdisplay, mlptr->ml_hsyncstart, | |
688 | mlptr->ml_hsyncend, mlptr->ml_htotal, | |
689 | mlptr->ml_vdisplay, mlptr->ml_vsyncstart, | |
690 | mlptr->ml_vsyncend, mlptr->ml_vtotal); | |
691 | if (mlptr->ml_flags & XF86CONF_PHSYNC) | |
692 | fprintf(cf, " +hsync"); | |
693 | if (mlptr->ml_flags & XF86CONF_NHSYNC) | |
694 | fprintf(cf, " -hsync"); | |
695 | if (mlptr->ml_flags & XF86CONF_PVSYNC) | |
696 | fprintf(cf, " +vsync"); | |
697 | if (mlptr->ml_flags & XF86CONF_NVSYNC) | |
698 | fprintf(cf, " -vsync"); | |
699 | if (mlptr->ml_flags & XF86CONF_INTERLACE) | |
700 | fprintf(cf, " interlace"); | |
701 | if (mlptr->ml_flags & XF86CONF_CSYNC) | |
702 | fprintf(cf, " composite"); | |
703 | if (mlptr->ml_flags & XF86CONF_PCSYNC) | |
704 | fprintf(cf, " +csync"); | |
705 | if (mlptr->ml_flags & XF86CONF_NCSYNC) | |
706 | fprintf(cf, " -csync"); | |
707 | if (mlptr->ml_flags & XF86CONF_DBLSCAN) | |
708 | fprintf(cf, " doublescan"); | |
709 | if (mlptr->ml_flags & XF86CONF_HSKEW) | |
710 | fprintf(cf, " hskew %d", mlptr->ml_hskew); | |
711 | if (mlptr->ml_flags & XF86CONF_BCAST) | |
712 | fprintf(cf, " bcast"); | |
713 | fprintf(cf, "\n"); | |
714 | } | |
715 | xf86printOptionList(cf, ptr->mon_option_lst, 1); | |
716 | fprintf(cf, "EndSection\n\n"); | |
717 | ptr = ptr->list.next; | |
718 | } | |
719 | } | |
720 | ||
721 | void | |
722 | xf86printModesSection(FILE * cf, XF86ConfModesPtr ptr) | |
723 | { | |
724 | XF86ConfModeLinePtr mlptr; | |
725 | ||
726 | while (ptr) { | |
727 | fprintf(cf, "Section \"Modes\"\n"); | |
728 | if (ptr->modes_comment) | |
729 | fprintf(cf, "%s", ptr->modes_comment); | |
730 | if (ptr->modes_identifier) | |
731 | fprintf(cf, "\tIdentifier \"%s\"\n", ptr->modes_identifier); | |
732 | for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next) { | |
733 | fprintf(cf, "\tModeLine \"%s\" %2.1f ", | |
734 | mlptr->ml_identifier, mlptr->ml_clock / 1000.0); | |
735 | fprintf(cf, "%d %d %d %d %d %d %d %d", | |
736 | mlptr->ml_hdisplay, mlptr->ml_hsyncstart, | |
737 | mlptr->ml_hsyncend, mlptr->ml_htotal, | |
738 | mlptr->ml_vdisplay, mlptr->ml_vsyncstart, | |
739 | mlptr->ml_vsyncend, mlptr->ml_vtotal); | |
740 | if (mlptr->ml_flags & XF86CONF_PHSYNC) | |
741 | fprintf(cf, " +hsync"); | |
742 | if (mlptr->ml_flags & XF86CONF_NHSYNC) | |
743 | fprintf(cf, " -hsync"); | |
744 | if (mlptr->ml_flags & XF86CONF_PVSYNC) | |
745 | fprintf(cf, " +vsync"); | |
746 | if (mlptr->ml_flags & XF86CONF_NVSYNC) | |
747 | fprintf(cf, " -vsync"); | |
748 | if (mlptr->ml_flags & XF86CONF_INTERLACE) | |
749 | fprintf(cf, " interlace"); | |
750 | if (mlptr->ml_flags & XF86CONF_CSYNC) | |
751 | fprintf(cf, " composite"); | |
752 | if (mlptr->ml_flags & XF86CONF_PCSYNC) | |
753 | fprintf(cf, " +csync"); | |
754 | if (mlptr->ml_flags & XF86CONF_NCSYNC) | |
755 | fprintf(cf, " -csync"); | |
756 | if (mlptr->ml_flags & XF86CONF_DBLSCAN) | |
757 | fprintf(cf, " doublescan"); | |
758 | if (mlptr->ml_flags & XF86CONF_HSKEW) | |
759 | fprintf(cf, " hskew %d", mlptr->ml_hskew); | |
760 | if (mlptr->ml_flags & XF86CONF_VSCAN) | |
761 | fprintf(cf, " vscan %d", mlptr->ml_vscan); | |
762 | if (mlptr->ml_flags & XF86CONF_BCAST) | |
763 | fprintf(cf, " bcast"); | |
764 | if (mlptr->ml_comment) | |
765 | fprintf(cf, "%s", mlptr->ml_comment); | |
766 | else | |
767 | fprintf(cf, "\n"); | |
768 | } | |
769 | fprintf(cf, "EndSection\n\n"); | |
770 | ptr = ptr->list.next; | |
771 | } | |
772 | } | |
773 | ||
774 | void | |
775 | xf86freeMonitorList(XF86ConfMonitorPtr ptr) | |
776 | { | |
777 | XF86ConfMonitorPtr prev; | |
778 | ||
779 | while (ptr) { | |
780 | TestFree(ptr->mon_identifier); | |
781 | TestFree(ptr->mon_vendor); | |
782 | TestFree(ptr->mon_modelname); | |
783 | TestFree(ptr->mon_comment); | |
784 | xf86optionListFree(ptr->mon_option_lst); | |
785 | xf86freeModeLineList(ptr->mon_modeline_lst); | |
786 | prev = ptr; | |
787 | ptr = ptr->list.next; | |
788 | free(prev); | |
789 | } | |
790 | } | |
791 | ||
792 | void | |
793 | xf86freeModesList(XF86ConfModesPtr ptr) | |
794 | { | |
795 | XF86ConfModesPtr prev; | |
796 | ||
797 | while (ptr) { | |
798 | TestFree(ptr->modes_identifier); | |
799 | TestFree(ptr->modes_comment); | |
800 | xf86freeModeLineList(ptr->mon_modeline_lst); | |
801 | prev = ptr; | |
802 | ptr = ptr->list.next; | |
803 | free(prev); | |
804 | } | |
805 | } | |
806 | ||
807 | XF86ConfMonitorPtr | |
808 | xf86findMonitor(const char *ident, XF86ConfMonitorPtr p) | |
809 | { | |
810 | while (p) { | |
811 | if (xf86nameCompare(ident, p->mon_identifier) == 0) | |
812 | return p; | |
813 | ||
814 | p = p->list.next; | |
815 | } | |
816 | return NULL; | |
817 | } | |
818 | ||
819 | XF86ConfModesPtr | |
820 | xf86findModes(const char *ident, XF86ConfModesPtr p) | |
821 | { | |
822 | while (p) { | |
823 | if (xf86nameCompare(ident, p->modes_identifier) == 0) | |
824 | return p; | |
825 | ||
826 | p = p->list.next; | |
827 | } | |
828 | return NULL; | |
829 | } | |
830 | ||
831 | XF86ConfModeLinePtr | |
832 | xf86findModeLine(const char *ident, XF86ConfModeLinePtr p) | |
833 | { | |
834 | while (p) { | |
835 | if (xf86nameCompare(ident, p->ml_identifier) == 0) | |
836 | return p; | |
837 | ||
838 | p = p->list.next; | |
839 | } | |
840 | return NULL; | |
841 | } | |
842 | ||
843 | int | |
844 | xf86validateMonitor(XF86ConfigPtr p, XF86ConfScreenPtr screen) | |
845 | { | |
846 | XF86ConfMonitorPtr monitor = screen->scrn_monitor; | |
847 | XF86ConfModesLinkPtr modeslnk = monitor->mon_modes_sect_lst; | |
848 | XF86ConfModesPtr modes; | |
849 | ||
850 | while (modeslnk) { | |
851 | modes = xf86findModes(modeslnk->ml_modes_str, p->conf_modes_lst); | |
852 | if (!modes) { | |
853 | xf86validationError(UNDEFINED_MODES_MSG, | |
854 | modeslnk->ml_modes_str, | |
855 | screen->scrn_identifier); | |
856 | return FALSE; | |
857 | } | |
858 | modeslnk->ml_modes = modes; | |
859 | modeslnk = modeslnk->list.next; | |
860 | } | |
861 | return TRUE; | |
862 | } |