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 65static int xf86ScrnInfoPrivateCount = 0; 66 67/* Add a pointer to a new DriverRec to xf86DriverList */ 68 69void 70xf86AddDriver(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 88void 89xf86DeleteDriver(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 102void 103xf86AddInputDriver(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 122void 123xf86DeleteInputDriver(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 131InputDriverPtr 132xf86LookupInputDriver(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 144InputInfoPtr 145xf86LookupInput(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 159ScrnInfoPtr 160xf86AllocateScreen(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 209void 210xf86DeleteScreen(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 281int 282xf86AllocateScrnInfoPrivateIndex(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 308Bool 309xf86AddPixFormat(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 361Bool 362xf86SetDepthBpp(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 */ 630void 631xf86PrintDepthBpp(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 */ 641Bool 642xf86SetWeight(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 740Bool 741xf86SetDefaultVisual(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 790Bool 791xf86SetGamma(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 849void 850xf86SetDpi(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 952void 953xf86SetBlackWhitePixels(ScreenPtr pScreen) 954{ 955 if (xf86FlipPixels) { 956 pScreen->whitePixel = 0; 957 pScreen->blackPixel = 1; 958 } 959 else { 960 pScreen->whitePixel = 1; 961 pScreen->blackPixel = 0; 962 } 963} 964 965/* 966 * Function to enable/disable access to the frame buffer 967 * 968 * This is used when VT switching and when entering/leaving DGA direct mode. 969 * 970 * This has been rewritten again to eliminate the saved pixmap. The 971 * devPrivate field in the screen pixmap is set to NULL to catch code 972 * accidentally referencing the frame buffer while the X server is not 973 * supposed to touch it. 974 * 975 * Here, we exchange the pixmap private data, rather than the pixmaps 976 * themselves to avoid having to find and change any references to the screen 977 * pixmap such as GC's, window privates etc. This also means that this code 978 * does not need to know exactly how the pixmap pixels are accessed. Further, 979 * this exchange is >not< done through the screen's ModifyPixmapHeader() 980 * vector. This means the called frame buffer code layers can determine 981 * whether they are switched in or out by keeping track of the root pixmap's 982 * private data, and therefore don't need to access pScrnInfo->vtSema. 983 */ 984void 985xf86EnableDisableFBAccess(ScrnInfoPtr pScrnInfo, Bool enable) 986{ 987 ScreenPtr pScreen = pScrnInfo->pScreen; 988 989 if (enable) { 990 /* 991 * Restore all of the clip lists on the screen 992 */ 993 if (!xf86Resetting) 994 SetRootClip(pScreen, ROOT_CLIP_FULL); 995 996 } 997 else { 998 /* 999 * Empty all of the clip lists on the screen 1000 */ 1001 SetRootClip(pScreen, ROOT_CLIP_NONE); 1002 } 1003} 1004 1005/* Print driver messages in the standard format of 1006 (<type>) <screen name>(<screen index>): <message> */ 1007void 1008xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format, 1009 va_list args) 1010{ 1011 /* Prefix the scrnIndex name to the format string. */ 1012 if (scrnIndex >= 0 && scrnIndex < xf86NumScreens && 1013 xf86Screens[scrnIndex]->name) 1014 LogHdrMessageVerb(type, verb, format, args, "%s(%d): ", 1015 xf86Screens[scrnIndex]->name, scrnIndex); 1016 else if (scrnIndex >= GPU_SCREEN_OFFSET && 1017 scrnIndex < GPU_SCREEN_OFFSET + xf86NumGPUScreens && 1018 xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name) 1019 LogHdrMessageVerb(type, verb, format, args, "%s(G%d): ", 1020 xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name, scrnIndex - GPU_SCREEN_OFFSET); 1021 else 1022 LogVMessageVerb(type, verb, format, args); 1023} 1024 1025/* Print driver messages, with verbose level specified directly */ 1026void 1027xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format, 1028 ...) 1029{ 1030 va_list ap; 1031 1032 va_start(ap, format); 1033 xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap); 1034 va_end(ap); 1035} 1036 1037/* Print driver messages, with verbose level of 1 (default) */ 1038void 1039xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...) 1040{ 1041 va_list ap; 1042 1043 va_start(ap, format); 1044 xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap); 1045 va_end(ap); 1046} 1047 1048/* Print input driver messages in the standard format of 1049 (<type>) <driver>: <device name>: <message> */ 1050void 1051xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, 1052 const char *format, va_list args) 1053{ 1054 const char *driverName = NULL; 1055 const char *deviceName = NULL; 1056 1057 /* Prefix driver and device names to formatted message. */ 1058 if (dev) { 1059 deviceName = dev->name; 1060 if (dev->drv) 1061 driverName = dev->drv->driverName; 1062 } 1063 1064 LogHdrMessageVerb(type, verb, format, args, "%s: %s: ", driverName, 1065 deviceName); 1066} 1067 1068/* Print input driver message, with verbose level specified directly */ 1069void 1070xf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, 1071 const char *format, ...) 1072{ 1073 va_list ap; 1074 1075 va_start(ap, format); 1076 xf86VIDrvMsgVerb(dev, type, verb, format, ap); 1077 va_end(ap); 1078} 1079 1080/* Print input driver messages, with verbose level of 1 (default) */ 1081void 1082xf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...) 1083{ 1084 va_list ap; 1085 1086 va_start(ap, format); 1087 xf86VIDrvMsgVerb(dev, type, 1, format, ap); 1088 va_end(ap); 1089} 1090 1091/* Print non-driver messages with verbose level specified directly */ 1092void 1093xf86MsgVerb(MessageType type, int verb, const char *format, ...) 1094{ 1095 va_list ap; 1096 1097 va_start(ap, format); 1098 LogVMessageVerb(type, verb, format, ap); 1099 va_end(ap); 1100} 1101 1102/* Print non-driver messages with verbose level of 1 (default) */ 1103void 1104xf86Msg(MessageType type, const char *format, ...) 1105{ 1106 va_list ap; 1107 1108 va_start(ap, format); 1109 LogVMessageVerb(type, 1, format, ap); 1110 va_end(ap); 1111} 1112 1113/* Just like ErrorF, but with the verbose level checked */ 1114void 1115xf86ErrorFVerb(int verb, const char *format, ...) 1116{ 1117 va_list ap; 1118 1119 va_start(ap, format); 1120 if (xf86Verbose >= verb || xf86LogVerbose >= verb) 1121 LogVWrite(verb, format, ap); 1122 va_end(ap); 1123} 1124 1125/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */ 1126void 1127xf86ErrorF(const char *format, ...) 1128{ 1129 va_list ap; 1130 1131 va_start(ap, format); 1132 if (xf86Verbose >= 1 || xf86LogVerbose >= 1) 1133 LogVWrite(1, format, ap); 1134 va_end(ap); 1135} 1136 1137/* Note temporarily modifies the passed in buffer! */ 1138static void xf86_mkdir_p(char *path) 1139{ 1140 char *sep = path; 1141 1142 while ((sep = strchr(sep + 1, '/'))) { 1143 *sep = 0; 1144 (void)mkdir(path, 0777); 1145 *sep = '/'; 1146 } 1147 (void)mkdir(path, 0777); 1148} 1149 1150void 1151xf86LogInit(void) 1152{ 1153 char *env, *lf = NULL; 1154 char buf[PATH_MAX]; 1155 1156#define LOGSUFFIX ".log" 1157#define LOGOLDSUFFIX ".old" 1158 1159 /* Get the log file name */ 1160 if (xf86LogFileFrom == X_DEFAULT) { 1161 /* When not running as root, we won't be able to write to /var/log */ 1162 if (geteuid() != 0) { 1163 if ((env = getenv("XDG_DATA_HOME"))) 1164 snprintf(buf, sizeof(buf), "%s/%s", env, 1165 DEFAULT_XDG_DATA_HOME_LOGDIR); 1166 else if ((env = getenv("HOME"))) 1167 snprintf(buf, sizeof(buf), "%s/%s/%s", env, 1168 DEFAULT_XDG_DATA_HOME, DEFAULT_XDG_DATA_HOME_LOGDIR); 1169 1170 if (env) { 1171 xf86_mkdir_p(buf); 1172 strlcat(buf, "/" DEFAULT_LOGPREFIX, sizeof(buf)); 1173 xf86LogFile = buf; 1174 } 1175 } 1176 /* Append the display number and ".log" */ 1177 if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1) 1178 FatalError("Cannot allocate space for the log file name\n"); 1179 xf86LogFile = lf; 1180 } 1181 1182 xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX); 1183 xf86LogFileWasOpened = TRUE; 1184 1185 xf86SetVerbosity(xf86Verbose); 1186 xf86SetLogVerbosity(xf86LogVerbose); 1187 1188#undef LOGSUFFIX 1189#undef LOGOLDSUFFIX 1190 1191 free(lf); 1192} 1193 1194void 1195xf86CloseLog(enum ExitCode error) 1196{ 1197 LogClose(error); 1198} 1199 1200/* 1201 * Drivers can use these for using their own SymTabRecs. 1202 */ 1203 1204const char * 1205xf86TokenToString(SymTabPtr table, int token) 1206{ 1207 int i; 1208 1209 for (i = 0; table[i].token >= 0 && table[i].token != token; i++); 1210 1211 if (table[i].token < 0) 1212 return NULL; 1213 else 1214 return table[i].name; 1215} 1216 1217int 1218xf86StringToToken(SymTabPtr table, const char *string) 1219{ 1220 int i; 1221 1222 if (string == NULL) 1223 return -1; 1224 1225 for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++); 1226 1227 return table[i].token; 1228} 1229 1230/* 1231 * helper to display the clocks found on a card 1232 */ 1233void 1234xf86ShowClocks(ScrnInfoPtr scrp, MessageType from) 1235{ 1236 int j; 1237 1238 xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:"); 1239 for (j = 0; j < scrp->numClocks; j++) { 1240 if ((j % 4) == 0) { 1241 xf86ErrorF("\n"); 1242 xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:"); 1243 } 1244 xf86ErrorF(" %7.3f", (double) scrp->clock[j] / 1000.0); 1245 } 1246 xf86ErrorF("\n"); 1247} 1248 1249/* 1250 * This prints out the driver identify message, including the names of 1251 * the supported chipsets. 1252 * 1253 * XXX This makes assumptions about the line width, etc. Maybe we could 1254 * use a more general "pretty print" function for messages. 1255 */ 1256void 1257xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips) 1258{ 1259 int len, i; 1260 1261 len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2; 1262 xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg); 1263 for (i = 0; chips[i].name != NULL; i++) { 1264 if (i != 0) { 1265 xf86ErrorF(","); 1266 len++; 1267 } 1268 if (len + 2 + strlen(chips[i].name) < 78) { 1269 xf86ErrorF(" "); 1270 len++; 1271 } 1272 else { 1273 xf86ErrorF("\n\t"); 1274 len = 8; 1275 } 1276 xf86ErrorF("%s", chips[i].name); 1277 len += strlen(chips[i].name); 1278 } 1279 xf86ErrorF("\n"); 1280} 1281 1282int 1283xf86MatchDevice(const char *drivername, GDevPtr ** sectlist) 1284{ 1285 GDevPtr gdp, *pgdp = NULL; 1286 confScreenPtr screensecptr; 1287 int i, j, k; 1288 1289 if (sectlist) 1290 *sectlist = NULL; 1291 1292 /* 1293 * 20111009 jmcneill: This line was removed with the following commit upstream: 1294 * http://cgit.freedesktop.org/xorg/xserver/commit/hw/xfree86/common/xf86Helper.c?id=0ceac6f64f5ad9bc2ac4b19be2dd245ffba78b05 1295 * 1296 * However, the log message is inaccurate: xf86MatchDevice will get called at 1297 * configuration time by drivers who still implement the legacy probing 1298 * API. 1299 */ 1300 if (xf86DoConfigure && xf86DoConfigurePass1) return 1; 1301 1302 /* 1303 * This can happen when running Xorg -showopts and a module like ati 1304 * or vmware tries to load its submodules when xf86ConfigLayout is empty 1305 */ 1306 if (!xf86ConfigLayout.screens) 1307 return 0; 1308 1309 /* 1310 * This is a very important function that matches the device sections 1311 * as they show up in the config file with the drivers that the server 1312 * loads at run time. 1313 * 1314 * ChipProbe can call 1315 * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist) 1316 * with its driver name. The function allocates an array of GDevPtr and 1317 * returns this via sectlist and returns the number of elements in 1318 * this list as return value. 0 means none found, -1 means fatal error. 1319 * 1320 * It can figure out which of the Device sections to use for which card 1321 * (using things like the Card statement, etc). For single headed servers 1322 * there will of course be just one such Device section. 1323 */ 1324 i = 0; 1325 1326 /* 1327 * first we need to loop over all the Screens sections to get to all 1328 * 'active' device sections 1329 */ 1330 for (j = 0; xf86ConfigLayout.screens[j].screen != NULL; j++) { 1331 screensecptr = xf86ConfigLayout.screens[j].screen; 1332 if ((screensecptr->device != NULL) 1333 && (screensecptr->device->driver != NULL) 1334 && (xf86NameCmp(screensecptr->device->driver, drivername) == 0) 1335 && (!screensecptr->device->claimed)) { 1336 /* 1337 * we have a matching driver that wasn't claimed, yet 1338 */ 1339 pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr)); 1340 pgdp[i++] = screensecptr->device; 1341 } 1342 for (k = 0; k < screensecptr->num_gpu_devices; k++) { 1343 if ((screensecptr->gpu_devices[k]->driver != NULL) 1344 && (xf86NameCmp(screensecptr->gpu_devices[k]->driver, drivername) == 0) 1345 && (!screensecptr->gpu_devices[k]->claimed)) { 1346 /* 1347 * we have a matching driver that wasn't claimed, yet 1348 */ 1349 pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); 1350 pgdp[i++] = screensecptr->gpu_devices[k]; 1351 } 1352 } 1353 } 1354 1355 /* Then handle the inactive devices */ 1356 j = 0; 1357 while (xf86ConfigLayout.inactives[j].identifier) { 1358 gdp = &xf86ConfigLayout.inactives[j]; 1359 if (gdp->driver && !gdp->claimed && 1360 !xf86NameCmp(gdp->driver, drivername)) { 1361 /* we have a matching driver that wasn't claimed yet */ 1362 pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr)); 1363 pgdp[i++] = gdp; 1364 } 1365 j++; 1366 } 1367 1368 /* 1369 * make the array NULL terminated and return its address 1370 */ 1371 if (i) 1372 pgdp[i] = NULL; 1373 1374 if (sectlist) 1375 *sectlist = pgdp; 1376 else 1377 free(pgdp); 1378 return i; 1379} 1380 1381const char * 1382xf86GetVisualName(int visual) 1383{ 1384 if (visual < 0 || visual > DirectColor) 1385 return NULL; 1386 1387 return xf86VisualNames[visual]; 1388} 1389 1390int 1391xf86GetVerbosity(void) 1392{ 1393 return max(xf86Verbose, xf86LogVerbose); 1394} 1395 1396int 1397xf86GetDepth(void) 1398{ 1399 return xf86Depth; 1400} 1401 1402rgb 1403xf86GetWeight(void) 1404{ 1405 return xf86Weight; 1406} 1407 1408Gamma 1409xf86GetGamma(void) 1410{ 1411 return xf86Gamma; 1412} 1413 1414Bool 1415xf86GetFlipPixels(void) 1416{ 1417 return xf86FlipPixels; 1418} 1419 1420Bool 1421xf86ServerIsExiting(void) 1422{ 1423 return (dispatchException & DE_TERMINATE) == DE_TERMINATE; 1424} 1425 1426Bool 1427xf86ServerIsResetting(void) 1428{ 1429 return xf86Resetting; 1430} 1431 1432Bool 1433xf86ServerIsOnlyDetecting(void) 1434{ 1435 return xf86DoConfigure; 1436} 1437 1438Bool 1439xf86GetVidModeAllowNonLocal(void) 1440{ 1441 return xf86Info.vidModeAllowNonLocal; 1442} 1443 1444Bool 1445xf86GetVidModeEnabled(void) 1446{ 1447 return xf86Info.vidModeEnabled; 1448} 1449 1450Bool 1451xf86GetModInDevAllowNonLocal(void) 1452{ 1453 return xf86Info.miscModInDevAllowNonLocal; 1454} 1455 1456Bool 1457xf86GetModInDevEnabled(void) 1458{ 1459 return xf86Info.miscModInDevEnabled; 1460} 1461 1462Bool 1463xf86GetAllowMouseOpenFail(void) 1464{ 1465 return xf86Info.allowMouseOpenFail; 1466} 1467 1468CARD32 1469xf86GetModuleVersion(void *module) 1470{ 1471 return (CARD32) LoaderGetModuleVersion(module); 1472} 1473 1474void * 1475xf86LoadDrvSubModule(DriverPtr drv, const char *name) 1476{ 1477 void *ret; 1478 int errmaj = 0, errmin = 0; 1479 1480 ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL, 1481 &errmaj, &errmin); 1482 if (!ret) 1483 LoaderErrorMsg(NULL, name, errmaj, errmin); 1484 return ret; 1485} 1486 1487void * 1488xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name) 1489{ 1490 void *ret; 1491 int errmaj = 0, errmin = 0; 1492 1493 ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL, 1494 &errmaj, &errmin); 1495 if (!ret) 1496 LoaderErrorMsg(pScrn->name, name, errmaj, errmin); 1497 return ret; 1498} 1499 1500/* 1501 * xf86LoadOneModule loads a single module. 1502 */ 1503void * 1504xf86LoadOneModule(const char *name, void *opt) 1505{ 1506 int errmaj; 1507 char *Name; 1508 void *mod; 1509 1510 if (!name) 1511 return NULL; 1512 1513 /* Normalise the module name */ 1514 Name = xf86NormalizeName(name); 1515 1516 /* Skip empty names */ 1517 if (Name == NULL) 1518 return NULL; 1519 if (*Name == '\0') { 1520 free(Name); 1521 return NULL; 1522 } 1523 1524 mod = LoadModule(Name, opt, NULL, &errmaj); 1525 if (!mod) 1526 LoaderErrorMsg(NULL, Name, errmaj, 0); 1527 free(Name); 1528 return mod; 1529} 1530 1531void 1532xf86UnloadSubModule(void *mod) 1533{ 1534 UnloadSubModule(mod); 1535} 1536 1537Bool 1538xf86LoaderCheckSymbol(const char *name) 1539{ 1540 return LoaderSymbol(name) != NULL; 1541} 1542 1543typedef enum { 1544 OPTION_BACKING_STORE 1545} BSOpts; 1546 1547static const OptionInfoRec BSOptions[] = { 1548 {OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE}, 1549 {-1, NULL, OPTV_NONE, {0}, FALSE} 1550}; 1551 1552void 1553xf86SetBackingStore(ScreenPtr pScreen) 1554{ 1555 Bool useBS = FALSE; 1556 MessageType from = X_DEFAULT; 1557 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1558 OptionInfoPtr options; 1559 1560 options = xnfalloc(sizeof(BSOptions)); 1561 (void) memcpy(options, BSOptions, sizeof(BSOptions)); 1562 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); 1563 1564 /* check for commandline option here */ 1565 if (xf86bsEnableFlag) { 1566 from = X_CMDLINE; 1567 useBS = TRUE; 1568 } 1569 else if (xf86bsDisableFlag) { 1570 from = X_CMDLINE; 1571 useBS = FALSE; 1572 } 1573 else { 1574 if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS)) 1575 from = X_CONFIG; 1576#ifdef COMPOSITE 1577 if (from != X_CONFIG) 1578 useBS = xf86ReturnOptValBool(options, OPTION_BACKING_STORE, 1579 !noCompositeExtension); 1580#endif 1581 } 1582 free(options); 1583 pScreen->backingStoreSupport = useBS ? WhenMapped : NotUseful; 1584 if (serverGeneration == 1) 1585 xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n", 1586 useBS ? "enabled" : "disabled"); 1587} 1588 1589typedef enum { 1590 OPTION_SILKEN_MOUSE 1591} SMOpts; 1592 1593static const OptionInfoRec SMOptions[] = { 1594 {OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE}, 1595 {-1, NULL, OPTV_NONE, {0}, FALSE} 1596}; 1597 1598void 1599xf86SetSilkenMouse(ScreenPtr pScreen) 1600{ 1601 Bool useSM = TRUE; 1602 MessageType from = X_DEFAULT; 1603 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1604 OptionInfoPtr options; 1605 1606 options = xnfalloc(sizeof(SMOptions)); 1607 (void) memcpy(options, SMOptions, sizeof(SMOptions)); 1608 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); 1609 1610 /* check for commandline option here */ 1611 /* disable if screen shares resources */ 1612 /* TODO VGA arb disable silken mouse */ 1613 if (xf86silkenMouseDisableFlag) { 1614 from = X_CMDLINE; 1615 useSM = FALSE; 1616 } 1617 else { 1618 if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM)) 1619 from = X_CONFIG; 1620 } 1621 free(options); 1622 /* 1623 * Use silken mouse if requested and if we have threaded input 1624 */ 1625 pScrn->silkenMouse = useSM && InputThreadEnable; 1626 if (serverGeneration == 1) 1627 xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n", 1628 pScrn->silkenMouse ? "enabled" : "disabled"); 1629} 1630 1631/* Wrote this function for the PM2 Xv driver, preliminary. */ 1632 1633void * 1634xf86FindXvOptions(ScrnInfoPtr pScrn, int adaptor_index, const char *port_name, 1635 const char **adaptor_name, void **adaptor_options) 1636{ 1637 confXvAdaptorPtr adaptor; 1638 int i; 1639 1640 if (adaptor_index >= pScrn->confScreen->numxvadaptors) { 1641 if (adaptor_name) 1642 *adaptor_name = NULL; 1643 if (adaptor_options) 1644 *adaptor_options = NULL; 1645 return NULL; 1646 } 1647 1648 adaptor = &pScrn->confScreen->xvadaptors[adaptor_index]; 1649 if (adaptor_name) 1650 *adaptor_name = adaptor->identifier; 1651 if (adaptor_options) 1652 *adaptor_options = adaptor->options; 1653 1654 for (i = 0; i < adaptor->numports; i++) 1655 if (!xf86NameCmp(adaptor->ports[i].identifier, port_name)) 1656 return adaptor->ports[i].options; 1657 1658 return NULL; 1659} 1660 1661static void 1662xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init, 1663 EntityProc enter, EntityProc leave, void *private) 1664{ 1665 ScrnInfoPtr pScrn; 1666 1667 if ((pScrn = xf86FindScreenForEntity(pEnt->index))) 1668 xf86RemoveEntityFromScreen(pScrn, pEnt->index); 1669} 1670 1671ScrnInfoPtr 1672xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex, 1673 EntityProc init, EntityProc enter, EntityProc leave, 1674 void *private) 1675{ 1676 EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex); 1677 1678 if (init || enter || leave) 1679 FatalError("Legacy entity access functions are unsupported\n"); 1680 1681 if (!pEnt) 1682 return pScrn; 1683 1684 if (!(pEnt->location.type == BUS_NONE)) { 1685 free(pEnt); 1686 return pScrn; 1687 } 1688 1689 if (!pEnt->active) { 1690 xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private); 1691 free(pEnt); 1692 return pScrn; 1693 } 1694 1695 if (!pScrn) 1696 pScrn = xf86AllocateScreen(pEnt->driver, scrnFlag); 1697 xf86AddEntityToScreen(pScrn, entityIndex); 1698 1699 free(pEnt); 1700 return pScrn; 1701} 1702 1703Bool 1704xf86IsScreenPrimary(ScrnInfoPtr pScrn) 1705{ 1706 int i; 1707 1708 for (i = 0; i < pScrn->numEntities; i++) { 1709 if (xf86IsEntityPrimary(i)) 1710 return TRUE; 1711 } 1712 return FALSE; 1713} 1714 1715Bool 1716xf86IsUnblank(int mode) 1717{ 1718 switch (mode) { 1719 case SCREEN_SAVER_OFF: 1720 case SCREEN_SAVER_FORCER: 1721 return TRUE; 1722 case SCREEN_SAVER_ON: 1723 case SCREEN_SAVER_CYCLE: 1724 return FALSE; 1725 default: 1726 xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode); 1727 return TRUE; 1728 } 1729} 1730 1731void 1732xf86MotionHistoryAllocate(InputInfoPtr pInfo) 1733{ 1734 AllocateMotionHistory(pInfo->dev); 1735} 1736 1737ScrnInfoPtr 1738xf86ScreenToScrn(ScreenPtr pScreen) 1739{ 1740 if (pScreen->isGPU) { 1741 assert(pScreen->myNum - GPU_SCREEN_OFFSET < xf86NumGPUScreens); 1742 return xf86GPUScreens[pScreen->myNum - GPU_SCREEN_OFFSET]; 1743 } else { 1744 assert(pScreen->myNum < xf86NumScreens); 1745 return xf86Screens[pScreen->myNum]; 1746 } 1747} 1748 1749ScreenPtr 1750xf86ScrnToScreen(ScrnInfoPtr pScrn) 1751{ 1752 if (pScrn->is_gpu) { 1753 assert(pScrn->scrnIndex - GPU_SCREEN_OFFSET < screenInfo.numGPUScreens); 1754 return screenInfo.gpuscreens[pScrn->scrnIndex - GPU_SCREEN_OFFSET]; 1755 } else { 1756 assert(pScrn->scrnIndex < screenInfo.numScreens); 1757 return screenInfo.screens[pScrn->scrnIndex]; 1758 } 1759} 1760 1761void 1762xf86UpdateDesktopDimensions(void) 1763{ 1764 update_desktop_dimensions(); 1765} 1766 1767 1768void 1769xf86AddInputEventDrainCallback(CallbackProcPtr callback, void *param) 1770{ 1771 mieqAddCallbackOnDrained(callback, param); 1772} 1773 1774void 1775xf86RemoveInputEventDrainCallback(CallbackProcPtr callback, void *param) 1776{ 1777 mieqRemoveCallbackOnDrained(callback, param); 1778} 1779