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 int VidModeGeneration
= 0;
51 static int VidModeIndex
= -1;
52 static int VidModeCount
= 0;
53 static Bool
VidModeClose(int i
, ScreenPtr pScreen
);
55 #define VMPTR(p) ((VidModePtr)(p)->devPrivates[VidModeIndex].ptr)
60 # define DEBUG_P(x) ErrorF(x"\n");
62 # define DEBUG_P(x) /**/
66 VidModeExtensionInit(ScreenPtr pScreen
)
71 DEBUG_P("VidModeExtensionInit");
73 if (!xf86GetVidModeEnabled()) {
74 DEBUG_P("!xf86GetVidModeEnabled()");
78 if (serverGeneration
!= VidModeGeneration
) {
79 if ((VidModeIndex
= AllocateScreenPrivateIndex()) < 0) {
80 DEBUG_P("AllocateScreenPrivateIndex() failed");
83 VidModeGeneration
= serverGeneration
;
86 if (!(pScreen
->devPrivates
[VidModeIndex
].ptr
= xcalloc(sizeof(VidModeRec
), 1))) {
87 DEBUG_P("xcalloc failed");
91 pVidMode
= VMPTR(pScreen
);
93 pVidMode
->Next
= NULL
;
94 pVidMode
->CloseScreen
= pScreen
->CloseScreen
;
95 pScreen
->CloseScreen
= VidModeClose
;
99 DEBUG_P("no vidmode extension");
108 VidModeClose(int i
, ScreenPtr pScreen
)
110 VidModePtr pVidMode
= VMPTR(pScreen
);
112 DEBUG_P("VidModeClose");
114 /* This shouldn't happen */
118 pScreen
->CloseScreen
= pVidMode
->CloseScreen
;
120 if (--VidModeCount
== 0) {
121 if (pScreen
->devPrivates
[VidModeIndex
].ptr
)
122 xfree(pScreen
->devPrivates
[VidModeIndex
].ptr
);
123 pScreen
->devPrivates
[VidModeIndex
].ptr
= NULL
;
126 return pScreen
->CloseScreen(i
, pScreen
);
130 VidModeAvailable(int scrnIndex
)
135 DEBUG_P("VidModeAvailable");
137 if (VidModeIndex
< 0) {
138 DEBUG_P("VidModeIndex < 0");
142 pScrn
= xf86Screens
[scrnIndex
];
144 DEBUG_P("pScrn == NULL");
148 pVidMode
= VMPTR(pScrn
->pScreen
);
152 DEBUG_P("pVidMode == NULL");
158 VidModeGetCurrentModeline(int scrnIndex
, pointer
*mode
, int *dotClock
)
162 DEBUG_P("VidModeGetCurrentModeline");
164 if (!VidModeAvailable(scrnIndex
))
167 pScrn
= xf86Screens
[scrnIndex
];
168 *mode
= (pointer
)(pScrn
->currentMode
);
169 *dotClock
= pScrn
->currentMode
->Clock
;
175 VidModeGetDotClock(int scrnIndex
, int Clock
)
179 DEBUG_P("VidModeGetDotClock");
181 if (!VidModeAvailable(scrnIndex
))
184 pScrn
= xf86Screens
[scrnIndex
];
185 if ((pScrn
->progClock
) || (Clock
>= MAXCLOCKS
))
188 return pScrn
->clock
[Clock
];
192 VidModeGetNumOfClocks(int scrnIndex
, Bool
*progClock
)
196 DEBUG_P("VidModeGetNumOfClocks");
198 if (!VidModeAvailable(scrnIndex
))
201 pScrn
= xf86Screens
[scrnIndex
];
202 if (pScrn
->progClock
){
207 return pScrn
->numClocks
;
212 VidModeGetClocks(int scrnIndex
, int *Clocks
)
217 DEBUG_P("VidModeGetClocks");
219 if (!VidModeAvailable(scrnIndex
))
222 pScrn
= xf86Screens
[scrnIndex
];
224 if (pScrn
->progClock
)
227 for (i
= 0; i
< pScrn
->numClocks
; i
++)
228 *Clocks
++ = pScrn
->clock
[i
];
235 VidModeGetFirstModeline(int scrnIndex
, pointer
*mode
, int *dotClock
)
240 DEBUG_P("VidModeGetFirstModeline");
242 if (!VidModeAvailable(scrnIndex
))
245 pScrn
= xf86Screens
[scrnIndex
];
246 pVidMode
= VMPTR(pScrn
->pScreen
);
247 pVidMode
->First
= pScrn
->modes
;
248 pVidMode
->Next
= pVidMode
->First
->next
;
250 if (pVidMode
->First
->status
== MODE_OK
) {
251 *mode
= (pointer
)(pVidMode
->First
);
252 *dotClock
= VidModeGetDotClock(scrnIndex
, pVidMode
->First
->Clock
);
256 return VidModeGetNextModeline(scrnIndex
, mode
, dotClock
);
260 VidModeGetNextModeline(int scrnIndex
, pointer
*mode
, int *dotClock
)
266 DEBUG_P("VidModeGetNextModeline");
268 if (!VidModeAvailable(scrnIndex
))
271 pScrn
= xf86Screens
[scrnIndex
];
272 pVidMode
= VMPTR(pScrn
->pScreen
);
274 for (p
= pVidMode
->Next
; p
!= NULL
&& p
!= pVidMode
->First
; p
= p
->next
) {
275 if (p
->status
== MODE_OK
) {
276 pVidMode
->Next
= p
->next
;
278 *dotClock
= VidModeGetDotClock(scrnIndex
, p
->Clock
);
287 VidModeDeleteModeline(int scrnIndex
, pointer mode
)
291 DEBUG_P("VidModeDeleteModeline");
293 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
296 pScrn
= xf86Screens
[scrnIndex
];
297 xf86DeleteMode(&(pScrn
->modes
), (DisplayModePtr
)mode
);
302 VidModeZoomViewport(int scrnIndex
, int zoom
)
306 DEBUG_P("VidModeZoomViewPort");
308 if (!VidModeAvailable(scrnIndex
))
311 pScrn
= xf86Screens
[scrnIndex
];
312 xf86ZoomViewport(pScrn
->pScreen
, zoom
);
317 VidModeSetViewPort(int scrnIndex
, int x
, int y
)
321 DEBUG_P("VidModeSetViewPort");
323 if (!VidModeAvailable(scrnIndex
))
326 pScrn
= xf86Screens
[scrnIndex
];
327 pScrn
->frameX0
= min( max(x
, 0),
328 pScrn
->virtualX
- pScrn
->currentMode
->HDisplay
);
329 pScrn
->frameX1
= pScrn
->frameX0
+ pScrn
->currentMode
->HDisplay
- 1;
330 pScrn
->frameY0
= min( max(y
, 0),
331 pScrn
->virtualY
- pScrn
->currentMode
->VDisplay
);
332 pScrn
->frameY1
= pScrn
->frameY0
+ pScrn
->currentMode
->VDisplay
- 1;
333 if (pScrn
->AdjustFrame
!= NULL
)
334 (pScrn
->AdjustFrame
)(scrnIndex
, pScrn
->frameX0
, pScrn
->frameY0
, 0);
340 VidModeGetViewPort(int scrnIndex
, int *x
, int *y
)
344 DEBUG_P("VidModeGetViewPort");
346 if (!VidModeAvailable(scrnIndex
))
349 pScrn
= xf86Screens
[scrnIndex
];
356 VidModeSwitchMode(int scrnIndex
, pointer mode
)
359 DisplayModePtr pTmpMode
;
362 DEBUG_P("VidModeSwitchMode");
364 if (!VidModeAvailable(scrnIndex
))
367 pScrn
= xf86Screens
[scrnIndex
];
368 /* save in case we fail */
369 pTmpMode
= pScrn
->currentMode
;
370 /* Force a mode switch */
371 pScrn
->currentMode
= NULL
;
372 retval
= xf86SwitchMode(pScrn
->pScreen
, mode
);
373 /* we failed: restore it */
375 pScrn
->currentMode
= pTmpMode
;
380 VidModeLockZoom(int scrnIndex
, Bool lock
)
384 DEBUG_P("VidModeLockZoom");
386 if (!VidModeAvailable(scrnIndex
))
389 pScrn
= xf86Screens
[scrnIndex
];
391 if (xf86Info
.dontZoom
)
394 xf86LockZoom(pScrn
->pScreen
, lock
);
399 VidModeGetMonitor(int scrnIndex
, pointer
*monitor
)
403 DEBUG_P("VidModeGetMonitor");
405 if (!VidModeAvailable(scrnIndex
))
408 pScrn
= xf86Screens
[scrnIndex
];
409 *monitor
= (pointer
)(pScrn
->monitor
);
415 VidModeCheckModeForMonitor(int scrnIndex
, pointer mode
)
419 DEBUG_P("VidModeCheckModeForMonitor");
421 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
424 pScrn
= xf86Screens
[scrnIndex
];
426 return xf86CheckModeForMonitor((DisplayModePtr
)mode
, pScrn
->monitor
);
430 VidModeCheckModeForDriver(int scrnIndex
, pointer mode
)
434 DEBUG_P("VidModeCheckModeForDriver");
436 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
439 pScrn
= xf86Screens
[scrnIndex
];
441 return xf86CheckModeForDriver(pScrn
, (DisplayModePtr
)mode
, 0);
445 VidModeSetCrtcForMode(int scrnIndex
, pointer mode
)
448 DisplayModePtr ScreenModes
;
450 DEBUG_P("VidModeSetCrtcForMode");
452 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
455 /* Ugly hack so that the xf86Mode.c function can be used without change */
456 pScrn
= xf86Screens
[scrnIndex
];
457 ScreenModes
= pScrn
->modes
;
458 pScrn
->modes
= (DisplayModePtr
)mode
;
460 xf86SetCrtcForModes(pScrn
, pScrn
->adjustFlags
);
461 pScrn
->modes
= ScreenModes
;
466 VidModeAddModeline(int scrnIndex
, pointer mode
)
470 DEBUG_P("VidModeAddModeline");
472 if ((mode
== NULL
) || (!VidModeAvailable(scrnIndex
)))
475 pScrn
= xf86Screens
[scrnIndex
];
477 ((DisplayModePtr
)mode
)->name
= strdup(""); /* freed by deletemode */
478 ((DisplayModePtr
)mode
)->status
= MODE_OK
;
479 ((DisplayModePtr
)mode
)->next
= pScrn
->modes
->next
;
480 ((DisplayModePtr
)mode
)->prev
= pScrn
->modes
;
481 pScrn
->modes
->next
= (DisplayModePtr
)mode
;
482 if( ((DisplayModePtr
)mode
)->next
!= NULL
)
483 ((DisplayModePtr
)mode
)->next
->prev
= (DisplayModePtr
)mode
;
489 VidModeGetNumOfModes(int scrnIndex
)
492 int dotClock
= 0, nummodes
= 0;
494 DEBUG_P("VidModeGetNumOfModes");
496 if (!VidModeGetFirstModeline(scrnIndex
, &mode
, &dotClock
))
501 if (!VidModeGetNextModeline(scrnIndex
, &mode
, &dotClock
))
507 VidModeSetGamma(int scrnIndex
, float red
, float green
, float blue
)
512 DEBUG_P("VidModeSetGamma");
514 if (!VidModeAvailable(scrnIndex
))
517 pScrn
= xf86Screens
[scrnIndex
];
521 if (xf86ChangeGamma(pScrn
->pScreen
, gamma
) != Success
)
528 VidModeGetGamma(int scrnIndex
, float *red
, float *green
, float *blue
)
532 DEBUG_P("VidModeGetGamma");
534 if (!VidModeAvailable(scrnIndex
))
537 pScrn
= xf86Screens
[scrnIndex
];
538 *red
= pScrn
->gamma
.red
;
539 *green
= pScrn
->gamma
.green
;
540 *blue
= pScrn
->gamma
.blue
;
545 VidModeSetGammaRamp(int scrnIndex
, int size
, CARD16
*r
, CARD16
*g
, CARD16
*b
)
549 if (!VidModeAvailable(scrnIndex
))
552 pScrn
= xf86Screens
[scrnIndex
];
553 xf86ChangeGammaRamp(pScrn
->pScreen
, size
, r
, g
, b
);
558 VidModeGetGammaRamp(int scrnIndex
, int size
, CARD16
*r
, CARD16
*g
, CARD16
*b
)
562 if (!VidModeAvailable(scrnIndex
))
565 pScrn
= xf86Screens
[scrnIndex
];
566 xf86GetGammaRamp(pScrn
->pScreen
, size
, r
, g
, b
);
571 VidModeGetGammaRampSize(int scrnIndex
)
573 if (!VidModeAvailable(scrnIndex
))
576 return xf86GetGammaRampSize(xf86Screens
[scrnIndex
]->pScreen
);
580 VidModeCreateMode(void)
584 mode
= xalloc(sizeof(DisplayModeRec
));
587 mode
->VScan
= 1; /* divides refresh rate. default = 1 */
588 mode
->Private
= NULL
;
596 VidModeCopyMode(pointer modefrom
, pointer modeto
)
598 memcpy(modeto
, modefrom
, sizeof(DisplayModeRec
));
603 VidModeGetModeValue(pointer mode
, int valtyp
)
608 case VIDMODE_H_DISPLAY
:
609 ret
= ((DisplayModePtr
) mode
)->HDisplay
;
611 case VIDMODE_H_SYNCSTART
:
612 ret
= ((DisplayModePtr
)mode
)->HSyncStart
;
614 case VIDMODE_H_SYNCEND
:
615 ret
= ((DisplayModePtr
)mode
)->HSyncEnd
;
617 case VIDMODE_H_TOTAL
:
618 ret
= ((DisplayModePtr
)mode
)->HTotal
;
621 ret
= ((DisplayModePtr
)mode
)->HSkew
;
623 case VIDMODE_V_DISPLAY
:
624 ret
= ((DisplayModePtr
)mode
)->VDisplay
;
626 case VIDMODE_V_SYNCSTART
:
627 ret
= ((DisplayModePtr
)mode
)->VSyncStart
;
629 case VIDMODE_V_SYNCEND
:
630 ret
= ((DisplayModePtr
)mode
)->VSyncEnd
;
632 case VIDMODE_V_TOTAL
:
633 ret
= ((DisplayModePtr
)mode
)->VTotal
;
636 ret
= ((DisplayModePtr
)mode
)->Flags
;
639 ret
= ((DisplayModePtr
)mode
)->Clock
;
646 VidModeSetModeValue(pointer mode
, int valtyp
, int val
)
649 case VIDMODE_H_DISPLAY
:
650 ((DisplayModePtr
)mode
)->HDisplay
= val
;
652 case VIDMODE_H_SYNCSTART
:
653 ((DisplayModePtr
)mode
)->HSyncStart
= val
;
655 case VIDMODE_H_SYNCEND
:
656 ((DisplayModePtr
)mode
)->HSyncEnd
= val
;
658 case VIDMODE_H_TOTAL
:
659 ((DisplayModePtr
)mode
)->HTotal
= val
;
662 ((DisplayModePtr
)mode
)->HSkew
= val
;
664 case VIDMODE_V_DISPLAY
:
665 ((DisplayModePtr
)mode
)->VDisplay
= val
;
667 case VIDMODE_V_SYNCSTART
:
668 ((DisplayModePtr
)mode
)->VSyncStart
= val
;
670 case VIDMODE_V_SYNCEND
:
671 ((DisplayModePtr
)mode
)->VSyncEnd
= val
;
673 case VIDMODE_V_TOTAL
:
674 ((DisplayModePtr
)mode
)->VTotal
= val
;
677 ((DisplayModePtr
)mode
)->Flags
= val
;
680 ((DisplayModePtr
)mode
)->Clock
= val
;
686 _X_EXPORT vidMonitorValue
687 VidModeGetMonitorValue(pointer monitor
, int valtyp
, int indx
)
692 case VIDMODE_MON_VENDOR
:
693 ret
.ptr
= (((MonPtr
)monitor
)->vendor
);
695 case VIDMODE_MON_MODEL
:
696 ret
.ptr
= (((MonPtr
)monitor
)->model
);
698 case VIDMODE_MON_NHSYNC
:
699 ret
.i
= ((MonPtr
)monitor
)->nHsync
;
701 case VIDMODE_MON_NVREFRESH
:
702 ret
.i
= ((MonPtr
)monitor
)->nVrefresh
;
704 case VIDMODE_MON_HSYNC_LO
:
705 ret
.f
= (100.0 * ((MonPtr
)monitor
)->hsync
[indx
].lo
);
707 case VIDMODE_MON_HSYNC_HI
:
708 ret
.f
= (100.0 * ((MonPtr
)monitor
)->hsync
[indx
].hi
);
710 case VIDMODE_MON_VREFRESH_LO
:
711 ret
.f
= (100.0 * ((MonPtr
)monitor
)->vrefresh
[indx
].lo
);
713 case VIDMODE_MON_VREFRESH_HI
:
714 ret
.f
= (100.0 * ((MonPtr
)monitor
)->vrefresh
[indx
].hi
);
721 #endif /* XF86VIDMODE */