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