First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / common / xf86VidMode.c
blobfb9151346afa3dd53cfa6f83605e366daaed4bf2
1 /*
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
34 * maintained.
37 #ifdef HAVE_XORG_CONFIG_H
38 #include <xorg-config.h>
39 #endif
41 #include <X11/X.h>
42 #include "os.h"
43 #include "xf86.h"
44 #include "xf86Priv.h"
46 #ifdef XF86VIDMODE
47 #include "vidmodeproc.h"
48 #include "xf86cmap.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)
57 #endif
59 #ifdef DEBUG
60 # define DEBUG_P(x) ErrorF(x"\n");
61 #else
62 # define DEBUG_P(x) /**/
63 #endif
65 _X_EXPORT Bool
66 VidModeExtensionInit(ScreenPtr pScreen)
68 #ifdef XF86VIDMODE
69 VidModePtr pVidMode;
71 DEBUG_P("VidModeExtensionInit");
73 if (!xf86GetVidModeEnabled()) {
74 DEBUG_P("!xf86GetVidModeEnabled()");
75 return FALSE;
78 if (serverGeneration != VidModeGeneration) {
79 if ((VidModeIndex = AllocateScreenPrivateIndex()) < 0) {
80 DEBUG_P("AllocateScreenPrivateIndex() failed");
81 return FALSE;
83 VidModeGeneration = serverGeneration;
86 if (!(pScreen->devPrivates[VidModeIndex].ptr = xcalloc(sizeof(VidModeRec), 1))) {
87 DEBUG_P("xcalloc failed");
88 return FALSE;
91 pVidMode = VMPTR(pScreen);
92 pVidMode->Flags = 0;
93 pVidMode->Next = NULL;
94 pVidMode->CloseScreen = pScreen->CloseScreen;
95 pScreen->CloseScreen = VidModeClose;
96 VidModeCount++;
97 return TRUE;
98 #else
99 DEBUG_P("no vidmode extension");
100 return FALSE;
101 #endif
105 #ifdef XF86VIDMODE
107 static Bool
108 VidModeClose(int i, ScreenPtr pScreen)
110 VidModePtr pVidMode = VMPTR(pScreen);
112 DEBUG_P("VidModeClose");
114 /* This shouldn't happen */
115 if (!pVidMode)
116 return FALSE;
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;
124 VidModeIndex = -1;
126 return pScreen->CloseScreen(i, pScreen);
129 Bool
130 VidModeAvailable(int scrnIndex)
132 ScrnInfoPtr pScrn;
133 VidModePtr pVidMode;
135 DEBUG_P("VidModeAvailable");
137 if (VidModeIndex < 0) {
138 DEBUG_P("VidModeIndex < 0");
139 return FALSE;
142 pScrn = xf86Screens[scrnIndex];
143 if (pScrn == NULL) {
144 DEBUG_P("pScrn == NULL");
145 return FALSE;
148 pVidMode = VMPTR(pScrn->pScreen);
149 if (pVidMode)
150 return TRUE;
151 else {
152 DEBUG_P("pVidMode == NULL");
153 return FALSE;
157 _X_EXPORT Bool
158 VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock)
160 ScrnInfoPtr pScrn;
162 DEBUG_P("VidModeGetCurrentModeline");
164 if (!VidModeAvailable(scrnIndex))
165 return FALSE;
167 pScrn = xf86Screens[scrnIndex];
168 *mode = (pointer)(pScrn->currentMode);
169 *dotClock = pScrn->currentMode->Clock;
171 return TRUE;
174 _X_EXPORT int
175 VidModeGetDotClock(int scrnIndex, int Clock)
177 ScrnInfoPtr pScrn;
179 DEBUG_P("VidModeGetDotClock");
181 if (!VidModeAvailable(scrnIndex))
182 return 0;
184 pScrn = xf86Screens[scrnIndex];
185 if ((pScrn->progClock) || (Clock >= MAXCLOCKS))
186 return Clock;
187 else
188 return pScrn->clock[Clock];
191 _X_EXPORT int
192 VidModeGetNumOfClocks(int scrnIndex, Bool *progClock)
194 ScrnInfoPtr pScrn;
196 DEBUG_P("VidModeGetNumOfClocks");
198 if (!VidModeAvailable(scrnIndex))
199 return 0;
201 pScrn = xf86Screens[scrnIndex];
202 if (pScrn->progClock){
203 *progClock = TRUE;
204 return 0;
205 } else {
206 *progClock = FALSE;
207 return pScrn->numClocks;
211 _X_EXPORT Bool
212 VidModeGetClocks(int scrnIndex, int *Clocks)
214 ScrnInfoPtr pScrn;
215 int i;
217 DEBUG_P("VidModeGetClocks");
219 if (!VidModeAvailable(scrnIndex))
220 return FALSE;
222 pScrn = xf86Screens[scrnIndex];
224 if (pScrn->progClock)
225 return FALSE;
227 for (i = 0; i < pScrn->numClocks; i++)
228 *Clocks++ = pScrn->clock[i];
230 return TRUE;
234 _X_EXPORT Bool
235 VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
237 ScrnInfoPtr pScrn;
238 VidModePtr pVidMode;
240 DEBUG_P("VidModeGetFirstModeline");
242 if (!VidModeAvailable(scrnIndex))
243 return FALSE;
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);
253 return TRUE;
256 return VidModeGetNextModeline(scrnIndex, mode, dotClock);
259 _X_EXPORT Bool
260 VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
262 ScrnInfoPtr pScrn;
263 VidModePtr pVidMode;
264 DisplayModePtr p;
266 DEBUG_P("VidModeGetNextModeline");
268 if (!VidModeAvailable(scrnIndex))
269 return FALSE;
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;
277 *mode = (pointer)p;
278 *dotClock = VidModeGetDotClock(scrnIndex, p->Clock);
279 return TRUE;
283 return FALSE;
286 _X_EXPORT Bool
287 VidModeDeleteModeline(int scrnIndex, pointer mode)
289 ScrnInfoPtr pScrn;
291 DEBUG_P("VidModeDeleteModeline");
293 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
294 return FALSE;
296 pScrn = xf86Screens[scrnIndex];
297 xf86DeleteMode(&(pScrn->modes), (DisplayModePtr)mode);
298 return TRUE;
301 _X_EXPORT Bool
302 VidModeZoomViewport(int scrnIndex, int zoom)
304 ScrnInfoPtr pScrn;
306 DEBUG_P("VidModeZoomViewPort");
308 if (!VidModeAvailable(scrnIndex))
309 return FALSE;
311 pScrn = xf86Screens[scrnIndex];
312 xf86ZoomViewport(pScrn->pScreen, zoom);
313 return TRUE;
316 _X_EXPORT Bool
317 VidModeSetViewPort(int scrnIndex, int x, int y)
319 ScrnInfoPtr pScrn;
321 DEBUG_P("VidModeSetViewPort");
323 if (!VidModeAvailable(scrnIndex))
324 return FALSE;
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);
336 return TRUE;
339 _X_EXPORT Bool
340 VidModeGetViewPort(int scrnIndex, int *x, int *y)
342 ScrnInfoPtr pScrn;
344 DEBUG_P("VidModeGetViewPort");
346 if (!VidModeAvailable(scrnIndex))
347 return FALSE;
349 pScrn = xf86Screens[scrnIndex];
350 *x = pScrn->frameX0;
351 *y = pScrn->frameY0;
352 return TRUE;
355 _X_EXPORT Bool
356 VidModeSwitchMode(int scrnIndex, pointer mode)
358 ScrnInfoPtr pScrn;
359 DisplayModePtr pTmpMode;
360 Bool retval;
362 DEBUG_P("VidModeSwitchMode");
364 if (!VidModeAvailable(scrnIndex))
365 return FALSE;
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 */
374 if (retval == FALSE)
375 pScrn->currentMode = pTmpMode;
376 return retval;
379 _X_EXPORT Bool
380 VidModeLockZoom(int scrnIndex, Bool lock)
382 ScrnInfoPtr pScrn;
384 DEBUG_P("VidModeLockZoom");
386 if (!VidModeAvailable(scrnIndex))
387 return FALSE;
389 pScrn = xf86Screens[scrnIndex];
391 if (xf86Info.dontZoom)
392 return FALSE;
394 xf86LockZoom(pScrn->pScreen, lock);
395 return TRUE;
398 _X_EXPORT Bool
399 VidModeGetMonitor(int scrnIndex, pointer *monitor)
401 ScrnInfoPtr pScrn;
403 DEBUG_P("VidModeGetMonitor");
405 if (!VidModeAvailable(scrnIndex))
406 return FALSE;
408 pScrn = xf86Screens[scrnIndex];
409 *monitor = (pointer)(pScrn->monitor);
411 return TRUE;
414 _X_EXPORT ModeStatus
415 VidModeCheckModeForMonitor(int scrnIndex, pointer mode)
417 ScrnInfoPtr pScrn;
419 DEBUG_P("VidModeCheckModeForMonitor");
421 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
422 return MODE_ERROR;
424 pScrn = xf86Screens[scrnIndex];
426 return xf86CheckModeForMonitor((DisplayModePtr)mode, pScrn->monitor);
429 _X_EXPORT ModeStatus
430 VidModeCheckModeForDriver(int scrnIndex, pointer mode)
432 ScrnInfoPtr pScrn;
434 DEBUG_P("VidModeCheckModeForDriver");
436 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
437 return MODE_ERROR;
439 pScrn = xf86Screens[scrnIndex];
441 return xf86CheckModeForDriver(pScrn, (DisplayModePtr)mode, 0);
444 _X_EXPORT void
445 VidModeSetCrtcForMode(int scrnIndex, pointer mode)
447 ScrnInfoPtr pScrn;
448 DisplayModePtr ScreenModes;
450 DEBUG_P("VidModeSetCrtcForMode");
452 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
453 return;
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;
462 return;
465 _X_EXPORT Bool
466 VidModeAddModeline(int scrnIndex, pointer mode)
468 ScrnInfoPtr pScrn;
470 DEBUG_P("VidModeAddModeline");
472 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
473 return FALSE;
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;
485 return TRUE;
488 _X_EXPORT int
489 VidModeGetNumOfModes(int scrnIndex)
491 pointer mode = NULL;
492 int dotClock= 0, nummodes = 0;
494 DEBUG_P("VidModeGetNumOfModes");
496 if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock))
497 return nummodes;
499 do {
500 nummodes++;
501 if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock))
502 return nummodes;
503 } while (TRUE);
506 _X_EXPORT Bool
507 VidModeSetGamma(int scrnIndex, float red, float green, float blue)
509 ScrnInfoPtr pScrn;
510 Gamma gamma;
512 DEBUG_P("VidModeSetGamma");
514 if (!VidModeAvailable(scrnIndex))
515 return FALSE;
517 pScrn = xf86Screens[scrnIndex];
518 gamma.red = red;
519 gamma.green = green;
520 gamma.blue = blue;
521 if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success)
522 return FALSE;
523 else
524 return TRUE;
527 _X_EXPORT Bool
528 VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue)
530 ScrnInfoPtr pScrn;
532 DEBUG_P("VidModeGetGamma");
534 if (!VidModeAvailable(scrnIndex))
535 return FALSE;
537 pScrn = xf86Screens[scrnIndex];
538 *red = pScrn->gamma.red;
539 *green = pScrn->gamma.green;
540 *blue = pScrn->gamma.blue;
541 return TRUE;
544 _X_EXPORT Bool
545 VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
547 ScrnInfoPtr pScrn;
549 if (!VidModeAvailable(scrnIndex))
550 return FALSE;
552 pScrn = xf86Screens[scrnIndex];
553 xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b);
554 return TRUE;
557 _X_EXPORT Bool
558 VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
560 ScrnInfoPtr pScrn;
562 if (!VidModeAvailable(scrnIndex))
563 return FALSE;
565 pScrn = xf86Screens[scrnIndex];
566 xf86GetGammaRamp(pScrn->pScreen, size, r, g, b);
567 return TRUE;
570 _X_EXPORT int
571 VidModeGetGammaRampSize(int scrnIndex)
573 if (!VidModeAvailable(scrnIndex))
574 return 0;
576 return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen);
579 _X_EXPORT pointer
580 VidModeCreateMode(void)
582 DisplayModePtr mode;
584 mode = xalloc(sizeof(DisplayModeRec));
585 if (mode != NULL) {
586 mode->name = "";
587 mode->VScan = 1; /* divides refresh rate. default = 1 */
588 mode->Private = NULL;
589 mode->next = mode;
590 mode->prev = mode;
592 return mode;
595 _X_EXPORT void
596 VidModeCopyMode(pointer modefrom, pointer modeto)
598 memcpy(modeto, modefrom, sizeof(DisplayModeRec));
602 _X_EXPORT int
603 VidModeGetModeValue(pointer mode, int valtyp)
605 int ret = 0;
607 switch (valtyp) {
608 case VIDMODE_H_DISPLAY:
609 ret = ((DisplayModePtr) mode)->HDisplay;
610 break;
611 case VIDMODE_H_SYNCSTART:
612 ret = ((DisplayModePtr)mode)->HSyncStart;
613 break;
614 case VIDMODE_H_SYNCEND:
615 ret = ((DisplayModePtr)mode)->HSyncEnd;
616 break;
617 case VIDMODE_H_TOTAL:
618 ret = ((DisplayModePtr)mode)->HTotal;
619 break;
620 case VIDMODE_H_SKEW:
621 ret = ((DisplayModePtr)mode)->HSkew;
622 break;
623 case VIDMODE_V_DISPLAY:
624 ret = ((DisplayModePtr)mode)->VDisplay;
625 break;
626 case VIDMODE_V_SYNCSTART:
627 ret = ((DisplayModePtr)mode)->VSyncStart;
628 break;
629 case VIDMODE_V_SYNCEND:
630 ret = ((DisplayModePtr)mode)->VSyncEnd;
631 break;
632 case VIDMODE_V_TOTAL:
633 ret = ((DisplayModePtr)mode)->VTotal;
634 break;
635 case VIDMODE_FLAGS:
636 ret = ((DisplayModePtr)mode)->Flags;
637 break;
638 case VIDMODE_CLOCK:
639 ret = ((DisplayModePtr)mode)->Clock;
640 break;
642 return ret;
645 _X_EXPORT void
646 VidModeSetModeValue(pointer mode, int valtyp, int val)
648 switch (valtyp) {
649 case VIDMODE_H_DISPLAY:
650 ((DisplayModePtr)mode)->HDisplay = val;
651 break;
652 case VIDMODE_H_SYNCSTART:
653 ((DisplayModePtr)mode)->HSyncStart = val;
654 break;
655 case VIDMODE_H_SYNCEND:
656 ((DisplayModePtr)mode)->HSyncEnd = val;
657 break;
658 case VIDMODE_H_TOTAL:
659 ((DisplayModePtr)mode)->HTotal = val;
660 break;
661 case VIDMODE_H_SKEW:
662 ((DisplayModePtr)mode)->HSkew = val;
663 break;
664 case VIDMODE_V_DISPLAY:
665 ((DisplayModePtr)mode)->VDisplay = val;
666 break;
667 case VIDMODE_V_SYNCSTART:
668 ((DisplayModePtr)mode)->VSyncStart = val;
669 break;
670 case VIDMODE_V_SYNCEND:
671 ((DisplayModePtr)mode)->VSyncEnd = val;
672 break;
673 case VIDMODE_V_TOTAL:
674 ((DisplayModePtr)mode)->VTotal = val;
675 break;
676 case VIDMODE_FLAGS:
677 ((DisplayModePtr)mode)->Flags = val;
678 break;
679 case VIDMODE_CLOCK:
680 ((DisplayModePtr)mode)->Clock = val;
681 break;
683 return;
686 _X_EXPORT vidMonitorValue
687 VidModeGetMonitorValue(pointer monitor, int valtyp, int indx)
689 vidMonitorValue ret;
691 switch (valtyp) {
692 case VIDMODE_MON_VENDOR:
693 ret.ptr = (((MonPtr)monitor)->vendor);
694 break;
695 case VIDMODE_MON_MODEL:
696 ret.ptr = (((MonPtr)monitor)->model);
697 break;
698 case VIDMODE_MON_NHSYNC:
699 ret.i = ((MonPtr)monitor)->nHsync;
700 break;
701 case VIDMODE_MON_NVREFRESH:
702 ret.i = ((MonPtr)monitor)->nVrefresh;
703 break;
704 case VIDMODE_MON_HSYNC_LO:
705 ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].lo);
706 break;
707 case VIDMODE_MON_HSYNC_HI:
708 ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].hi);
709 break;
710 case VIDMODE_MON_VREFRESH_LO:
711 ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].lo);
712 break;
713 case VIDMODE_MON_VREFRESH_HI:
714 ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].hi);
715 break;
717 return ret;
721 #endif /* XF86VIDMODE */