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