xf86Helper.c (50341B)
1 /* 2 * Copyright (c) 1997-2003 by The XFree86 Project, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the copyright holder(s) 23 * and author(s) shall not be used in advertising or otherwise to promote 24 * the sale, use or other dealings in this Software without prior written 25 * authorization from the copyright holder(s) and author(s). 26 */ 27 28 /* 29 * Authors: Dirk Hohndel <hohndel@XFree86.Org> 30 * David Dawes <dawes@XFree86.Org> 31 * ... and others 32 * 33 * This file includes the helper functions that the server provides for 34 * different drivers. 35 */ 36 37 #ifdef HAVE_XORG_CONFIG_H 38 #include <xorg-config.h> 39 #endif 40 41 #include <X11/X.h> 42 #include "mi.h" 43 #include "os.h" 44 #include "servermd.h" 45 #include "pixmapstr.h" 46 #include "windowstr.h" 47 #include "propertyst.h" 48 #include "gcstruct.h" 49 #include "loaderProcs.h" 50 #include "xf86.h" 51 #include "xf86Priv.h" 52 #include "xf86_OSlib.h" 53 #include "micmap.h" 54 #include "xf86DDC.h" 55 #include "xf86Xinput.h" 56 #include "xf86InPriv.h" 57 #include "mivalidate.h" 58 59 /* For xf86GetClocks */ 60 #if defined(CSRG_BASED) || defined(__GNU__) 61 #define HAS_SETPRIORITY 62 #include <sys/resource.h> 63 #endif 64 65 static int xf86ScrnInfoPrivateCount = 0; 66 67 /* Add a pointer to a new DriverRec to xf86DriverList */ 68 69 void 70 xf86AddDriver(DriverPtr driver, void *module, int flags) 71 { 72 /* Don't add null entries */ 73 if (!driver) 74 return; 75 76 if (xf86DriverList == NULL) 77 xf86NumDrivers = 0; 78 79 xf86NumDrivers++; 80 xf86DriverList = xnfreallocarray(xf86DriverList, 81 xf86NumDrivers, sizeof(DriverPtr)); 82 xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec)); 83 *xf86DriverList[xf86NumDrivers - 1] = *driver; 84 xf86DriverList[xf86NumDrivers - 1]->module = module; 85 xf86DriverList[xf86NumDrivers - 1]->refCount = 0; 86 } 87 88 void 89 xf86DeleteDriver(int drvIndex) 90 { 91 if (xf86DriverList[drvIndex] 92 && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) { 93 if (xf86DriverList[drvIndex]->module) 94 UnloadModule(xf86DriverList[drvIndex]->module); 95 free(xf86DriverList[drvIndex]); 96 xf86DriverList[drvIndex] = NULL; 97 } 98 } 99 100 /* Add a pointer to a new InputDriverRec to xf86InputDriverList */ 101 102 void 103 xf86AddInputDriver(InputDriverPtr driver, void *module, int flags) 104 { 105 /* Don't add null entries */ 106 if (!driver) 107 return; 108 109 if (xf86InputDriverList == NULL) 110 xf86NumInputDrivers = 0; 111 112 xf86NumInputDrivers++; 113 xf86InputDriverList = xnfreallocarray(xf86InputDriverList, 114 xf86NumInputDrivers, 115 sizeof(InputDriverPtr)); 116 xf86InputDriverList[xf86NumInputDrivers - 1] = 117 xnfalloc(sizeof(InputDriverRec)); 118 *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver; 119 xf86InputDriverList[xf86NumInputDrivers - 1]->module = module; 120 } 121 122 void 123 xf86DeleteInputDriver(int drvIndex) 124 { 125 if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module) 126 UnloadModule(xf86InputDriverList[drvIndex]->module); 127 free(xf86InputDriverList[drvIndex]); 128 xf86InputDriverList[drvIndex] = NULL; 129 } 130 131 InputDriverPtr 132 xf86LookupInputDriver(const char *name) 133 { 134 int i; 135 136 for (i = 0; i < xf86NumInputDrivers; i++) { 137 if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName && 138 xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0) 139 return xf86InputDriverList[i]; 140 } 141 return NULL; 142 } 143 144 InputInfoPtr 145 xf86LookupInput(const char *name) 146 { 147 InputInfoPtr p; 148 149 for (p = xf86InputDevs; p != NULL; p = p->next) { 150 if (strcmp(name, p->name) == 0) 151 return p; 152 } 153 154 return NULL; 155 } 156 157 /* Allocate a new ScrnInfoRec in xf86Screens */ 158 159 ScrnInfoPtr 160 xf86AllocateScreen(DriverPtr drv, int flags) 161 { 162 int i; 163 ScrnInfoPtr pScrn; 164 165 if (flags & XF86_ALLOCATE_GPU_SCREEN) { 166 if (xf86GPUScreens == NULL) 167 xf86NumGPUScreens = 0; 168 i = xf86NumGPUScreens++; 169 xf86GPUScreens = xnfreallocarray(xf86GPUScreens, xf86NumGPUScreens, 170 sizeof(ScrnInfoPtr)); 171 xf86GPUScreens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1); 172 pScrn = xf86GPUScreens[i]; 173 pScrn->scrnIndex = i + GPU_SCREEN_OFFSET; /* Changes when a screen is removed */ 174 pScrn->is_gpu = TRUE; 175 } else { 176 if (xf86Screens == NULL) 177 xf86NumScreens = 0; 178 179 i = xf86NumScreens++; 180 xf86Screens = xnfreallocarray(xf86Screens, xf86NumScreens, 181 sizeof(ScrnInfoPtr)); 182 xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1); 183 pScrn = xf86Screens[i]; 184 185 pScrn->scrnIndex = i; /* Changes when a screen is removed */ 186 } 187 188 pScrn->origIndex = pScrn->scrnIndex; /* This never changes */ 189 pScrn->privates = xnfcalloc(sizeof(DevUnion), xf86ScrnInfoPrivateCount); 190 /* 191 * EnableDisableFBAccess now gets initialized in InitOutput() 192 * pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess; 193 */ 194 195 pScrn->drv = drv; 196 drv->refCount++; 197 pScrn->module = DuplicateModule(drv->module, NULL); 198 199 pScrn->DriverFunc = drv->driverFunc; 200 201 return pScrn; 202 } 203 204 /* 205 * Remove an entry from xf86Screens. Ideally it should free all allocated 206 * data. To do this properly may require a driver hook. 207 */ 208 209 void 210 xf86DeleteScreen(ScrnInfoPtr pScrn) 211 { 212 int i; 213 int scrnIndex; 214 Bool is_gpu = FALSE; 215 216 if (!pScrn) 217 return; 218 219 if (pScrn->is_gpu) { 220 /* First check if the screen is valid */ 221 if (xf86NumGPUScreens == 0 || xf86GPUScreens == NULL) 222 return; 223 is_gpu = TRUE; 224 } else { 225 /* First check if the screen is valid */ 226 if (xf86NumScreens == 0 || xf86Screens == NULL) 227 return; 228 } 229 230 scrnIndex = pScrn->scrnIndex; 231 /* If a FreeScreen function is defined, call it here */ 232 if (pScrn->FreeScreen != NULL) 233 pScrn->FreeScreen(pScrn); 234 235 while (pScrn->modes) 236 xf86DeleteMode(&pScrn->modes, pScrn->modes); 237 238 while (pScrn->modePool) 239 xf86DeleteMode(&pScrn->modePool, pScrn->modePool); 240 241 xf86OptionListFree(pScrn->options); 242 243 if (pScrn->module) 244 UnloadModule(pScrn->module); 245 246 if (pScrn->drv) 247 pScrn->drv->refCount--; 248 249 free(pScrn->privates); 250 251 xf86ClearEntityListForScreen(pScrn); 252 253 free(pScrn); 254 255 /* Move the other entries down, updating their scrnIndex fields */ 256 257 if (is_gpu) { 258 xf86NumGPUScreens--; 259 scrnIndex -= GPU_SCREEN_OFFSET; 260 for (i = scrnIndex; i < xf86NumGPUScreens; i++) { 261 xf86GPUScreens[i] = xf86GPUScreens[i + 1]; 262 xf86GPUScreens[i]->scrnIndex = i + GPU_SCREEN_OFFSET; 263 /* Also need to take care of the screen layout settings */ 264 } 265 } 266 else { 267 xf86NumScreens--; 268 269 for (i = scrnIndex; i < xf86NumScreens; i++) { 270 xf86Screens[i] = xf86Screens[i + 1]; 271 xf86Screens[i]->scrnIndex = i; 272 /* Also need to take care of the screen layout settings */ 273 } 274 } 275 } 276 277 /* 278 * Allocate a private in ScrnInfoRec. 279 */ 280 281 int 282 xf86AllocateScrnInfoPrivateIndex(void) 283 { 284 int idx, i; 285 ScrnInfoPtr pScr; 286 DevUnion *nprivs; 287 288 idx = xf86ScrnInfoPrivateCount++; 289 for (i = 0; i < xf86NumScreens; i++) { 290 pScr = xf86Screens[i]; 291 nprivs = xnfreallocarray(pScr->privates, 292 xf86ScrnInfoPrivateCount, sizeof(DevUnion)); 293 /* Zero the new private */ 294 memset(&nprivs[idx], 0, sizeof(DevUnion)); 295 pScr->privates = nprivs; 296 } 297 for (i = 0; i < xf86NumGPUScreens; i++) { 298 pScr = xf86GPUScreens[i]; 299 nprivs = xnfreallocarray(pScr->privates, 300 xf86ScrnInfoPrivateCount, sizeof(DevUnion)); 301 /* Zero the new private */ 302 memset(&nprivs[idx], 0, sizeof(DevUnion)); 303 pScr->privates = nprivs; 304 } 305 return idx; 306 } 307 308 Bool 309 xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad) 310 { 311 int i; 312 313 if (pScrn->numFormats >= MAXFORMATS) 314 return FALSE; 315 316 if (bpp <= 0) { 317 if (depth == 1) 318 bpp = 1; 319 else if (depth <= 8) 320 bpp = 8; 321 else if (depth <= 16) 322 bpp = 16; 323 else if (depth <= 32) 324 bpp = 32; 325 else 326 return FALSE; 327 } 328 if (pad <= 0) 329 pad = BITMAP_SCANLINE_PAD; 330 331 i = pScrn->numFormats++; 332 pScrn->formats[i].depth = depth; 333 pScrn->formats[i].bitsPerPixel = bpp; 334 pScrn->formats[i].scanlinePad = pad; 335 return TRUE; 336 } 337 338 /* 339 * Set the depth we are using based on (in the following order of preference): 340 * - values given on the command line 341 * - values given in the config file 342 * - values provided by the driver 343 * - an overall default when nothing else is given 344 * 345 * Also find a Display subsection matching the depth/bpp found. 346 * 347 * Sets the following ScrnInfoRec fields: 348 * bitsPerPixel, depth, display, imageByteOrder, 349 * bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats, 350 * formats, fbFormat. 351 */ 352 353 /* Can the screen handle 32 bpp pixmaps */ 354 #define DO_PIX32(f) ((f & Support32bppFb) || \ 355 ((f & Support24bppFb) && (f & SupportConvert32to24))) 356 357 #ifndef GLOBAL_DEFAULT_DEPTH 358 #define GLOBAL_DEFAULT_DEPTH 24 359 #endif 360 361 Bool 362 xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp, 363 int depth24flags) 364 { 365 int i; 366 DispPtr disp; 367 368 scrp->bitsPerPixel = -1; 369 scrp->depth = -1; 370 scrp->bitsPerPixelFrom = X_DEFAULT; 371 scrp->depthFrom = X_DEFAULT; 372 373 if (xf86FbBpp > 0) { 374 if (xf86FbBpp == 24) /* lol no */ 375 xf86FbBpp = 32; 376 scrp->bitsPerPixel = xf86FbBpp; 377 scrp->bitsPerPixelFrom = X_CMDLINE; 378 } 379 380 if (xf86Depth > 0) { 381 scrp->depth = xf86Depth; 382 scrp->depthFrom = X_CMDLINE; 383 } 384 385 if (xf86FbBpp < 0 && xf86Depth < 0) { 386 if (scrp->confScreen->defaultfbbpp > 0) { 387 scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp; 388 scrp->bitsPerPixelFrom = X_CONFIG; 389 } 390 if (scrp->confScreen->defaultdepth > 0) { 391 scrp->depth = scrp->confScreen->defaultdepth; 392 scrp->depthFrom = X_CONFIG; 393 } 394 395 if (scrp->confScreen->defaultfbbpp <= 0 && 396 scrp->confScreen->defaultdepth <= 0) { 397 /* 398 * Check for DefaultDepth and DefaultFbBpp options in the 399 * Device sections. 400 */ 401 GDevPtr device; 402 Bool found = FALSE; 403 404 for (i = 0; i < scrp->numEntities; i++) { 405 device = xf86GetDevFromEntity(scrp->entityList[i], 406 scrp->entityInstanceList[i]); 407 if (device && device->options) { 408 if (xf86FindOption(device->options, "DefaultDepth")) { 409 scrp->depth = xf86SetIntOption(device->options, 410 "DefaultDepth", -1); 411 scrp->depthFrom = X_CONFIG; 412 found = TRUE; 413 } 414 if (xf86FindOption(device->options, "DefaultFbBpp")) { 415 scrp->bitsPerPixel = xf86SetIntOption(device->options, 416 "DefaultFbBpp", 417 -1); 418 scrp->bitsPerPixelFrom = X_CONFIG; 419 found = TRUE; 420 } 421 } 422 if (found) 423 break; 424 } 425 } 426 } 427 428 /* If none of these is set, pick a default */ 429 if (scrp->bitsPerPixel < 0 && scrp->depth < 0) { 430 if (fbbpp > 0 || depth > 0) { 431 if (fbbpp > 0) 432 scrp->bitsPerPixel = fbbpp; 433 if (depth > 0) 434 scrp->depth = depth; 435 } 436 else { 437 scrp->depth = GLOBAL_DEFAULT_DEPTH; 438 } 439 } 440 441 /* If any are not given, determine a default for the others */ 442 443 if (scrp->bitsPerPixel < 0) { 444 /* The depth must be set */ 445 if (scrp->depth > -1) { 446 if (scrp->depth == 1) 447 scrp->bitsPerPixel = 1; 448 else if (scrp->depth <= 4) 449 scrp->bitsPerPixel = 4; 450 else if (scrp->depth <= 8) 451 scrp->bitsPerPixel = 8; 452 else if (scrp->depth <= 16) 453 scrp->bitsPerPixel = 16; 454 else if (scrp->depth <= 24 && DO_PIX32(depth24flags)) { 455 scrp->bitsPerPixel = 32; 456 } 457 else if (scrp->depth <= 32) 458 scrp->bitsPerPixel = 32; 459 else { 460 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 461 "No bpp for depth (%d)\n", scrp->depth); 462 return FALSE; 463 } 464 } 465 else { 466 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 467 "xf86SetDepthBpp: internal error: depth and fbbpp" 468 " are both not set\n"); 469 return FALSE; 470 } 471 if (scrp->bitsPerPixel < 0) { 472 if ((depth24flags & (Support24bppFb | Support32bppFb)) == 473 NoDepth24Support) 474 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 475 "Driver can't support depth 24\n"); 476 else 477 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 478 "Can't find fbbpp for depth 24\n"); 479 return FALSE; 480 } 481 scrp->bitsPerPixelFrom = X_PROBED; 482 } 483 484 if (scrp->depth <= 0) { 485 /* bitsPerPixel is already set */ 486 switch (scrp->bitsPerPixel) { 487 case 32: 488 scrp->depth = 24; 489 break; 490 default: 491 /* 1, 4, 8, 16 and 24 */ 492 scrp->depth = scrp->bitsPerPixel; 493 break; 494 } 495 scrp->depthFrom = X_PROBED; 496 } 497 498 /* Sanity checks */ 499 if (scrp->depth < 1 || scrp->depth > 32) { 500 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 501 "Specified depth (%d) is not in the range 1-32\n", 502 scrp->depth); 503 return FALSE; 504 } 505 switch (scrp->bitsPerPixel) { 506 case 1: 507 case 4: 508 case 8: 509 case 16: 510 case 32: 511 break; 512 default: 513 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 514 "Specified fbbpp (%d) is not a permitted value\n", 515 scrp->bitsPerPixel); 516 return FALSE; 517 } 518 if (scrp->depth > scrp->bitsPerPixel) { 519 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 520 "Specified depth (%d) is greater than the fbbpp (%d)\n", 521 scrp->depth, scrp->bitsPerPixel); 522 return FALSE; 523 } 524 525 /* 526 * Find the Display subsection matching the depth/fbbpp and initialise 527 * scrp->display with it. 528 */ 529 for (i = 0; i < scrp->confScreen->numdisplays; i++) { 530 disp = scrp->confScreen->displays[i]; 531 if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel) 532 || (disp->depth == scrp->depth && disp->fbbpp <= 0) 533 || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) { 534 scrp->display = disp; 535 break; 536 } 537 } 538 539 /* 540 * If an exact match can't be found, see if there is one with no 541 * depth or fbbpp specified. 542 */ 543 if (i == scrp->confScreen->numdisplays) { 544 for (i = 0; i < scrp->confScreen->numdisplays; i++) { 545 disp = scrp->confScreen->displays[i]; 546 if (disp->depth <= 0 && disp->fbbpp <= 0) { 547 scrp->display = disp; 548 break; 549 } 550 } 551 } 552 553 /* 554 * If all else fails, create a default one. 555 */ 556 if (i == scrp->confScreen->numdisplays) { 557 scrp->confScreen->numdisplays++; 558 scrp->confScreen->displays = 559 xnfreallocarray(scrp->confScreen->displays, 560 scrp->confScreen->numdisplays, sizeof(DispPtr)); 561 xf86DrvMsg(scrp->scrnIndex, X_INFO, 562 "Creating default Display subsection in Screen section\n" 563 "\t\"%s\" for depth/fbbpp %d/%d\n", 564 scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel); 565 scrp->confScreen->displays[i] = xnfcalloc(1, sizeof(DispRec)); 566 memset(scrp->confScreen->displays[i], 0, sizeof(DispRec)); 567 scrp->confScreen->displays[i]->blackColour.red = -1; 568 scrp->confScreen->displays[i]->blackColour.green = -1; 569 scrp->confScreen->displays[i]->blackColour.blue = -1; 570 scrp->confScreen->displays[i]->whiteColour.red = -1; 571 scrp->confScreen->displays[i]->whiteColour.green = -1; 572 scrp->confScreen->displays[i]->whiteColour.blue = -1; 573 scrp->confScreen->displays[i]->defaultVisual = -1; 574 scrp->confScreen->displays[i]->modes = xnfalloc(sizeof(char *)); 575 scrp->confScreen->displays[i]->modes[0] = NULL; 576 scrp->confScreen->displays[i]->depth = depth; 577 scrp->confScreen->displays[i]->fbbpp = fbbpp; 578 scrp->display = scrp->confScreen->displays[i]; 579 } 580 581 /* 582 * Setup defaults for the display-wide attributes the framebuffer will 583 * need. These defaults should eventually be set globally, and not 584 * dependent on the screens. 585 */ 586 scrp->imageByteOrder = IMAGE_BYTE_ORDER; 587 scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD; 588 if (scrp->depth < 8) { 589 /* Planar modes need these settings */ 590 scrp->bitmapScanlineUnit = 8; 591 scrp->bitmapBitOrder = MSBFirst; 592 } 593 else { 594 scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; 595 scrp->bitmapBitOrder = BITMAP_BIT_ORDER; 596 } 597 598 /* 599 * If an unusual depth is required, add it to scrp->formats. The formats 600 * for the common depths are handled globally in InitOutput 601 */ 602 switch (scrp->depth) { 603 case 1: 604 case 4: 605 case 8: 606 case 15: 607 case 16: 608 case 24: 609 /* Common depths. Nothing to do for them */ 610 break; 611 default: 612 if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) { 613 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 614 "Can't add pixmap format for depth %d\n", scrp->depth); 615 return FALSE; 616 } 617 } 618 619 /* Initialise the framebuffer format for this screen */ 620 scrp->fbFormat.depth = scrp->depth; 621 scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel; 622 scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD; 623 624 return TRUE; 625 } 626 627 /* 628 * Print out the selected depth and bpp. 629 */ 630 void 631 xf86PrintDepthBpp(ScrnInfoPtr scrp) 632 { 633 xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth); 634 xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel); 635 } 636 637 /* 638 * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths 639 * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits. 640 */ 641 Bool 642 xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask) 643 { 644 MessageType weightFrom = X_DEFAULT; 645 646 scrp->weight.red = 0; 647 scrp->weight.green = 0; 648 scrp->weight.blue = 0; 649 650 if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) { 651 scrp->weight = xf86Weight; 652 weightFrom = X_CMDLINE; 653 } 654 else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0 655 && scrp->display->weight.blue > 0) { 656 scrp->weight = scrp->display->weight; 657 weightFrom = X_CONFIG; 658 } 659 else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) { 660 scrp->weight = weight; 661 } 662 else { 663 switch (scrp->depth) { 664 case 1: 665 case 4: 666 case 8: 667 scrp->weight.red = scrp->weight.green = 668 scrp->weight.blue = scrp->rgbBits; 669 break; 670 case 15: 671 scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5; 672 break; 673 case 16: 674 scrp->weight.red = scrp->weight.blue = 5; 675 scrp->weight.green = 6; 676 break; 677 case 18: 678 scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6; 679 break; 680 case 24: 681 scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8; 682 break; 683 case 30: 684 scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10; 685 break; 686 } 687 } 688 689 if (scrp->weight.red) 690 xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n", 691 (int) scrp->weight.red, (int) scrp->weight.green, 692 (int) scrp->weight.blue); 693 694 if (scrp->depth > MAX_PSEUDO_DEPTH && 695 (scrp->depth != scrp->weight.red + scrp->weight.green + 696 scrp->weight.blue)) { 697 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 698 "Weight given (%d%d%d) is inconsistent with the " 699 "depth (%d)\n", 700 (int) scrp->weight.red, (int) scrp->weight.green, 701 (int) scrp->weight.blue, scrp->depth); 702 return FALSE; 703 } 704 if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) { 705 /* 706 * XXX Does this even mean anything for TrueColor visuals? 707 * If not, we shouldn't even be setting it here. However, this 708 * matches the behaviour of 3.x versions of XFree86. 709 */ 710 scrp->rgbBits = scrp->weight.red; 711 if (scrp->weight.green > scrp->rgbBits) 712 scrp->rgbBits = scrp->weight.green; 713 if (scrp->weight.blue > scrp->rgbBits) 714 scrp->rgbBits = scrp->weight.blue; 715 } 716 717 /* Set the mask and offsets */ 718 if (mask.red == 0 || mask.green == 0 || mask.blue == 0) { 719 /* Default to a setting common to PC hardware */ 720 scrp->offset.red = scrp->weight.green + scrp->weight.blue; 721 scrp->offset.green = scrp->weight.blue; 722 scrp->offset.blue = 0; 723 scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red; 724 scrp->mask.green = ((1 << scrp->weight.green) - 1) 725 << scrp->offset.green; 726 scrp->mask.blue = (1 << scrp->weight.blue) - 1; 727 } 728 else { 729 /* Initialise to the values passed */ 730 scrp->mask.red = mask.red; 731 scrp->mask.green = mask.green; 732 scrp->mask.blue = mask.blue; 733 scrp->offset.red = ffs(mask.red) - 1; 734 scrp->offset.green = ffs(mask.green) - 1; 735 scrp->offset.blue = ffs(mask.blue) - 1; 736 } 737 return TRUE; 738 } 739 740 Bool 741 xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual) 742 { 743 MessageType visualFrom = X_DEFAULT; 744 745 if (defaultColorVisualClass >= 0) { 746 scrp->defaultVisual = defaultColorVisualClass; 747 visualFrom = X_CMDLINE; 748 } 749 else if (scrp->display->defaultVisual >= 0) { 750 scrp->defaultVisual = scrp->display->defaultVisual; 751 visualFrom = X_CONFIG; 752 } 753 else if (visual >= 0) { 754 scrp->defaultVisual = visual; 755 } 756 else { 757 if (scrp->depth == 1) 758 scrp->defaultVisual = StaticGray; 759 else if (scrp->depth == 4) 760 scrp->defaultVisual = StaticColor; 761 else if (scrp->depth <= MAX_PSEUDO_DEPTH) 762 scrp->defaultVisual = PseudoColor; 763 else 764 scrp->defaultVisual = TrueColor; 765 } 766 switch (scrp->defaultVisual) { 767 case StaticGray: 768 case GrayScale: 769 case StaticColor: 770 case PseudoColor: 771 case TrueColor: 772 case DirectColor: 773 xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n", 774 xf86VisualNames[scrp->defaultVisual]); 775 return TRUE; 776 default: 777 778 xf86DrvMsg(scrp->scrnIndex, X_ERROR, 779 "Invalid default visual class (%d)\n", scrp->defaultVisual); 780 return FALSE; 781 } 782 } 783 784 #define TEST_GAMMA(g) \ 785 (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO 786 787 #define SET_GAMMA(g) \ 788 (g) > GAMMA_ZERO ? (g) : 1.0 789 790 Bool 791 xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma) 792 { 793 MessageType from = X_DEFAULT; 794 795 #if 0 796 xf86MonPtr DDC = (xf86MonPtr) (scrp->monitor->DDC); 797 #endif 798 if (TEST_GAMMA(xf86Gamma)) { 799 from = X_CMDLINE; 800 scrp->gamma.red = SET_GAMMA(xf86Gamma.red); 801 scrp->gamma.green = SET_GAMMA(xf86Gamma.green); 802 scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue); 803 } 804 else if (TEST_GAMMA(scrp->monitor->gamma)) { 805 from = X_CONFIG; 806 scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red); 807 scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green); 808 scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue); 809 #if 0 810 } 811 else if (DDC && DDC->features.gamma > GAMMA_ZERO) { 812 from = X_PROBED; 813 scrp->gamma.red = SET_GAMMA(DDC->features.gamma); 814 scrp->gamma.green = SET_GAMMA(DDC->features.gamma); 815 scrp->gamma.blue = SET_GAMMA(DDC->features.gamma); 816 /* EDID structure version 2 gives optional separate red, green & blue 817 * gamma values in bytes 0x57-0x59 */ 818 #endif 819 } 820 else if (TEST_GAMMA(gamma)) { 821 scrp->gamma.red = SET_GAMMA(gamma.red); 822 scrp->gamma.green = SET_GAMMA(gamma.green); 823 scrp->gamma.blue = SET_GAMMA(gamma.blue); 824 } 825 else { 826 scrp->gamma.red = 1.0; 827 scrp->gamma.green = 1.0; 828 scrp->gamma.blue = 1.0; 829 } 830 831 xf86DrvMsg(scrp->scrnIndex, from, 832 "Using gamma correction (%.1f, %.1f, %.1f)\n", 833 scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue); 834 835 return TRUE; 836 } 837 838 #undef TEST_GAMMA 839 #undef SET_GAMMA 840 841 /* 842 * Set the DPI from the command line option. XXX should allow it to be 843 * calculated from the widthmm/heightmm values. 844 */ 845 846 #undef MMPERINCH 847 #define MMPERINCH 25.4 848 849 void 850 xf86SetDpi(ScrnInfoPtr pScrn, int x, int y) 851 { 852 MessageType from = X_DEFAULT; 853 xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC); 854 int ddcWidthmm, ddcHeightmm; 855 int widthErr, heightErr; 856 857 /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */ 858 pScrn->widthmm = pScrn->monitor->widthmm; 859 pScrn->heightmm = pScrn->monitor->heightmm; 860 861 if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0)) { 862 /* DDC gives display size in mm for individual modes, 863 * but cm for monitor 864 */ 865 ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */ 866 ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */ 867 } 868 else { 869 ddcWidthmm = ddcHeightmm = 0; 870 } 871 872 if (monitorResolution > 0) { 873 pScrn->xDpi = monitorResolution; 874 pScrn->yDpi = monitorResolution; 875 from = X_CMDLINE; 876 } 877 else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) { 878 from = X_CONFIG; 879 if (pScrn->widthmm > 0) { 880 pScrn->xDpi = 881 (int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm); 882 } 883 if (pScrn->heightmm > 0) { 884 pScrn->yDpi = 885 (int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm); 886 } 887 if (pScrn->xDpi > 0 && pScrn->yDpi <= 0) 888 pScrn->yDpi = pScrn->xDpi; 889 if (pScrn->yDpi > 0 && pScrn->xDpi <= 0) 890 pScrn->xDpi = pScrn->yDpi; 891 xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", 892 pScrn->widthmm, pScrn->heightmm); 893 894 /* Warn if config and probe disagree about display size */ 895 if (ddcWidthmm && ddcHeightmm) { 896 if (pScrn->widthmm > 0) { 897 widthErr = abs(ddcWidthmm - pScrn->widthmm); 898 } 899 else { 900 widthErr = 0; 901 } 902 if (pScrn->heightmm > 0) { 903 heightErr = abs(ddcHeightmm - pScrn->heightmm); 904 } 905 else { 906 heightErr = 0; 907 } 908 if (widthErr > 10 || heightErr > 10) { 909 /* Should include config file name for monitor here */ 910 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 911 "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n", 912 ddcWidthmm, ddcHeightmm, pScrn->widthmm, 913 pScrn->heightmm); 914 } 915 } 916 } 917 else if (ddcWidthmm && ddcHeightmm) { 918 from = X_PROBED; 919 xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n", 920 ddcWidthmm, ddcHeightmm); 921 pScrn->widthmm = ddcWidthmm; 922 pScrn->heightmm = ddcHeightmm; 923 if (pScrn->widthmm > 0) { 924 pScrn->xDpi = 925 (int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm); 926 } 927 if (pScrn->heightmm > 0) { 928 pScrn->yDpi = 929 (int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm); 930 } 931 if (pScrn->xDpi > 0 && pScrn->yDpi <= 0) 932 pScrn->yDpi = pScrn->xDpi; 933 if (pScrn->yDpi > 0 && pScrn->xDpi <= 0) 934 pScrn->xDpi = pScrn->yDpi; 935 } 936 else { 937 if (x > 0) 938 pScrn->xDpi = x; 939 else 940 pScrn->xDpi = DEFAULT_DPI; 941 if (y > 0) 942 pScrn->yDpi = y; 943 else 944 pScrn->yDpi = DEFAULT_DPI; 945 } 946 xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n", 947 pScrn->xDpi, pScrn->yDpi); 948 } 949 950 #undef MMPERINCH 951 952 void 953 xf86SetBlackWhitePixels(ScreenPtr pScreen) 954 { 955 pScreen->whitePixel = 1; 956 pScreen->blackPixel = 0; 957 } 958 959 /* 960 * Function to enable/disable access to the frame buffer 961 * 962 * This is used when VT switching and when entering/leaving DGA direct mode. 963 * 964 * This has been rewritten again to eliminate the saved pixmap. The 965 * devPrivate field in the screen pixmap is set to NULL to catch code 966 * accidentally referencing the frame buffer while the X server is not 967 * supposed to touch it. 968 * 969 * Here, we exchange the pixmap private data, rather than the pixmaps 970 * themselves to avoid having to find and change any references to the screen 971 * pixmap such as GC's, window privates etc. This also means that this code 972 * does not need to know exactly how the pixmap pixels are accessed. Further, 973 * this exchange is >not< done through the screen's ModifyPixmapHeader() 974 * vector. This means the called frame buffer code layers can determine 975 * whether they are switched in or out by keeping track of the root pixmap's 976 * private data, and therefore don't need to access pScrnInfo->vtSema. 977 */ 978 void 979 xf86EnableDisableFBAccess(ScrnInfoPtr pScrnInfo, Bool enable) 980 { 981 ScreenPtr pScreen = pScrnInfo->pScreen; 982 983 if (enable) { 984 /* 985 * Restore all of the clip lists on the screen 986 */ 987 if (!xf86Resetting) 988 SetRootClip(pScreen, ROOT_CLIP_FULL); 989 990 } 991 else { 992 /* 993 * Empty all of the clip lists on the screen 994 */ 995 SetRootClip(pScreen, ROOT_CLIP_NONE); 996 } 997 } 998 999 /* Print driver messages in the standard format of 1000 (<type>) <screen name>(<screen index>): <message> */ 1001 void 1002 xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format, 1003 va_list args) 1004 { 1005 /* Prefix the scrnIndex name to the format string. */ 1006 if (scrnIndex >= 0 && scrnIndex < xf86NumScreens && 1007 xf86Screens[scrnIndex]->name) 1008 LogHdrMessageVerb(type, verb, format, args, "%s(%d): ", 1009 xf86Screens[scrnIndex]->name, scrnIndex); 1010 else if (scrnIndex >= GPU_SCREEN_OFFSET && 1011 scrnIndex < GPU_SCREEN_OFFSET + xf86NumGPUScreens && 1012 xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name) 1013 LogHdrMessageVerb(type, verb, format, args, "%s(G%d): ", 1014 xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name, scrnIndex - GPU_SCREEN_OFFSET); 1015 else 1016 LogVMessageVerb(type, verb, format, args); 1017 } 1018 1019 /* Print driver messages, with verbose level specified directly */ 1020 void 1021 xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format, 1022 ...) 1023 { 1024 va_list ap; 1025 1026 va_start(ap, format); 1027 xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap); 1028 va_end(ap); 1029 } 1030 1031 /* Print driver messages, with verbose level of 1 (default) */ 1032 void 1033 xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...) 1034 { 1035 va_list ap; 1036 1037 va_start(ap, format); 1038 xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap); 1039 va_end(ap); 1040 } 1041 1042 /* Print input driver messages in the standard format of 1043 (<type>) <driver>: <device name>: <message> */ 1044 void 1045 xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, 1046 const char *format, va_list args) 1047 { 1048 const char *driverName = NULL; 1049 const char *deviceName = NULL; 1050 1051 /* Prefix driver and device names to formatted message. */ 1052 if (dev) { 1053 deviceName = dev->name; 1054 if (dev->drv) 1055 driverName = dev->drv->driverName; 1056 } 1057 1058 LogHdrMessageVerb(type, verb, format, args, "%s: %s: ", driverName, 1059 deviceName); 1060 } 1061 1062 /* Print input driver message, with verbose level specified directly */ 1063 void 1064 xf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, 1065 const char *format, ...) 1066 { 1067 va_list ap; 1068 1069 va_start(ap, format); 1070 xf86VIDrvMsgVerb(dev, type, verb, format, ap); 1071 va_end(ap); 1072 } 1073 1074 /* Print input driver messages, with verbose level of 1 (default) */ 1075 void 1076 xf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...) 1077 { 1078 va_list ap; 1079 1080 va_start(ap, format); 1081 xf86VIDrvMsgVerb(dev, type, 1, format, ap); 1082 va_end(ap); 1083 } 1084 1085 /* Print non-driver messages with verbose level specified directly */ 1086 void 1087 xf86MsgVerb(MessageType type, int verb, const char *format, ...) 1088 { 1089 va_list ap; 1090 1091 va_start(ap, format); 1092 LogVMessageVerb(type, verb, format, ap); 1093 va_end(ap); 1094 } 1095 1096 /* Print non-driver messages with verbose level of 1 (default) */ 1097 void 1098 xf86Msg(MessageType type, const char *format, ...) 1099 { 1100 va_list ap; 1101 1102 va_start(ap, format); 1103 LogVMessageVerb(type, 1, format, ap); 1104 va_end(ap); 1105 } 1106 1107 /* Just like ErrorF, but with the verbose level checked */ 1108 void 1109 xf86ErrorFVerb(int verb, const char *format, ...) 1110 { 1111 va_list ap; 1112 1113 va_start(ap, format); 1114 if (xf86Verbose >= verb || xf86LogVerbose >= verb) 1115 LogVWrite(verb, format, ap); 1116 va_end(ap); 1117 } 1118 1119 /* Like xf86ErrorFVerb, but with an implied verbose level of 1 */ 1120 void 1121 xf86ErrorF(const char *format, ...) 1122 { 1123 va_list ap; 1124 1125 va_start(ap, format); 1126 if (xf86Verbose >= 1 || xf86LogVerbose >= 1) 1127 LogVWrite(1, format, ap); 1128 va_end(ap); 1129 } 1130 1131 /* Note temporarily modifies the passed in buffer! */ 1132 static void xf86_mkdir_p(char *path) 1133 { 1134 char *sep = path; 1135 1136 while ((sep = strchr(sep + 1, '/'))) { 1137 *sep = 0; 1138 (void)mkdir(path, 0777); 1139 *sep = '/'; 1140 } 1141 (void)mkdir(path, 0777); 1142 } 1143 1144 void 1145 xf86LogInit(void) 1146 { 1147 char *env, *lf = NULL; 1148 char buf[PATH_MAX]; 1149 1150 #define LOGSUFFIX ".log" 1151 #define LOGOLDSUFFIX ".old" 1152 1153 /* Get the log file name */ 1154 if (xf86LogFileFrom == X_DEFAULT) { 1155 /* When not running as root, we won't be able to write to /var/log */ 1156 if (geteuid() != 0) { 1157 if ((env = getenv("XDG_DATA_HOME"))) 1158 snprintf(buf, sizeof(buf), "%s/%s", env, 1159 DEFAULT_XDG_DATA_HOME_LOGDIR); 1160 else if ((env = getenv("HOME"))) 1161 snprintf(buf, sizeof(buf), "%s/%s/%s", env, 1162 DEFAULT_XDG_DATA_HOME, DEFAULT_XDG_DATA_HOME_LOGDIR); 1163 1164 if (env) { 1165 xf86_mkdir_p(buf); 1166 strlcat(buf, "/" DEFAULT_LOGPREFIX, sizeof(buf)); 1167 xf86LogFile = buf; 1168 } 1169 } 1170 /* Append the display number and ".log" */ 1171 if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1) 1172 FatalError("Cannot allocate space for the log file name\n"); 1173 xf86LogFile = lf; 1174 } 1175 1176 xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX); 1177 xf86LogFileWasOpened = TRUE; 1178 1179 xf86SetVerbosity(xf86Verbose); 1180 xf86SetLogVerbosity(xf86LogVerbose); 1181 1182 #undef LOGSUFFIX 1183 #undef LOGOLDSUFFIX 1184 1185 free(lf); 1186 } 1187 1188 void 1189 xf86CloseLog(enum ExitCode error) 1190 { 1191 LogClose(error); 1192 } 1193 1194 /* 1195 * Drivers can use these for using their own SymTabRecs. 1196 */ 1197 1198 const char * 1199 xf86TokenToString(SymTabPtr table, int token) 1200 { 1201 int i; 1202 1203 for (i = 0; table[i].token >= 0 && table[i].token != token; i++); 1204 1205 if (table[i].token < 0) 1206 return NULL; 1207 else 1208 return table[i].name; 1209 } 1210 1211 int 1212 xf86StringToToken(SymTabPtr table, const char *string) 1213 { 1214 int i; 1215 1216 if (string == NULL) 1217 return -1; 1218 1219 for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++); 1220 1221 return table[i].token; 1222 } 1223 1224 /* 1225 * helper to display the clocks found on a card 1226 */ 1227 void 1228 xf86ShowClocks(ScrnInfoPtr scrp, MessageType from) 1229 { 1230 int j; 1231 1232 xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:"); 1233 for (j = 0; j < scrp->numClocks; j++) { 1234 if ((j % 4) == 0) { 1235 xf86ErrorF("\n"); 1236 xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:"); 1237 } 1238 xf86ErrorF(" %7.3f", (double) scrp->clock[j] / 1000.0); 1239 } 1240 xf86ErrorF("\n"); 1241 } 1242 1243 /* 1244 * This prints out the driver identify message, including the names of 1245 * the supported chipsets. 1246 * 1247 * XXX This makes assumptions about the line width, etc. Maybe we could 1248 * use a more general "pretty print" function for messages. 1249 */ 1250 void 1251 xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips) 1252 { 1253 int len, i; 1254 1255 len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2; 1256 xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg); 1257 for (i = 0; chips[i].name != NULL; i++) { 1258 if (i != 0) { 1259 xf86ErrorF(","); 1260 len++; 1261 } 1262 if (len + 2 + strlen(chips[i].name) < 78) { 1263 xf86ErrorF(" "); 1264 len++; 1265 } 1266 else { 1267 xf86ErrorF("\n\t"); 1268 len = 8; 1269 } 1270 xf86ErrorF("%s", chips[i].name); 1271 len += strlen(chips[i].name); 1272 } 1273 xf86ErrorF("\n"); 1274 } 1275 1276 int 1277 xf86MatchDevice(const char *drivername, GDevPtr ** sectlist) 1278 { 1279 GDevPtr gdp, *pgdp = NULL; 1280 confScreenPtr screensecptr; 1281 int i, j, k; 1282 1283 if (sectlist) 1284 *sectlist = NULL; 1285 1286 /* 1287 * This can happen when running Xorg -showopts and a module like ati 1288 * or vmware tries to load its submodules when xf86ConfigLayout is empty 1289 */ 1290 if (!xf86ConfigLayout.screens) 1291 return 0; 1292 1293 /* 1294 * This is a very important function that matches the device sections 1295 * as they show up in the config file with the drivers that the server 1296 * loads at run time. 1297 * 1298 * ChipProbe can call 1299 * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist) 1300 * with its driver name. The function allocates an array of GDevPtr and 1301 * returns this via sectlist and returns the number of elements in 1302 * this list as return value. 0 means none found, -1 means fatal error. 1303 * 1304 * It can figure out which of the Device sections to use for which card 1305 * (using things like the Card statement, etc). For single headed servers 1306 * there will of course be just one such Device section. 1307 */ 1308 i = 0; 1309 1310 /* 1311 * first we need to loop over all the Screens sections to get to all 1312 * 'active' device sections 1313 */ 1314 for (j = 0; xf86ConfigLayout.screens[j].screen != NULL; j++) { 1315 screensecptr = xf86ConfigLayout.screens[j].screen; 1316 if ((screensecptr->device->driver != NULL) 1317 && (xf86NameCmp(screensecptr->device->driver, drivername) == 0) 1318 && (!screensecptr->device->claimed)) { 1319 /* 1320 * we have a matching driver that wasn't claimed, yet 1321 */ 1322 pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr)); 1323 pgdp[i++] = screensecptr->device; 1324 } 1325 for (k = 0; k < screensecptr->num_gpu_devices; k++) { 1326 if ((screensecptr->gpu_devices[k]->driver != NULL) 1327 && (xf86NameCmp(screensecptr->gpu_devices[k]->driver, drivername) == 0) 1328 && (!screensecptr->gpu_devices[k]->claimed)) { 1329 /* 1330 * we have a matching driver that wasn't claimed, yet 1331 */ 1332 pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); 1333 pgdp[i++] = screensecptr->gpu_devices[k]; 1334 } 1335 } 1336 } 1337 1338 /* Then handle the inactive devices */ 1339 j = 0; 1340 while (xf86ConfigLayout.inactives[j].identifier) { 1341 gdp = &xf86ConfigLayout.inactives[j]; 1342 if (gdp->driver && !gdp->claimed && 1343 !xf86NameCmp(gdp->driver, drivername)) { 1344 /* we have a matching driver that wasn't claimed yet */ 1345 pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr)); 1346 pgdp[i++] = gdp; 1347 } 1348 j++; 1349 } 1350 1351 /* 1352 * make the array NULL terminated and return its address 1353 */ 1354 if (i) 1355 pgdp[i] = NULL; 1356 1357 if (sectlist) 1358 *sectlist = pgdp; 1359 else 1360 free(pgdp); 1361 return i; 1362 } 1363 1364 const char * 1365 xf86GetVisualName(int visual) 1366 { 1367 if (visual < 0 || visual > DirectColor) 1368 return NULL; 1369 1370 return xf86VisualNames[visual]; 1371 } 1372 1373 int 1374 xf86GetVerbosity(void) 1375 { 1376 return max(xf86Verbose, xf86LogVerbose); 1377 } 1378 1379 int 1380 xf86GetDepth(void) 1381 { 1382 return xf86Depth; 1383 } 1384 1385 rgb 1386 xf86GetWeight(void) 1387 { 1388 return xf86Weight; 1389 } 1390 1391 Gamma 1392 xf86GetGamma(void) 1393 { 1394 return xf86Gamma; 1395 } 1396 1397 Bool 1398 xf86ServerIsExiting(void) 1399 { 1400 return (dispatchException & DE_TERMINATE) == DE_TERMINATE; 1401 } 1402 1403 Bool 1404 xf86ServerIsResetting(void) 1405 { 1406 return xf86Resetting; 1407 } 1408 1409 Bool 1410 xf86ServerIsOnlyDetecting(void) 1411 { 1412 return xf86DoConfigure; 1413 } 1414 1415 Bool 1416 xf86GetVidModeAllowNonLocal(void) 1417 { 1418 return xf86Info.vidModeAllowNonLocal; 1419 } 1420 1421 Bool 1422 xf86GetVidModeEnabled(void) 1423 { 1424 return xf86Info.vidModeEnabled; 1425 } 1426 1427 Bool 1428 xf86GetModInDevAllowNonLocal(void) 1429 { 1430 return xf86Info.miscModInDevAllowNonLocal; 1431 } 1432 1433 Bool 1434 xf86GetModInDevEnabled(void) 1435 { 1436 return xf86Info.miscModInDevEnabled; 1437 } 1438 1439 Bool 1440 xf86GetAllowMouseOpenFail(void) 1441 { 1442 return xf86Info.allowMouseOpenFail; 1443 } 1444 1445 CARD32 1446 xf86GetModuleVersion(void *module) 1447 { 1448 return (CARD32) LoaderGetModuleVersion(module); 1449 } 1450 1451 void * 1452 xf86LoadDrvSubModule(DriverPtr drv, const char *name) 1453 { 1454 void *ret; 1455 int errmaj = 0, errmin = 0; 1456 1457 ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL, 1458 &errmaj, &errmin); 1459 if (!ret) 1460 LoaderErrorMsg(NULL, name, errmaj, errmin); 1461 return ret; 1462 } 1463 1464 void * 1465 xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name) 1466 { 1467 void *ret; 1468 int errmaj = 0, errmin = 0; 1469 1470 ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL, 1471 &errmaj, &errmin); 1472 if (!ret) 1473 LoaderErrorMsg(pScrn->name, name, errmaj, errmin); 1474 return ret; 1475 } 1476 1477 /* 1478 * xf86LoadOneModule loads a single module. 1479 */ 1480 void * 1481 xf86LoadOneModule(const char *name, void *opt) 1482 { 1483 int errmaj; 1484 char *Name; 1485 void *mod; 1486 1487 if (!name) 1488 return NULL; 1489 1490 /* Normalise the module name */ 1491 Name = xf86NormalizeName(name); 1492 1493 /* Skip empty names */ 1494 if (Name == NULL) 1495 return NULL; 1496 if (*Name == '\0') { 1497 free(Name); 1498 return NULL; 1499 } 1500 1501 mod = LoadModule(Name, opt, NULL, &errmaj); 1502 if (!mod) 1503 LoaderErrorMsg(NULL, Name, errmaj, 0); 1504 free(Name); 1505 return mod; 1506 } 1507 1508 void 1509 xf86UnloadSubModule(void *mod) 1510 { 1511 UnloadSubModule(mod); 1512 } 1513 1514 Bool 1515 xf86LoaderCheckSymbol(const char *name) 1516 { 1517 return LoaderSymbol(name) != NULL; 1518 } 1519 1520 typedef enum { 1521 OPTION_BACKING_STORE 1522 } BSOpts; 1523 1524 static const OptionInfoRec BSOptions[] = { 1525 {OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE}, 1526 {-1, NULL, OPTV_NONE, {0}, FALSE} 1527 }; 1528 1529 void 1530 xf86SetBackingStore(ScreenPtr pScreen) 1531 { 1532 Bool useBS = FALSE; 1533 MessageType from = X_DEFAULT; 1534 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1535 OptionInfoPtr options; 1536 1537 options = xnfalloc(sizeof(BSOptions)); 1538 (void) memcpy(options, BSOptions, sizeof(BSOptions)); 1539 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); 1540 1541 /* check for commandline option here */ 1542 if (xf86bsEnableFlag) { 1543 from = X_CMDLINE; 1544 useBS = TRUE; 1545 } 1546 else if (xf86bsDisableFlag) { 1547 from = X_CMDLINE; 1548 useBS = FALSE; 1549 } 1550 else { 1551 if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS)) 1552 from = X_CONFIG; 1553 #ifdef COMPOSITE 1554 if (from != X_CONFIG) 1555 useBS = xf86ReturnOptValBool(options, OPTION_BACKING_STORE, 1556 !noCompositeExtension); 1557 #endif 1558 } 1559 free(options); 1560 pScreen->backingStoreSupport = useBS ? WhenMapped : NotUseful; 1561 if (serverGeneration == 1) 1562 xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n", 1563 useBS ? "enabled" : "disabled"); 1564 } 1565 1566 typedef enum { 1567 OPTION_SILKEN_MOUSE 1568 } SMOpts; 1569 1570 static const OptionInfoRec SMOptions[] = { 1571 {OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE}, 1572 {-1, NULL, OPTV_NONE, {0}, FALSE} 1573 }; 1574 1575 void 1576 xf86SetSilkenMouse(ScreenPtr pScreen) 1577 { 1578 Bool useSM = TRUE; 1579 MessageType from = X_DEFAULT; 1580 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1581 OptionInfoPtr options; 1582 1583 options = xnfalloc(sizeof(SMOptions)); 1584 (void) memcpy(options, SMOptions, sizeof(SMOptions)); 1585 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); 1586 1587 /* check for commandline option here */ 1588 /* disable if screen shares resources */ 1589 /* TODO VGA arb disable silken mouse */ 1590 if (xf86silkenMouseDisableFlag) { 1591 from = X_CMDLINE; 1592 useSM = FALSE; 1593 } 1594 else { 1595 if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM)) 1596 from = X_CONFIG; 1597 } 1598 free(options); 1599 /* 1600 * Use silken mouse if requested and if we have threaded input 1601 */ 1602 pScrn->silkenMouse = useSM && InputThreadEnable; 1603 if (serverGeneration == 1) 1604 xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n", 1605 pScrn->silkenMouse ? "enabled" : "disabled"); 1606 } 1607 1608 /* Wrote this function for the PM2 Xv driver, preliminary. */ 1609 1610 void * 1611 xf86FindXvOptions(ScrnInfoPtr pScrn, int adaptor_index, const char *port_name, 1612 const char **adaptor_name, void **adaptor_options) 1613 { 1614 confXvAdaptorPtr adaptor; 1615 int i; 1616 1617 if (adaptor_index >= pScrn->confScreen->numxvadaptors) { 1618 if (adaptor_name) 1619 *adaptor_name = NULL; 1620 if (adaptor_options) 1621 *adaptor_options = NULL; 1622 return NULL; 1623 } 1624 1625 adaptor = &pScrn->confScreen->xvadaptors[adaptor_index]; 1626 if (adaptor_name) 1627 *adaptor_name = adaptor->identifier; 1628 if (adaptor_options) 1629 *adaptor_options = adaptor->options; 1630 1631 for (i = 0; i < adaptor->numports; i++) 1632 if (!xf86NameCmp(adaptor->ports[i].identifier, port_name)) 1633 return adaptor->ports[i].options; 1634 1635 return NULL; 1636 } 1637 1638 static void 1639 xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init, 1640 EntityProc enter, EntityProc leave, void *private) 1641 { 1642 ScrnInfoPtr pScrn; 1643 1644 if ((pScrn = xf86FindScreenForEntity(pEnt->index))) 1645 xf86RemoveEntityFromScreen(pScrn, pEnt->index); 1646 } 1647 1648 ScrnInfoPtr 1649 xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex, 1650 EntityProc init, EntityProc enter, EntityProc leave, 1651 void *private) 1652 { 1653 EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex); 1654 1655 if (init || enter || leave) 1656 FatalError("Legacy entity access functions are unsupported\n"); 1657 1658 if (!pEnt) 1659 return pScrn; 1660 1661 if (!(pEnt->location.type == BUS_NONE)) { 1662 free(pEnt); 1663 return pScrn; 1664 } 1665 1666 if (!pEnt->active) { 1667 xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private); 1668 free(pEnt); 1669 return pScrn; 1670 } 1671 1672 if (!pScrn) 1673 pScrn = xf86AllocateScreen(pEnt->driver, scrnFlag); 1674 xf86AddEntityToScreen(pScrn, entityIndex); 1675 1676 free(pEnt); 1677 return pScrn; 1678 } 1679 1680 Bool 1681 xf86IsScreenPrimary(ScrnInfoPtr pScrn) 1682 { 1683 int i; 1684 1685 for (i = 0; i < pScrn->numEntities; i++) { 1686 if (xf86IsEntityPrimary(i)) 1687 return TRUE; 1688 } 1689 return FALSE; 1690 } 1691 1692 Bool 1693 xf86IsUnblank(int mode) 1694 { 1695 switch (mode) { 1696 case SCREEN_SAVER_OFF: 1697 case SCREEN_SAVER_FORCER: 1698 return TRUE; 1699 case SCREEN_SAVER_ON: 1700 case SCREEN_SAVER_CYCLE: 1701 return FALSE; 1702 default: 1703 xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode); 1704 return TRUE; 1705 } 1706 } 1707 1708 void 1709 xf86MotionHistoryAllocate(InputInfoPtr pInfo) 1710 { 1711 AllocateMotionHistory(pInfo->dev); 1712 } 1713 1714 ScrnInfoPtr 1715 xf86ScreenToScrn(ScreenPtr pScreen) 1716 { 1717 if (pScreen->isGPU) { 1718 assert(pScreen->myNum - GPU_SCREEN_OFFSET < xf86NumGPUScreens); 1719 return xf86GPUScreens[pScreen->myNum - GPU_SCREEN_OFFSET]; 1720 } else { 1721 assert(pScreen->myNum < xf86NumScreens); 1722 return xf86Screens[pScreen->myNum]; 1723 } 1724 } 1725 1726 ScreenPtr 1727 xf86ScrnToScreen(ScrnInfoPtr pScrn) 1728 { 1729 if (pScrn->is_gpu) { 1730 assert(pScrn->scrnIndex - GPU_SCREEN_OFFSET < screenInfo.numGPUScreens); 1731 return screenInfo.gpuscreens[pScrn->scrnIndex - GPU_SCREEN_OFFSET]; 1732 } else { 1733 assert(pScrn->scrnIndex < screenInfo.numScreens); 1734 return screenInfo.screens[pScrn->scrnIndex]; 1735 } 1736 } 1737 1738 void 1739 xf86UpdateDesktopDimensions(void) 1740 { 1741 update_desktop_dimensions(); 1742 } 1743 1744 1745 void 1746 xf86AddInputEventDrainCallback(CallbackProcPtr callback, void *param) 1747 { 1748 mieqAddCallbackOnDrained(callback, param); 1749 } 1750 1751 void 1752 xf86RemoveInputEventDrainCallback(CallbackProcPtr callback, void *param) 1753 { 1754 mieqRemoveCallbackOnDrained(callback, param); 1755 }