Screen.c revision 35c4bbdf
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 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 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