1
/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86VidMode.c,v 1.17 2003/08/24 17:36:55 dawes Exp $ */
3
* Copyright (c) 1999-2003 by The XFree86 Project, Inc.
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
12
* The above copyright notice and this permission notice shall be included in
13
* all copies or substantial portions of the Software.
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
* OTHER DEALINGS IN THE SOFTWARE.
23
* Except as contained in this notice, the name of the copyright holder(s)
24
* and author(s) shall not be used in advertising or otherwise to promote
25
* the sale, use or other dealings in this Software without prior written
26
* authorization from the copyright holder(s) and author(s).
30
* This file contains the VidMode functions required by the extension.
31
* These have been added to avoid the need for the higher level extension
32
* code to access the private XFree86 data structures directly. Wherever
33
* possible this code uses the functions in xf86Mode.c to do the work,
34
* so that two version of code that do similar things don't have to be
38
#ifdef HAVE_XORG_CONFIG_H
39
#include <xorg-config.h>
48
#include "vidmodeproc.h"
51
static int VidModeGeneration = 0;
52
static int VidModeIndex = -1;
53
static int VidModeCount = 0;
54
static Bool VidModeClose(int i, ScreenPtr pScreen);
56
#define VMPTR(p) ((VidModePtr)(p)->devPrivates[VidModeIndex].ptr)
61
# define DEBUG_P(x) ErrorF(x"\n");
63
# define DEBUG_P(x) /**/
67
VidModeExtensionInit(ScreenPtr pScreen)
72
DEBUG_P("VidModeExtensionInit");
74
if (!xf86GetVidModeEnabled()) {
75
DEBUG_P("!xf86GetVidModeEnabled()");
79
if (serverGeneration != VidModeGeneration) {
80
if ((VidModeIndex = AllocateScreenPrivateIndex()) < 0) {
81
DEBUG_P("AllocateScreenPrivateIndex() failed");
84
VidModeGeneration = serverGeneration;
87
if (!(pScreen->devPrivates[VidModeIndex].ptr = xcalloc(sizeof(VidModeRec), 1))) {
88
DEBUG_P("xcalloc failed");
92
pVidMode = VMPTR(pScreen);
94
pVidMode->Next = NULL;
95
pVidMode->CloseScreen = pScreen->CloseScreen;
96
pScreen->CloseScreen = VidModeClose;
100
DEBUG_P("no vidmode extension");
109
VidModeClose(int i, ScreenPtr pScreen)
111
VidModePtr pVidMode = VMPTR(pScreen);
113
DEBUG_P("VidModeClose");
115
/* This shouldn't happen */
119
pScreen->CloseScreen = pVidMode->CloseScreen;
121
if (--VidModeCount == 0) {
122
if (pScreen->devPrivates[VidModeIndex].ptr)
123
xfree(pScreen->devPrivates[VidModeIndex].ptr);
124
pScreen->devPrivates[VidModeIndex].ptr = NULL;
127
return pScreen->CloseScreen(i, pScreen);
131
VidModeAvailable(int scrnIndex)
136
DEBUG_P("VidModeAvailable");
138
if (VidModeIndex < 0) {
139
DEBUG_P("VidModeIndex < 0");
143
pScrn = xf86Screens[scrnIndex];
145
DEBUG_P("pScrn == NULL");
149
pVidMode = VMPTR(pScrn->pScreen);
153
DEBUG_P("pVidMode == NULL");
159
VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock)
163
DEBUG_P("VidModeGetCurrentModeline");
165
if (!VidModeAvailable(scrnIndex))
168
pScrn = xf86Screens[scrnIndex];
169
*mode = (pointer)(pScrn->currentMode);
170
*dotClock = pScrn->currentMode->Clock;
176
VidModeGetDotClock(int scrnIndex, int Clock)
180
DEBUG_P("VidModeGetDotClock");
182
if (!VidModeAvailable(scrnIndex))
185
pScrn = xf86Screens[scrnIndex];
186
if ((pScrn->progClock) || (Clock > MAXCLOCKS))
189
return pScrn->clock[Clock];
193
VidModeGetNumOfClocks(int scrnIndex, Bool *progClock)
197
DEBUG_P("VidModeGetNumOfClocks");
199
if (!VidModeAvailable(scrnIndex))
202
pScrn = xf86Screens[scrnIndex];
203
if (pScrn->progClock){
208
return pScrn->numClocks;
213
VidModeGetClocks(int scrnIndex, int *Clocks)
218
DEBUG_P("VidModeGetClocks");
220
if (!VidModeAvailable(scrnIndex))
223
pScrn = xf86Screens[scrnIndex];
225
if (pScrn->progClock)
228
for (i = 0; i < pScrn->numClocks; i++)
229
*Clocks++ = pScrn->clock[i];
236
VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
241
DEBUG_P("VidModeGetFirstModeline");
243
if (!VidModeAvailable(scrnIndex))
246
pScrn = xf86Screens[scrnIndex];
247
pVidMode = VMPTR(pScrn->pScreen);
248
pVidMode->First = pScrn->modes;
249
pVidMode->Next = pVidMode->First->next;
251
if (pVidMode->First->status == MODE_OK) {
252
*mode = (pointer)(pVidMode->First);
253
*dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock);
257
return VidModeGetNextModeline(scrnIndex, mode, dotClock);
261
VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
267
DEBUG_P("VidModeGetNextModeline");
269
if (!VidModeAvailable(scrnIndex))
272
pScrn = xf86Screens[scrnIndex];
273
pVidMode = VMPTR(pScrn->pScreen);
275
for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
276
if (p->status == MODE_OK) {
277
pVidMode->Next = p->next;
279
*dotClock = VidModeGetDotClock(scrnIndex, p->Clock);
288
VidModeDeleteModeline(int scrnIndex, pointer mode)
292
DEBUG_P("VidModeDeleteModeline");
294
if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
297
pScrn = xf86Screens[scrnIndex];
298
xf86DeleteMode(&(pScrn->modes), (DisplayModePtr)mode);
303
VidModeZoomViewport(int scrnIndex, int zoom)
307
DEBUG_P("VidModeZoomViewPort");
309
if (!VidModeAvailable(scrnIndex))
312
pScrn = xf86Screens[scrnIndex];
313
xf86ZoomViewport(pScrn->pScreen, zoom);
318
VidModeSetViewPort(int scrnIndex, int x, int y)
322
DEBUG_P("VidModeSetViewPort");
324
if (!VidModeAvailable(scrnIndex))
327
pScrn = xf86Screens[scrnIndex];
328
pScrn->frameX0 = min( max(x, 0),
329
pScrn->virtualX - pScrn->currentMode->HDisplay );
330
pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
331
pScrn->frameY0 = min( max(y, 0),
332
pScrn->virtualY - pScrn->currentMode->VDisplay );
333
pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1;
334
if (pScrn->AdjustFrame != NULL)
335
(pScrn->AdjustFrame)(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
341
VidModeGetViewPort(int scrnIndex, int *x, int *y)
345
DEBUG_P("VidModeGetViewPort");
347
if (!VidModeAvailable(scrnIndex))
350
pScrn = xf86Screens[scrnIndex];
357
VidModeSwitchMode(int scrnIndex, pointer mode)
360
DisplayModePtr pTmpMode;
363
DEBUG_P("VidModeSwitchMode");
365
if (!VidModeAvailable(scrnIndex))
368
pScrn = xf86Screens[scrnIndex];
369
/* save in case we fail */
370
pTmpMode = pScrn->currentMode;
371
/* Force a mode switch */
372
pScrn->currentMode = NULL;
373
retval = xf86SwitchMode(pScrn->pScreen, mode);
374
/* we failed: restore it */
376
pScrn->currentMode = pTmpMode;
381
VidModeLockZoom(int scrnIndex, Bool lock)
385
DEBUG_P("VidModeLockZoom");
387
if (!VidModeAvailable(scrnIndex))
390
pScrn = xf86Screens[scrnIndex];
392
if (xf86Info.dontZoom)
395
xf86LockZoom(pScrn->pScreen, lock);
400
VidModeGetMonitor(int scrnIndex, pointer *monitor)
404
DEBUG_P("VidModeGetMonitor");
406
if (!VidModeAvailable(scrnIndex))
409
pScrn = xf86Screens[scrnIndex];
410
*monitor = (pointer)(pScrn->monitor);
416
VidModeCheckModeForMonitor(int scrnIndex, pointer mode)
420
DEBUG_P("VidModeCheckModeForMonitor");
422
if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
425
pScrn = xf86Screens[scrnIndex];
427
return xf86CheckModeForMonitor((DisplayModePtr)mode, pScrn->monitor);
431
VidModeCheckModeForDriver(int scrnIndex, pointer mode)
435
DEBUG_P("VidModeCheckModeForDriver");
437
if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
440
pScrn = xf86Screens[scrnIndex];
442
return xf86CheckModeForDriver(pScrn, (DisplayModePtr)mode, 0);
446
VidModeSetCrtcForMode(int scrnIndex, pointer mode)
449
DisplayModePtr ScreenModes;
451
DEBUG_P("VidModeSetCrtcForMode");
453
if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
456
/* Ugly hack so that the xf86Mode.c function can be used without change */
457
pScrn = xf86Screens[scrnIndex];
458
ScreenModes = pScrn->modes;
459
pScrn->modes = (DisplayModePtr)mode;
461
xf86SetCrtcForModes(pScrn, pScrn->adjustFlags);
462
pScrn->modes = ScreenModes;
467
VidModeAddModeline(int scrnIndex, pointer mode)
471
DEBUG_P("VidModeAddModeline");
473
if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
476
pScrn = xf86Screens[scrnIndex];
478
((DisplayModePtr)mode)->name = strdup(""); /* freed by deletemode */
479
((DisplayModePtr)mode)->status = MODE_OK;
480
((DisplayModePtr)mode)->next = pScrn->modes->next;
481
((DisplayModePtr)mode)->prev = pScrn->modes;
482
pScrn->modes->next = (DisplayModePtr)mode;
483
if( ((DisplayModePtr)mode)->next != NULL )
484
((DisplayModePtr)mode)->next->prev = (DisplayModePtr)mode;
490
VidModeGetNumOfModes(int scrnIndex)
493
int dotClock= 0, nummodes = 0;
495
DEBUG_P("VidModeGetNumOfModes");
497
if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock))
502
if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock))
508
VidModeSetGamma(int scrnIndex, float red, float green, float blue)
513
DEBUG_P("VidModeSetGamma");
515
if (!VidModeAvailable(scrnIndex))
518
pScrn = xf86Screens[scrnIndex];
522
if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success)
529
VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue)
533
DEBUG_P("VidModeGetGamma");
535
if (!VidModeAvailable(scrnIndex))
538
pScrn = xf86Screens[scrnIndex];
539
*red = pScrn->gamma.red;
540
*green = pScrn->gamma.green;
541
*blue = pScrn->gamma.blue;
546
VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
550
if (!VidModeAvailable(scrnIndex))
553
pScrn = xf86Screens[scrnIndex];
554
xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b);
559
VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
563
if (!VidModeAvailable(scrnIndex))
566
pScrn = xf86Screens[scrnIndex];
567
xf86GetGammaRamp(pScrn->pScreen, size, r, g, b);
572
VidModeGetGammaRampSize(int scrnIndex)
574
if (!VidModeAvailable(scrnIndex))
577
return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen);
581
VidModeCreateMode(void)
585
mode = xalloc(sizeof(DisplayModeRec));
588
mode->VScan = 1; /* divides refresh rate. default = 1 */
589
mode->Private = NULL;
597
VidModeCopyMode(pointer modefrom, pointer modeto)
599
memcpy(modeto, modefrom, sizeof(DisplayModeRec));
604
VidModeGetModeValue(pointer mode, int valtyp)
609
case VIDMODE_H_DISPLAY:
610
ret = ((DisplayModePtr) mode)->HDisplay;
612
case VIDMODE_H_SYNCSTART:
613
ret = ((DisplayModePtr)mode)->HSyncStart;
615
case VIDMODE_H_SYNCEND:
616
ret = ((DisplayModePtr)mode)->HSyncEnd;
618
case VIDMODE_H_TOTAL:
619
ret = ((DisplayModePtr)mode)->HTotal;
622
ret = ((DisplayModePtr)mode)->HSkew;
624
case VIDMODE_V_DISPLAY:
625
ret = ((DisplayModePtr)mode)->VDisplay;
627
case VIDMODE_V_SYNCSTART:
628
ret = ((DisplayModePtr)mode)->VSyncStart;
630
case VIDMODE_V_SYNCEND:
631
ret = ((DisplayModePtr)mode)->VSyncEnd;
633
case VIDMODE_V_TOTAL:
634
ret = ((DisplayModePtr)mode)->VTotal;
637
ret = ((DisplayModePtr)mode)->Flags;
640
ret = ((DisplayModePtr)mode)->Clock;
647
VidModeSetModeValue(pointer mode, int valtyp, int val)
650
case VIDMODE_H_DISPLAY:
651
((DisplayModePtr)mode)->HDisplay = val;
653
case VIDMODE_H_SYNCSTART:
654
((DisplayModePtr)mode)->HSyncStart = val;
656
case VIDMODE_H_SYNCEND:
657
((DisplayModePtr)mode)->HSyncEnd = val;
659
case VIDMODE_H_TOTAL:
660
((DisplayModePtr)mode)->HTotal = val;
663
((DisplayModePtr)mode)->HSkew = val;
665
case VIDMODE_V_DISPLAY:
666
((DisplayModePtr)mode)->VDisplay = val;
668
case VIDMODE_V_SYNCSTART:
669
((DisplayModePtr)mode)->VSyncStart = val;
671
case VIDMODE_V_SYNCEND:
672
((DisplayModePtr)mode)->VSyncEnd = val;
674
case VIDMODE_V_TOTAL:
675
((DisplayModePtr)mode)->VTotal = val;
678
((DisplayModePtr)mode)->Flags = val;
681
((DisplayModePtr)mode)->Clock = val;
688
VidModeGetMonitorValue(pointer monitor, int valtyp, int indx)
693
case VIDMODE_MON_VENDOR:
694
ret.ptr = (((MonPtr)monitor)->vendor);
696
case VIDMODE_MON_MODEL:
697
ret.ptr = (((MonPtr)monitor)->model);
699
case VIDMODE_MON_NHSYNC:
700
ret.i = ((MonPtr)monitor)->nHsync;
702
case VIDMODE_MON_NVREFRESH:
703
ret.i = ((MonPtr)monitor)->nVrefresh;
705
case VIDMODE_MON_HSYNC_LO:
706
ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].lo);
708
case VIDMODE_MON_HSYNC_HI:
709
ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].hi);
711
case VIDMODE_MON_VREFRESH_LO:
712
ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].lo);
714
case VIDMODE_MON_VREFRESH_HI:
715
ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].hi);
722
#endif /* XF86VIDMODE */