xf86VidMode.c revision 9ace9065
1/* 2 * Copyright (c) 1999-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 * This file contains the VidMode functions required by the extension. 30 * These have been added to avoid the need for the higher level extension 31 * code to access the private XFree86 data structures directly. Wherever 32 * possible this code uses the functions in xf86Mode.c to do the work, 33 * so that two version of code that do similar things don't have to be 34 * maintained. 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 "xf86.h" 44#include "xf86Priv.h" 45 46#ifdef XF86VIDMODE 47#include "vidmodeproc.h" 48#include "xf86cmap.h" 49 50static DevPrivateKeyRec VidModeKeyRec; 51static DevPrivateKey VidModeKey; 52static int VidModeCount = 0; 53static Bool VidModeClose(int i, ScreenPtr pScreen); 54 55#define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey)) 56 57#endif 58 59Bool 60VidModeExtensionInit(ScreenPtr pScreen) 61{ 62#ifdef XF86VIDMODE 63 VidModePtr pVidMode; 64 65 if (!xf86GetVidModeEnabled()) { 66 DebugF("!xf86GetVidModeEnabled()\n"); 67 return FALSE; 68 } 69 70 VidModeKey = &VidModeKeyRec; 71 72 if (!dixRegisterPrivateKey(&VidModeKeyRec, PRIVATE_SCREEN, 0)) 73 return FALSE; 74 75 pVidMode = calloc(sizeof(VidModeRec), 1); 76 if (!pVidMode) 77 return FALSE; 78 79 dixSetPrivate(&pScreen->devPrivates, VidModeKey, pVidMode); 80 81 pVidMode->Flags = 0; 82 pVidMode->Next = NULL; 83 pVidMode->CloseScreen = pScreen->CloseScreen; 84 pScreen->CloseScreen = VidModeClose; 85 VidModeCount++; 86 return TRUE; 87#else 88 DebugF("no vidmode extension\n"); 89 return FALSE; 90#endif 91} 92 93 94#ifdef XF86VIDMODE 95 96static Bool 97VidModeClose(int i, ScreenPtr pScreen) 98{ 99 VidModePtr pVidMode = VMPTR(pScreen); 100 101 /* This shouldn't happen */ 102 if (!pVidMode) 103 return FALSE; 104 105 pScreen->CloseScreen = pVidMode->CloseScreen; 106 107 if (--VidModeCount == 0) { 108 free(dixLookupPrivate(&pScreen->devPrivates, VidModeKey)); 109 dixSetPrivate(&pScreen->devPrivates, VidModeKey, NULL); 110 VidModeKey = NULL; 111 } 112 return pScreen->CloseScreen(i, pScreen); 113} 114 115Bool 116VidModeAvailable(int scrnIndex) 117{ 118 ScrnInfoPtr pScrn; 119 VidModePtr pVidMode; 120 121 if (VidModeKey == NULL) { 122 DebugF("VidModeKey == NULL\n"); 123 return FALSE; 124 } 125 126 pScrn = xf86Screens[scrnIndex]; 127 if (pScrn == NULL) { 128 DebugF("pScrn == NULL\n"); 129 return FALSE; 130 } 131 132 pVidMode = VMPTR(pScrn->pScreen); 133 if (pVidMode) 134 return TRUE; 135 else { 136 DebugF("pVidMode == NULL\n"); 137 return FALSE; 138 } 139} 140 141Bool 142VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock) 143{ 144 ScrnInfoPtr pScrn; 145 146 if (!VidModeAvailable(scrnIndex)) 147 return FALSE; 148 149 pScrn = xf86Screens[scrnIndex]; 150 151 if (pScrn->currentMode) { 152 *mode = (pointer)(pScrn->currentMode); 153 *dotClock = pScrn->currentMode->Clock; 154 155 return TRUE; 156 } 157 return FALSE; 158} 159 160int 161VidModeGetDotClock(int scrnIndex, int Clock) 162{ 163 ScrnInfoPtr pScrn; 164 165 if (!VidModeAvailable(scrnIndex)) 166 return 0; 167 168 pScrn = xf86Screens[scrnIndex]; 169 if ((pScrn->progClock) || (Clock >= MAXCLOCKS)) 170 return Clock; 171 else 172 return pScrn->clock[Clock]; 173} 174 175int 176VidModeGetNumOfClocks(int scrnIndex, Bool *progClock) 177{ 178 ScrnInfoPtr pScrn; 179 180 if (!VidModeAvailable(scrnIndex)) 181 return 0; 182 183 pScrn = xf86Screens[scrnIndex]; 184 if (pScrn->progClock){ 185 *progClock = TRUE; 186 return 0; 187 } else { 188 *progClock = FALSE; 189 return pScrn->numClocks; 190 } 191} 192 193Bool 194VidModeGetClocks(int scrnIndex, int *Clocks) 195{ 196 ScrnInfoPtr pScrn; 197 int i; 198 199 if (!VidModeAvailable(scrnIndex)) 200 return FALSE; 201 202 pScrn = xf86Screens[scrnIndex]; 203 204 if (pScrn->progClock) 205 return FALSE; 206 207 for (i = 0; i < pScrn->numClocks; i++) 208 *Clocks++ = pScrn->clock[i]; 209 210 return TRUE; 211} 212 213 214Bool 215VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock) 216{ 217 ScrnInfoPtr pScrn; 218 VidModePtr pVidMode; 219 220 if (!VidModeAvailable(scrnIndex)) 221 return FALSE; 222 223 pScrn = xf86Screens[scrnIndex]; 224 pVidMode = VMPTR(pScrn->pScreen); 225 pVidMode->First = pScrn->modes; 226 pVidMode->Next = pVidMode->First->next; 227 228 if (pVidMode->First->status == MODE_OK) { 229 *mode = (pointer)(pVidMode->First); 230 *dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock); 231 return TRUE; 232 } 233 234 return VidModeGetNextModeline(scrnIndex, mode, dotClock); 235} 236 237Bool 238VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock) 239{ 240 ScrnInfoPtr pScrn; 241 VidModePtr pVidMode; 242 DisplayModePtr p; 243 244 if (!VidModeAvailable(scrnIndex)) 245 return FALSE; 246 247 pScrn = xf86Screens[scrnIndex]; 248 pVidMode = VMPTR(pScrn->pScreen); 249 250 for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) { 251 if (p->status == MODE_OK) { 252 pVidMode->Next = p->next; 253 *mode = (pointer)p; 254 *dotClock = VidModeGetDotClock(scrnIndex, p->Clock); 255 return TRUE; 256 } 257 } 258 259 return FALSE; 260} 261 262Bool 263VidModeDeleteModeline(int scrnIndex, pointer mode) 264{ 265 ScrnInfoPtr pScrn; 266 267 if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) 268 return FALSE; 269 270 pScrn = xf86Screens[scrnIndex]; 271 xf86DeleteMode(&(pScrn->modes), (DisplayModePtr)mode); 272 return TRUE; 273} 274 275Bool 276VidModeZoomViewport(int scrnIndex, int zoom) 277{ 278 ScrnInfoPtr pScrn; 279 280 if (!VidModeAvailable(scrnIndex)) 281 return FALSE; 282 283 pScrn = xf86Screens[scrnIndex]; 284 xf86ZoomViewport(pScrn->pScreen, zoom); 285 return TRUE; 286} 287 288Bool 289VidModeSetViewPort(int scrnIndex, int x, int y) 290{ 291 ScrnInfoPtr pScrn; 292 293 if (!VidModeAvailable(scrnIndex)) 294 return FALSE; 295 296 pScrn = xf86Screens[scrnIndex]; 297 pScrn->frameX0 = min( max(x, 0), 298 pScrn->virtualX - pScrn->currentMode->HDisplay ); 299 pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1; 300 pScrn->frameY0 = min( max(y, 0), 301 pScrn->virtualY - pScrn->currentMode->VDisplay ); 302 pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1; 303 if (pScrn->AdjustFrame != NULL) 304 (pScrn->AdjustFrame)(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 305 306 return TRUE; 307} 308 309Bool 310VidModeGetViewPort(int scrnIndex, int *x, int *y) 311{ 312 ScrnInfoPtr pScrn; 313 314 if (!VidModeAvailable(scrnIndex)) 315 return FALSE; 316 317 pScrn = xf86Screens[scrnIndex]; 318 *x = pScrn->frameX0; 319 *y = pScrn->frameY0; 320 return TRUE; 321} 322 323Bool 324VidModeSwitchMode(int scrnIndex, pointer mode) 325{ 326 ScrnInfoPtr pScrn; 327 DisplayModePtr pTmpMode; 328 Bool retval; 329 330 if (!VidModeAvailable(scrnIndex)) 331 return FALSE; 332 333 pScrn = xf86Screens[scrnIndex]; 334 /* save in case we fail */ 335 pTmpMode = pScrn->currentMode; 336 /* Force a mode switch */ 337 pScrn->currentMode = NULL; 338 retval = xf86SwitchMode(pScrn->pScreen, mode); 339 /* we failed: restore it */ 340 if (retval == FALSE) 341 pScrn->currentMode = pTmpMode; 342 return retval; 343} 344 345Bool 346VidModeLockZoom(int scrnIndex, Bool lock) 347{ 348 ScrnInfoPtr pScrn; 349 350 if (!VidModeAvailable(scrnIndex)) 351 return FALSE; 352 353 pScrn = xf86Screens[scrnIndex]; 354 355 if (xf86Info.dontZoom) 356 return FALSE; 357 358 xf86LockZoom(pScrn->pScreen, lock); 359 return TRUE; 360} 361 362Bool 363VidModeGetMonitor(int scrnIndex, pointer *monitor) 364{ 365 ScrnInfoPtr pScrn; 366 367 if (!VidModeAvailable(scrnIndex)) 368 return FALSE; 369 370 pScrn = xf86Screens[scrnIndex]; 371 *monitor = (pointer)(pScrn->monitor); 372 373 return TRUE; 374} 375 376ModeStatus 377VidModeCheckModeForMonitor(int scrnIndex, pointer mode) 378{ 379 ScrnInfoPtr pScrn; 380 381 if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) 382 return MODE_ERROR; 383 384 pScrn = xf86Screens[scrnIndex]; 385 386 return xf86CheckModeForMonitor((DisplayModePtr)mode, pScrn->monitor); 387} 388 389ModeStatus 390VidModeCheckModeForDriver(int scrnIndex, pointer mode) 391{ 392 ScrnInfoPtr pScrn; 393 394 if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) 395 return MODE_ERROR; 396 397 pScrn = xf86Screens[scrnIndex]; 398 399 return xf86CheckModeForDriver(pScrn, (DisplayModePtr)mode, 0); 400} 401 402void 403VidModeSetCrtcForMode(int scrnIndex, pointer mode) 404{ 405 ScrnInfoPtr pScrn; 406 DisplayModePtr ScreenModes; 407 408 if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) 409 return; 410 411 /* Ugly hack so that the xf86Mode.c function can be used without change */ 412 pScrn = xf86Screens[scrnIndex]; 413 ScreenModes = pScrn->modes; 414 pScrn->modes = (DisplayModePtr)mode; 415 416 xf86SetCrtcForModes(pScrn, pScrn->adjustFlags); 417 pScrn->modes = ScreenModes; 418 return; 419} 420 421Bool 422VidModeAddModeline(int scrnIndex, pointer mode) 423{ 424 ScrnInfoPtr pScrn; 425 426 if ((mode == NULL) || (!VidModeAvailable(scrnIndex))) 427 return FALSE; 428 429 pScrn = xf86Screens[scrnIndex]; 430 431 ((DisplayModePtr)mode)->name = strdup(""); /* freed by deletemode */ 432 ((DisplayModePtr)mode)->status = MODE_OK; 433 ((DisplayModePtr)mode)->next = pScrn->modes->next; 434 ((DisplayModePtr)mode)->prev = pScrn->modes; 435 pScrn->modes->next = (DisplayModePtr)mode; 436 if( ((DisplayModePtr)mode)->next != NULL ) 437 ((DisplayModePtr)mode)->next->prev = (DisplayModePtr)mode; 438 439 return TRUE; 440} 441 442int 443VidModeGetNumOfModes(int scrnIndex) 444{ 445 pointer mode = NULL; 446 int dotClock= 0, nummodes = 0; 447 448 if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock)) 449 return nummodes; 450 451 do { 452 nummodes++; 453 if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock)) 454 return nummodes; 455 } while (TRUE); 456} 457 458Bool 459VidModeSetGamma(int scrnIndex, float red, float green, float blue) 460{ 461 ScrnInfoPtr pScrn; 462 Gamma gamma; 463 464 if (!VidModeAvailable(scrnIndex)) 465 return FALSE; 466 467 pScrn = xf86Screens[scrnIndex]; 468 gamma.red = red; 469 gamma.green = green; 470 gamma.blue = blue; 471 if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success) 472 return FALSE; 473 else 474 return TRUE; 475} 476 477Bool 478VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue) 479{ 480 ScrnInfoPtr pScrn; 481 482 if (!VidModeAvailable(scrnIndex)) 483 return FALSE; 484 485 pScrn = xf86Screens[scrnIndex]; 486 *red = pScrn->gamma.red; 487 *green = pScrn->gamma.green; 488 *blue = pScrn->gamma.blue; 489 return TRUE; 490} 491 492Bool 493VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b) 494{ 495 ScrnInfoPtr pScrn; 496 497 if (!VidModeAvailable(scrnIndex)) 498 return FALSE; 499 500 pScrn = xf86Screens[scrnIndex]; 501 xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b); 502 return TRUE; 503} 504 505Bool 506VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b) 507{ 508 ScrnInfoPtr pScrn; 509 510 if (!VidModeAvailable(scrnIndex)) 511 return FALSE; 512 513 pScrn = xf86Screens[scrnIndex]; 514 xf86GetGammaRamp(pScrn->pScreen, size, r, g, b); 515 return TRUE; 516} 517 518int 519VidModeGetGammaRampSize(int scrnIndex) 520{ 521 if (!VidModeAvailable(scrnIndex)) 522 return 0; 523 524 return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen); 525} 526 527pointer 528VidModeCreateMode(void) 529{ 530 DisplayModePtr mode; 531 532 mode = malloc(sizeof(DisplayModeRec)); 533 if (mode != NULL) { 534 mode->name = ""; 535 mode->VScan = 1; /* divides refresh rate. default = 1 */ 536 mode->Private = NULL; 537 mode->next = mode; 538 mode->prev = mode; 539 } 540 return mode; 541} 542 543void 544VidModeCopyMode(pointer modefrom, pointer modeto) 545{ 546 memcpy(modeto, modefrom, sizeof(DisplayModeRec)); 547} 548 549 550int 551VidModeGetModeValue(pointer mode, int valtyp) 552{ 553 int ret = 0; 554 555 switch (valtyp) { 556 case VIDMODE_H_DISPLAY: 557 ret = ((DisplayModePtr) mode)->HDisplay; 558 break; 559 case VIDMODE_H_SYNCSTART: 560 ret = ((DisplayModePtr)mode)->HSyncStart; 561 break; 562 case VIDMODE_H_SYNCEND: 563 ret = ((DisplayModePtr)mode)->HSyncEnd; 564 break; 565 case VIDMODE_H_TOTAL: 566 ret = ((DisplayModePtr)mode)->HTotal; 567 break; 568 case VIDMODE_H_SKEW: 569 ret = ((DisplayModePtr)mode)->HSkew; 570 break; 571 case VIDMODE_V_DISPLAY: 572 ret = ((DisplayModePtr)mode)->VDisplay; 573 break; 574 case VIDMODE_V_SYNCSTART: 575 ret = ((DisplayModePtr)mode)->VSyncStart; 576 break; 577 case VIDMODE_V_SYNCEND: 578 ret = ((DisplayModePtr)mode)->VSyncEnd; 579 break; 580 case VIDMODE_V_TOTAL: 581 ret = ((DisplayModePtr)mode)->VTotal; 582 break; 583 case VIDMODE_FLAGS: 584 ret = ((DisplayModePtr)mode)->Flags; 585 break; 586 case VIDMODE_CLOCK: 587 ret = ((DisplayModePtr)mode)->Clock; 588 break; 589 } 590 return ret; 591} 592 593void 594VidModeSetModeValue(pointer mode, int valtyp, int val) 595{ 596 switch (valtyp) { 597 case VIDMODE_H_DISPLAY: 598 ((DisplayModePtr)mode)->HDisplay = val; 599 break; 600 case VIDMODE_H_SYNCSTART: 601 ((DisplayModePtr)mode)->HSyncStart = val; 602 break; 603 case VIDMODE_H_SYNCEND: 604 ((DisplayModePtr)mode)->HSyncEnd = val; 605 break; 606 case VIDMODE_H_TOTAL: 607 ((DisplayModePtr)mode)->HTotal = val; 608 break; 609 case VIDMODE_H_SKEW: 610 ((DisplayModePtr)mode)->HSkew = val; 611 break; 612 case VIDMODE_V_DISPLAY: 613 ((DisplayModePtr)mode)->VDisplay = val; 614 break; 615 case VIDMODE_V_SYNCSTART: 616 ((DisplayModePtr)mode)->VSyncStart = val; 617 break; 618 case VIDMODE_V_SYNCEND: 619 ((DisplayModePtr)mode)->VSyncEnd = val; 620 break; 621 case VIDMODE_V_TOTAL: 622 ((DisplayModePtr)mode)->VTotal = val; 623 break; 624 case VIDMODE_FLAGS: 625 ((DisplayModePtr)mode)->Flags = val; 626 break; 627 case VIDMODE_CLOCK: 628 ((DisplayModePtr)mode)->Clock = val; 629 break; 630 } 631 return; 632} 633 634vidMonitorValue 635VidModeGetMonitorValue(pointer monitor, int valtyp, int indx) 636{ 637 vidMonitorValue ret = { NULL, }; 638 639 switch (valtyp) { 640 case VIDMODE_MON_VENDOR: 641 ret.ptr = (((MonPtr)monitor)->vendor); 642 break; 643 case VIDMODE_MON_MODEL: 644 ret.ptr = (((MonPtr)monitor)->model); 645 break; 646 case VIDMODE_MON_NHSYNC: 647 ret.i = ((MonPtr)monitor)->nHsync; 648 break; 649 case VIDMODE_MON_NVREFRESH: 650 ret.i = ((MonPtr)monitor)->nVrefresh; 651 break; 652 case VIDMODE_MON_HSYNC_LO: 653 ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].lo); 654 break; 655 case VIDMODE_MON_HSYNC_HI: 656 ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].hi); 657 break; 658 case VIDMODE_MON_VREFRESH_LO: 659 ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].lo); 660 break; 661 case VIDMODE_MON_VREFRESH_HI: 662 ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].hi); 663 break; 664 } 665 return ret; 666} 667 668 669#endif /* XF86VIDMODE */ 670