xf86VidMode.c revision 35c4bbdf
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#include "extinit.h" 46 47#ifdef XF86VIDMODE 48#include "vidmodestr.h" 49#include "xf86Privstr.h" 50#include "xf86Extensions.h" 51#include "xf86cmap.h" 52 53static vidMonitorValue 54xf86VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx) 55{ 56 vidMonitorValue ret = { NULL, }; 57 MonPtr monitor; 58 ScrnInfoPtr pScrn; 59 60 pScrn = xf86ScreenToScrn(pScreen); 61 monitor = pScrn->monitor; 62 63 switch (valtyp) { 64 case VIDMODE_MON_VENDOR: 65 ret.ptr = monitor->vendor; 66 break; 67 case VIDMODE_MON_MODEL: 68 ret.ptr = monitor->model; 69 break; 70 case VIDMODE_MON_NHSYNC: 71 ret.i = monitor->nHsync; 72 break; 73 case VIDMODE_MON_NVREFRESH: 74 ret.i = monitor->nVrefresh; 75 break; 76 case VIDMODE_MON_HSYNC_LO: 77 ret.f = (100.0 * monitor->hsync[indx].lo); 78 break; 79 case VIDMODE_MON_HSYNC_HI: 80 ret.f = (100.0 * monitor->hsync[indx].hi); 81 break; 82 case VIDMODE_MON_VREFRESH_LO: 83 ret.f = (100.0 * monitor->vrefresh[indx].lo); 84 break; 85 case VIDMODE_MON_VREFRESH_HI: 86 ret.f = (100.0 * monitor->vrefresh[indx].hi); 87 break; 88 } 89 return ret; 90} 91 92static Bool 93xf86VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock) 94{ 95 ScrnInfoPtr pScrn; 96 97 pScrn = xf86ScreenToScrn(pScreen); 98 99 if (pScrn->currentMode) { 100 *mode = pScrn->currentMode; 101 *dotClock = pScrn->currentMode->Clock; 102 103 return TRUE; 104 } 105 return FALSE; 106} 107 108static int 109xf86VidModeGetDotClock(ScreenPtr pScreen, int Clock) 110{ 111 ScrnInfoPtr pScrn; 112 113 pScrn = xf86ScreenToScrn(pScreen); 114 if ((pScrn->progClock) || (Clock >= MAXCLOCKS)) 115 return Clock; 116 else 117 return pScrn->clock[Clock]; 118} 119 120static int 121xf86VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock) 122{ 123 ScrnInfoPtr pScrn; 124 125 pScrn = xf86ScreenToScrn(pScreen); 126 if (pScrn->progClock) { 127 *progClock = TRUE; 128 return 0; 129 } 130 else { 131 *progClock = FALSE; 132 return pScrn->numClocks; 133 } 134} 135 136static Bool 137xf86VidModeGetClocks(ScreenPtr pScreen, int *Clocks) 138{ 139 ScrnInfoPtr pScrn; 140 int i; 141 142 pScrn = xf86ScreenToScrn(pScreen); 143 144 if (pScrn->progClock) 145 return FALSE; 146 147 for (i = 0; i < pScrn->numClocks; i++) 148 *Clocks++ = pScrn->clock[i]; 149 150 return TRUE; 151} 152 153static Bool 154xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock) 155{ 156 VidModePtr pVidMode; 157 DisplayModePtr p; 158 159 pVidMode = VidModeGetPtr(pScreen); 160 161 for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) { 162 if (p->status == MODE_OK) { 163 pVidMode->Next = p->next; 164 *mode = p; 165 *dotClock = xf86VidModeGetDotClock(pScreen, p->Clock); 166 return TRUE; 167 } 168 } 169 170 return FALSE; 171} 172 173static Bool 174xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock) 175{ 176 ScrnInfoPtr pScrn; 177 VidModePtr pVidMode; 178 179 pScrn = xf86ScreenToScrn(pScreen); 180 if (pScrn->modes == NULL) 181 return FALSE; 182 183 pVidMode = VidModeGetPtr(pScreen); 184 pVidMode->First = pScrn->modes; 185 pVidMode->Next = pVidMode->First->next; 186 187 if (pVidMode->First->status == MODE_OK) { 188 *mode = pVidMode->First; 189 *dotClock = xf86VidModeGetDotClock(pScreen, pVidMode->First->Clock); 190 return TRUE; 191 } 192 193 return xf86VidModeGetNextModeline(pScreen, mode, dotClock); 194} 195 196static Bool 197xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode) 198{ 199 ScrnInfoPtr pScrn; 200 201 if (mode == NULL) 202 return FALSE; 203 204 pScrn = xf86ScreenToScrn(pScreen); 205 xf86DeleteMode(&(pScrn->modes), mode); 206 return TRUE; 207} 208 209static Bool 210xf86VidModeZoomViewport(ScreenPtr pScreen, int zoom) 211{ 212 xf86ZoomViewport(pScreen, zoom); 213 return TRUE; 214} 215 216static Bool 217xf86VidModeSetViewPort(ScreenPtr pScreen, int x, int y) 218{ 219 ScrnInfoPtr pScrn; 220 221 pScrn = xf86ScreenToScrn(pScreen); 222 pScrn->frameX0 = min(max(x, 0), 223 pScrn->virtualX - pScrn->currentMode->HDisplay); 224 pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1; 225 pScrn->frameY0 = min(max(y, 0), 226 pScrn->virtualY - pScrn->currentMode->VDisplay); 227 pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1; 228 if (pScrn->AdjustFrame != NULL) 229 (pScrn->AdjustFrame) (pScrn, pScrn->frameX0, pScrn->frameY0); 230 231 return TRUE; 232} 233 234static Bool 235xf86VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y) 236{ 237 ScrnInfoPtr pScrn; 238 239 pScrn = xf86ScreenToScrn(pScreen); 240 *x = pScrn->frameX0; 241 *y = pScrn->frameY0; 242 return TRUE; 243} 244 245static Bool 246xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode) 247{ 248 ScrnInfoPtr pScrn; 249 DisplayModePtr pTmpMode; 250 Bool retval; 251 252 pScrn = xf86ScreenToScrn(pScreen); 253 /* save in case we fail */ 254 pTmpMode = pScrn->currentMode; 255 /* Force a mode switch */ 256 pScrn->currentMode = NULL; 257 retval = xf86SwitchMode(pScrn->pScreen, mode); 258 /* we failed: restore it */ 259 if (retval == FALSE) 260 pScrn->currentMode = pTmpMode; 261 return retval; 262} 263 264static Bool 265xf86VidModeLockZoom(ScreenPtr pScreen, Bool lock) 266{ 267 if (xf86Info.dontZoom) 268 return FALSE; 269 270 xf86LockZoom(pScreen, lock); 271 return TRUE; 272} 273 274static ModeStatus 275xf86VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode) 276{ 277 ScrnInfoPtr pScrn; 278 279 if (mode == NULL) 280 return MODE_ERROR; 281 282 pScrn = xf86ScreenToScrn(pScreen); 283 284 return xf86CheckModeForMonitor(mode, pScrn->monitor); 285} 286 287static ModeStatus 288xf86VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode) 289{ 290 ScrnInfoPtr pScrn; 291 292 if (mode == NULL) 293 return MODE_ERROR; 294 295 pScrn = xf86ScreenToScrn(pScreen); 296 297 return xf86CheckModeForDriver(pScrn, mode, 0); 298} 299 300static void 301xf86VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode) 302{ 303 ScrnInfoPtr pScrn; 304 DisplayModePtr ScreenModes; 305 306 if (mode == NULL) 307 return; 308 309 /* Ugly hack so that the xf86Mode.c function can be used without change */ 310 pScrn = xf86ScreenToScrn(pScreen); 311 ScreenModes = pScrn->modes; 312 pScrn->modes = mode; 313 314 xf86SetCrtcForModes(pScrn, pScrn->adjustFlags); 315 pScrn->modes = ScreenModes; 316 return; 317} 318 319static Bool 320xf86VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode) 321{ 322 ScrnInfoPtr pScrn; 323 324 if (mode == NULL) 325 return FALSE; 326 327 pScrn = xf86ScreenToScrn(pScreen); 328 329 mode->name = strdup(""); /* freed by deletemode */ 330 mode->status = MODE_OK; 331 mode->next = pScrn->modes->next; 332 mode->prev = pScrn->modes; 333 pScrn->modes->next = mode; 334 if (mode->next != NULL) 335 mode->next->prev = mode; 336 337 return TRUE; 338} 339 340static int 341xf86VidModeGetNumOfModes(ScreenPtr pScreen) 342{ 343 DisplayModePtr mode = NULL; 344 int dotClock = 0, nummodes = 0; 345 346 if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock)) 347 return nummodes; 348 349 do { 350 nummodes++; 351 if (!xf86VidModeGetNextModeline(pScreen, &mode, &dotClock)) 352 return nummodes; 353 } while (TRUE); 354} 355 356static Bool 357xf86VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue) 358{ 359 Gamma gamma; 360 361 gamma.red = red; 362 gamma.green = green; 363 gamma.blue = blue; 364 if (xf86ChangeGamma(pScreen, gamma) != Success) 365 return FALSE; 366 else 367 return TRUE; 368} 369 370static Bool 371xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue) 372{ 373 ScrnInfoPtr pScrn; 374 375 pScrn = xf86ScreenToScrn(pScreen); 376 *red = pScrn->gamma.red; 377 *green = pScrn->gamma.green; 378 *blue = pScrn->gamma.blue; 379 return TRUE; 380} 381 382static Bool 383xf86VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b) 384{ 385 xf86ChangeGammaRamp(pScreen, size, r, g, b); 386 return TRUE; 387} 388 389static Bool 390xf86VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b) 391{ 392 xf86GetGammaRamp(pScreen, size, r, g, b); 393 return TRUE; 394} 395 396static Bool 397xf86VidModeInit(ScreenPtr pScreen) 398{ 399 VidModePtr pVidMode; 400 401 if (!xf86GetVidModeEnabled()) { 402 DebugF("!xf86GetVidModeEnabled()\n"); 403 return FALSE; 404 } 405 406 pVidMode = VidModeInit(pScreen); 407 if (!pVidMode) 408 return FALSE; 409 410 pVidMode->Flags = 0; 411 pVidMode->Next = NULL; 412 413 pVidMode->GetMonitorValue = xf86VidModeGetMonitorValue; 414 pVidMode->GetCurrentModeline = xf86VidModeGetCurrentModeline; 415 pVidMode->GetFirstModeline = xf86VidModeGetFirstModeline; 416 pVidMode->GetNextModeline = xf86VidModeGetNextModeline; 417 pVidMode->DeleteModeline = xf86VidModeDeleteModeline; 418 pVidMode->ZoomViewport = xf86VidModeZoomViewport; 419 pVidMode->GetViewPort = xf86VidModeGetViewPort; 420 pVidMode->SetViewPort = xf86VidModeSetViewPort; 421 pVidMode->SwitchMode = xf86VidModeSwitchMode; 422 pVidMode->LockZoom = xf86VidModeLockZoom; 423 pVidMode->GetNumOfClocks = xf86VidModeGetNumOfClocks; 424 pVidMode->GetClocks = xf86VidModeGetClocks; 425 pVidMode->CheckModeForMonitor = xf86VidModeCheckModeForMonitor; 426 pVidMode->CheckModeForDriver = xf86VidModeCheckModeForDriver; 427 pVidMode->SetCrtcForMode = xf86VidModeSetCrtcForMode; 428 pVidMode->AddModeline = xf86VidModeAddModeline; 429 pVidMode->GetDotClock = xf86VidModeGetDotClock; 430 pVidMode->GetNumOfModes = xf86VidModeGetNumOfModes; 431 pVidMode->SetGamma = xf86VidModeSetGamma; 432 pVidMode->GetGamma = xf86VidModeGetGamma; 433 pVidMode->SetGammaRamp = xf86VidModeSetGammaRamp; 434 pVidMode->GetGammaRamp = xf86VidModeGetGammaRamp; 435 pVidMode->GetGammaRampSize = xf86GetGammaRampSize; /* use xf86cmap API directly */ 436 437 return TRUE; 438} 439 440void 441XFree86VidModeExtensionInit(void) 442{ 443 int i; 444 Bool enabled = FALSE; 445 446 DebugF("XFree86VidModeExtensionInit"); 447 448 /* This means that the DDX doesn't want the vidmode extension enabled */ 449 if (!xf86GetVidModeEnabled()) 450 return; 451 452 for (i = 0; i < screenInfo.numScreens; i++) { 453 if (xf86VidModeInit (screenInfo.screens[i])) 454 enabled = TRUE; 455 } 456 /* This means that the DDX doesn't want the vidmode extension enabled */ 457 if (!enabled) 458 return; 459 460 VidModeAddExtension(xf86GetVidModeAllowNonLocal()); 461} 462 463#endif /* XF86VIDMODE */ 464