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