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