2 * Copyright (c) 1999-2003 by The XFree86 Project, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
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).
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
37 #ifdef HAVE_XORG_CONFIG_H
38 #include <xorg-config.h>
47 #include "vidmodeproc.h"
50 static DevPrivateKeyRec VidModeKeyRec
;
51 static DevPrivateKey VidModeKey
;
52 static int VidModeCount
= 0;
53 static Bool
VidModeClose(ScreenPtr pScreen
);
55 #define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey))
60 VidModeExtensionInit(ScreenPtr pScreen
)
65 if (!xf86GetVidModeEnabled()) {
66 DebugF("!xf86GetVidModeEnabled()\n");
70 VidModeKey
= &VidModeKeyRec
;
72 if (!dixRegisterPrivateKey(&VidModeKeyRec
, PRIVATE_SCREEN
, 0))
75 pVidMode
= calloc(sizeof(VidModeRec
), 1);
79 dixSetPrivate(&pScreen
->devPrivates
, VidModeKey
, pVidMode
);
82 pVidMode
->Next
= NULL
;
83 pVidMode
->CloseScreen
= pScreen
->CloseScreen
;
84 pScreen
->CloseScreen
= VidModeClose
;
88 DebugF("no vidmode extension\n");
96 VidModeClose(ScreenPtr pScreen
)
98 VidModePtr pVidMode
= VMPTR(pScreen
);
100 /* This shouldn't happen */
104 pScreen
->CloseScreen
= pVidMode
->CloseScreen
;
106 if (--VidModeCount
== 0) {
107 free(dixLookupPrivate(&pScreen
->devPrivates
, VidModeKey
));
108 dixSetPrivate(&pScreen
->devPrivates
, VidModeKey
, NULL
);
111 return pScreen
->CloseScreen(pScreen
);
115 VidModeAvailable(int scrnIndex
)
120 if (VidModeKey
== NULL
) {
121 DebugF("VidModeKey == NULL\n");
125 pScrn
= xf86Screens
[scrnIndex
];
127 DebugF("pScrn == NULL\n");
131 pVidMode
= VMPTR(pScrn
->pScreen
);
135 DebugF("pVidMode == NULL\n");
141 VidModeGetCurrentModeline(int scrnIndex
, pointer
*mode
, int *dotClock
)
145 if (!VidModeAvailable(scrnIndex
))
148 pScrn
= xf86Screens
[scrnIndex
];
150 if (pScrn
->currentMode
) {
151 *mode
= (pointer
) (pScrn
->currentMode
);
152 *dotClock
= pScrn
->currentMode
->Clock
;
160 VidModeGetDotClock(int scrnIndex
, int Clock
)
164 if (!VidModeAvailable(scrnIndex
))
167 pScrn
= xf86Screens
[scrnIndex
];
168 if ((pScrn
->progClock
) || (Clock
>= MAXCLOCKS
))
171 return pScrn
->clock
[Clock
];
175 VidModeGetNumOfClocks(int scrnIndex
, Bool
*progClock
)
179 if (!VidModeAvailable(scrnIndex
))
182 pScrn
= xf86Screens
[scrnIndex
];
183 if (pScrn
->progClock
) {
189 return pScrn
->numClocks
;
194 VidModeGetClocks(int scrnIndex
, int *Clocks
)
199 if (!VidModeAvailable(scrnIndex
))
202 pScrn
= xf86Screens
[scrnIndex
];
204 if (pScrn
->progClock
)
207 for (i
= 0; i
< pScrn
->numClocks
; i
++)
208 *Clocks
++ = pScrn
->clock
[i
];
214 VidModeGetFirstModeline(int scrnIndex
, pointer
*mode
, int *dotClock
)
219 if (!VidModeAvailable(scrnIndex
))
222 pScrn
= xf86Screens
[scrnIndex
];
223 if (pScrn
->modes
== NULL
)
226 pVidMode
= VMPTR(pScrn
->pScreen
);
227 pVidMode
->First
= pScrn
->modes
;
228 pVidMode
->Next
= pVidMode
->First
->next
;
230 if (pVidMode
->First
->status
== MODE_OK
) {
231 *mode
= (pointer
) (pVidMode
->First
);
232 *dotClock
= VidModeGetDotClock(scrnIndex
, pVidMode
->First
->Clock
);
236 return VidModeGetNextModeline(scrnIndex
, mode
, dotClock
);
240 VidModeGetNextModeline(int scrnIndex
, pointer
*mode
, int *dotClock
)
246 if (!VidModeAvailable(scrnIndex
))
249 pScrn
= xf86Screens
[scrnIndex
];
250 pVidMode
= VMPTR(pScrn
->pScreen
);
252 for (p
= pVidMode
->Next
; p
!= NULL
&& p
!= pVidMode
->First
; p
= p
->next
) {
253 if (p
->status
== MODE_OK
) {
254 pVidMode
->Next
= p
->next
;
256 *dotClock
= VidModeGetDotClock(scrnIndex
, p
->Clock
);
265 VidModeDeleteModeline(int scrnIndex
, pointer mode
)
269 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
272 pScrn
= xf86Screens
[scrnIndex
];
273 xf86DeleteMode(&(pScrn
->modes
), (DisplayModePtr
) mode
);
278 VidModeZoomViewport(int scrnIndex
, int zoom
)
282 if (!VidModeAvailable(scrnIndex
))
285 pScrn
= xf86Screens
[scrnIndex
];
286 xf86ZoomViewport(pScrn
->pScreen
, zoom
);
291 VidModeSetViewPort(int scrnIndex
, int x
, int y
)
295 if (!VidModeAvailable(scrnIndex
))
298 pScrn
= xf86Screens
[scrnIndex
];
299 pScrn
->frameX0
= min(max(x
, 0),
300 pScrn
->virtualX
- pScrn
->currentMode
->HDisplay
);
301 pScrn
->frameX1
= pScrn
->frameX0
+ pScrn
->currentMode
->HDisplay
- 1;
302 pScrn
->frameY0
= min(max(y
, 0),
303 pScrn
->virtualY
- pScrn
->currentMode
->VDisplay
);
304 pScrn
->frameY1
= pScrn
->frameY0
+ pScrn
->currentMode
->VDisplay
- 1;
305 if (pScrn
->AdjustFrame
!= NULL
)
306 (pScrn
->AdjustFrame
) (pScrn
, pScrn
->frameX0
, pScrn
->frameY0
);
312 VidModeGetViewPort(int scrnIndex
, int *x
, int *y
)
316 if (!VidModeAvailable(scrnIndex
))
319 pScrn
= xf86Screens
[scrnIndex
];
326 VidModeSwitchMode(int scrnIndex
, pointer mode
)
329 DisplayModePtr pTmpMode
;
332 if (!VidModeAvailable(scrnIndex
))
335 pScrn
= xf86Screens
[scrnIndex
];
336 /* save in case we fail */
337 pTmpMode
= pScrn
->currentMode
;
338 /* Force a mode switch */
339 pScrn
->currentMode
= NULL
;
340 retval
= xf86SwitchMode(pScrn
->pScreen
, mode
);
341 /* we failed: restore it */
343 pScrn
->currentMode
= pTmpMode
;
348 VidModeLockZoom(int scrnIndex
, Bool lock
)
352 if (!VidModeAvailable(scrnIndex
))
355 pScrn
= xf86Screens
[scrnIndex
];
357 if (xf86Info
.dontZoom
)
360 xf86LockZoom(pScrn
->pScreen
, lock
);
365 VidModeGetMonitor(int scrnIndex
, pointer
*monitor
)
369 if (!VidModeAvailable(scrnIndex
))
372 pScrn
= xf86Screens
[scrnIndex
];
373 *monitor
= (pointer
) (pScrn
->monitor
);
379 VidModeCheckModeForMonitor(int scrnIndex
, pointer mode
)
383 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
386 pScrn
= xf86Screens
[scrnIndex
];
388 return xf86CheckModeForMonitor((DisplayModePtr
) mode
, pScrn
->monitor
);
392 VidModeCheckModeForDriver(int scrnIndex
, pointer mode
)
396 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
399 pScrn
= xf86Screens
[scrnIndex
];
401 return xf86CheckModeForDriver(pScrn
, (DisplayModePtr
) mode
, 0);
405 VidModeSetCrtcForMode(int scrnIndex
, pointer mode
)
408 DisplayModePtr ScreenModes
;
410 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
413 /* Ugly hack so that the xf86Mode.c function can be used without change */
414 pScrn
= xf86Screens
[scrnIndex
];
415 ScreenModes
= pScrn
->modes
;
416 pScrn
->modes
= (DisplayModePtr
) mode
;
418 xf86SetCrtcForModes(pScrn
, pScrn
->adjustFlags
);
419 pScrn
->modes
= ScreenModes
;
424 VidModeAddModeline(int scrnIndex
, pointer mode
)
428 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
431 pScrn
= xf86Screens
[scrnIndex
];
433 ((DisplayModePtr
) mode
)->name
= strdup(""); /* freed by deletemode */
434 ((DisplayModePtr
) mode
)->status
= MODE_OK
;
435 ((DisplayModePtr
) mode
)->next
= pScrn
->modes
->next
;
436 ((DisplayModePtr
) mode
)->prev
= pScrn
->modes
;
437 pScrn
->modes
->next
= (DisplayModePtr
) mode
;
438 if (((DisplayModePtr
) mode
)->next
!= NULL
)
439 ((DisplayModePtr
) mode
)->next
->prev
= (DisplayModePtr
) mode
;
445 VidModeGetNumOfModes(int scrnIndex
)
448 int dotClock
= 0, nummodes
= 0;
450 if (!VidModeGetFirstModeline(scrnIndex
, &mode
, &dotClock
))
455 if (!VidModeGetNextModeline(scrnIndex
, &mode
, &dotClock
))
461 VidModeSetGamma(int scrnIndex
, float red
, float green
, float blue
)
466 if (!VidModeAvailable(scrnIndex
))
469 pScrn
= xf86Screens
[scrnIndex
];
473 if (xf86ChangeGamma(pScrn
->pScreen
, gamma
) != Success
)
480 VidModeGetGamma(int scrnIndex
, float *red
, float *green
, float *blue
)
484 if (!VidModeAvailable(scrnIndex
))
487 pScrn
= xf86Screens
[scrnIndex
];
488 *red
= pScrn
->gamma
.red
;
489 *green
= pScrn
->gamma
.green
;
490 *blue
= pScrn
->gamma
.blue
;
495 VidModeSetGammaRamp(int scrnIndex
, int size
, CARD16
*r
, CARD16
*g
, CARD16
*b
)
499 if (!VidModeAvailable(scrnIndex
))
502 pScrn
= xf86Screens
[scrnIndex
];
503 xf86ChangeGammaRamp(pScrn
->pScreen
, size
, r
, g
, b
);
508 VidModeGetGammaRamp(int scrnIndex
, int size
, CARD16
*r
, CARD16
*g
, CARD16
*b
)
512 if (!VidModeAvailable(scrnIndex
))
515 pScrn
= xf86Screens
[scrnIndex
];
516 xf86GetGammaRamp(pScrn
->pScreen
, size
, r
, g
, b
);
521 VidModeGetGammaRampSize(int scrnIndex
)
523 if (!VidModeAvailable(scrnIndex
))
526 return xf86GetGammaRampSize(xf86Screens
[scrnIndex
]->pScreen
);
530 VidModeCreateMode(void)
534 mode
= malloc(sizeof(DisplayModeRec
));
537 mode
->VScan
= 1; /* divides refresh rate. default = 1 */
538 mode
->Private
= NULL
;
546 VidModeCopyMode(pointer modefrom
, pointer modeto
)
548 memcpy(modeto
, modefrom
, sizeof(DisplayModeRec
));
552 VidModeGetModeValue(pointer mode
, int valtyp
)
557 case VIDMODE_H_DISPLAY
:
558 ret
= ((DisplayModePtr
) mode
)->HDisplay
;
560 case VIDMODE_H_SYNCSTART
:
561 ret
= ((DisplayModePtr
) mode
)->HSyncStart
;
563 case VIDMODE_H_SYNCEND
:
564 ret
= ((DisplayModePtr
) mode
)->HSyncEnd
;
566 case VIDMODE_H_TOTAL
:
567 ret
= ((DisplayModePtr
) mode
)->HTotal
;
570 ret
= ((DisplayModePtr
) mode
)->HSkew
;
572 case VIDMODE_V_DISPLAY
:
573 ret
= ((DisplayModePtr
) mode
)->VDisplay
;
575 case VIDMODE_V_SYNCSTART
:
576 ret
= ((DisplayModePtr
) mode
)->VSyncStart
;
578 case VIDMODE_V_SYNCEND
:
579 ret
= ((DisplayModePtr
) mode
)->VSyncEnd
;
581 case VIDMODE_V_TOTAL
:
582 ret
= ((DisplayModePtr
) mode
)->VTotal
;
585 ret
= ((DisplayModePtr
) mode
)->Flags
;
588 ret
= ((DisplayModePtr
) mode
)->Clock
;
595 VidModeSetModeValue(pointer mode
, int valtyp
, int val
)
598 case VIDMODE_H_DISPLAY
:
599 ((DisplayModePtr
) mode
)->HDisplay
= val
;
601 case VIDMODE_H_SYNCSTART
:
602 ((DisplayModePtr
) mode
)->HSyncStart
= val
;
604 case VIDMODE_H_SYNCEND
:
605 ((DisplayModePtr
) mode
)->HSyncEnd
= val
;
607 case VIDMODE_H_TOTAL
:
608 ((DisplayModePtr
) mode
)->HTotal
= val
;
611 ((DisplayModePtr
) mode
)->HSkew
= val
;
613 case VIDMODE_V_DISPLAY
:
614 ((DisplayModePtr
) mode
)->VDisplay
= val
;
616 case VIDMODE_V_SYNCSTART
:
617 ((DisplayModePtr
) mode
)->VSyncStart
= val
;
619 case VIDMODE_V_SYNCEND
:
620 ((DisplayModePtr
) mode
)->VSyncEnd
= val
;
622 case VIDMODE_V_TOTAL
:
623 ((DisplayModePtr
) mode
)->VTotal
= val
;
626 ((DisplayModePtr
) mode
)->Flags
= val
;
629 ((DisplayModePtr
) mode
)->Clock
= val
;
636 VidModeGetMonitorValue(pointer monitor
, int valtyp
, int indx
)
638 vidMonitorValue ret
= { NULL
, };
641 case VIDMODE_MON_VENDOR
:
642 ret
.ptr
= (((MonPtr
) monitor
)->vendor
);
644 case VIDMODE_MON_MODEL
:
645 ret
.ptr
= (((MonPtr
) monitor
)->model
);
647 case VIDMODE_MON_NHSYNC
:
648 ret
.i
= ((MonPtr
) monitor
)->nHsync
;
650 case VIDMODE_MON_NVREFRESH
:
651 ret
.i
= ((MonPtr
) monitor
)->nVrefresh
;
653 case VIDMODE_MON_HSYNC_LO
:
654 ret
.f
= (100.0 * ((MonPtr
) monitor
)->hsync
[indx
].lo
);
656 case VIDMODE_MON_HSYNC_HI
:
657 ret
.f
= (100.0 * ((MonPtr
) monitor
)->hsync
[indx
].hi
);
659 case VIDMODE_MON_VREFRESH_LO
:
660 ret
.f
= (100.0 * ((MonPtr
) monitor
)->vrefresh
[indx
].lo
);
662 case VIDMODE_MON_VREFRESH_HI
:
663 ret
.f
= (100.0 * ((MonPtr
) monitor
)->vrefresh
[indx
].hi
);
669 #endif /* XF86VIDMODE */