Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / common / xf86VidMode.c
CommitLineData
a09e091a
JB
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
46#ifdef XF86VIDMODE
47#include "vidmodeproc.h"
48#include "xf86cmap.h"
49
50static DevPrivateKeyRec VidModeKeyRec;
51static DevPrivateKey VidModeKey;
52static int VidModeCount = 0;
53static Bool VidModeClose(ScreenPtr pScreen);
54
55#define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey))
56
57#endif
58
59Bool
60VidModeExtensionInit(ScreenPtr pScreen)
61{
62#ifdef XF86VIDMODE
63 VidModePtr pVidMode;
64
65 if (!xf86GetVidModeEnabled()) {
66 DebugF("!xf86GetVidModeEnabled()\n");
67 return FALSE;
68 }
69
70 VidModeKey = &VidModeKeyRec;
71
72 if (!dixRegisterPrivateKey(&VidModeKeyRec, PRIVATE_SCREEN, 0))
73 return FALSE;
74
75 pVidMode = calloc(sizeof(VidModeRec), 1);
76 if (!pVidMode)
77 return FALSE;
78
79 dixSetPrivate(&pScreen->devPrivates, VidModeKey, pVidMode);
80
81 pVidMode->Flags = 0;
82 pVidMode->Next = NULL;
83 pVidMode->CloseScreen = pScreen->CloseScreen;
84 pScreen->CloseScreen = VidModeClose;
85 VidModeCount++;
86 return TRUE;
87#else
88 DebugF("no vidmode extension\n");
89 return FALSE;
90#endif
91}
92
93#ifdef XF86VIDMODE
94
95static Bool
96VidModeClose(ScreenPtr pScreen)
97{
98 VidModePtr pVidMode = VMPTR(pScreen);
99
100 /* This shouldn't happen */
101 if (!pVidMode)
102 return FALSE;
103
104 pScreen->CloseScreen = pVidMode->CloseScreen;
105
106 if (--VidModeCount == 0) {
107 free(dixLookupPrivate(&pScreen->devPrivates, VidModeKey));
108 dixSetPrivate(&pScreen->devPrivates, VidModeKey, NULL);
109 VidModeKey = NULL;
110 }
111 return pScreen->CloseScreen(pScreen);
112}
113
114Bool
115VidModeAvailable(int scrnIndex)
116{
117 ScrnInfoPtr pScrn;
118 VidModePtr pVidMode;
119
120 if (VidModeKey == NULL) {
121 DebugF("VidModeKey == NULL\n");
122 return FALSE;
123 }
124
125 pScrn = xf86Screens[scrnIndex];
126 if (pScrn == NULL) {
127 DebugF("pScrn == NULL\n");
128 return FALSE;
129 }
130
131 pVidMode = VMPTR(pScrn->pScreen);
132 if (pVidMode)
133 return TRUE;
134 else {
135 DebugF("pVidMode == NULL\n");
136 return FALSE;
137 }
138}
139
140Bool
141VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock)
142{
143 ScrnInfoPtr pScrn;
144
145 if (!VidModeAvailable(scrnIndex))
146 return FALSE;
147
148 pScrn = xf86Screens[scrnIndex];
149
150 if (pScrn->currentMode) {
151 *mode = (pointer) (pScrn->currentMode);
152 *dotClock = pScrn->currentMode->Clock;
153
154 return TRUE;
155 }
156 return FALSE;
157}
158
159int
160VidModeGetDotClock(int scrnIndex, int Clock)
161{
162 ScrnInfoPtr pScrn;
163
164 if (!VidModeAvailable(scrnIndex))
165 return 0;
166
167 pScrn = xf86Screens[scrnIndex];
168 if ((pScrn->progClock) || (Clock >= MAXCLOCKS))
169 return Clock;
170 else
171 return pScrn->clock[Clock];
172}
173
174int
175VidModeGetNumOfClocks(int scrnIndex, Bool *progClock)
176{
177 ScrnInfoPtr pScrn;
178
179 if (!VidModeAvailable(scrnIndex))
180 return 0;
181
182 pScrn = xf86Screens[scrnIndex];
183 if (pScrn->progClock) {
184 *progClock = TRUE;
185 return 0;
186 }
187 else {
188 *progClock = FALSE;
189 return pScrn->numClocks;
190 }
191}
192
193Bool
194VidModeGetClocks(int scrnIndex, int *Clocks)
195{
196 ScrnInfoPtr pScrn;
197 int i;
198
199 if (!VidModeAvailable(scrnIndex))
200 return FALSE;
201
202 pScrn = xf86Screens[scrnIndex];
203
204 if (pScrn->progClock)
205 return FALSE;
206
207 for (i = 0; i < pScrn->numClocks; i++)
208 *Clocks++ = pScrn->clock[i];
209
210 return TRUE;
211}
212
213Bool
214VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
215{
216 ScrnInfoPtr pScrn;
217 VidModePtr pVidMode;
218
219 if (!VidModeAvailable(scrnIndex))
220 return FALSE;
221
222 pScrn = xf86Screens[scrnIndex];
223 if (pScrn->modes == NULL)
224 return FALSE;
225
226 pVidMode = VMPTR(pScrn->pScreen);
227 pVidMode->First = pScrn->modes;
228 pVidMode->Next = pVidMode->First->next;
229
230 if (pVidMode->First->status == MODE_OK) {
231 *mode = (pointer) (pVidMode->First);
232 *dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock);
233 return TRUE;
234 }
235
236 return VidModeGetNextModeline(scrnIndex, mode, dotClock);
237}
238
239Bool
240VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
241{
242 ScrnInfoPtr pScrn;
243 VidModePtr pVidMode;
244 DisplayModePtr p;
245
246 if (!VidModeAvailable(scrnIndex))
247 return FALSE;
248
249 pScrn = xf86Screens[scrnIndex];
250 pVidMode = VMPTR(pScrn->pScreen);
251
252 for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
253 if (p->status == MODE_OK) {
254 pVidMode->Next = p->next;
255 *mode = (pointer) p;
256 *dotClock = VidModeGetDotClock(scrnIndex, p->Clock);
257 return TRUE;
258 }
259 }
260
261 return FALSE;
262}
263
264Bool
265VidModeDeleteModeline(int scrnIndex, pointer mode)
266{
267 ScrnInfoPtr pScrn;
268
269 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
270 return FALSE;
271
272 pScrn = xf86Screens[scrnIndex];
273 xf86DeleteMode(&(pScrn->modes), (DisplayModePtr) mode);
274 return TRUE;
275}
276
277Bool
278VidModeZoomViewport(int scrnIndex, int zoom)
279{
280 ScrnInfoPtr pScrn;
281
282 if (!VidModeAvailable(scrnIndex))
283 return FALSE;
284
285 pScrn = xf86Screens[scrnIndex];
286 xf86ZoomViewport(pScrn->pScreen, zoom);
287 return TRUE;
288}
289
290Bool
291VidModeSetViewPort(int scrnIndex, int x, int y)
292{
293 ScrnInfoPtr pScrn;
294
295 if (!VidModeAvailable(scrnIndex))
296 return FALSE;
297
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);
307
308 return TRUE;
309}
310
311Bool
312VidModeGetViewPort(int scrnIndex, int *x, int *y)
313{
314 ScrnInfoPtr pScrn;
315
316 if (!VidModeAvailable(scrnIndex))
317 return FALSE;
318
319 pScrn = xf86Screens[scrnIndex];
320 *x = pScrn->frameX0;
321 *y = pScrn->frameY0;
322 return TRUE;
323}
324
325Bool
326VidModeSwitchMode(int scrnIndex, pointer mode)
327{
328 ScrnInfoPtr pScrn;
329 DisplayModePtr pTmpMode;
330 Bool retval;
331
332 if (!VidModeAvailable(scrnIndex))
333 return FALSE;
334
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 */
342 if (retval == FALSE)
343 pScrn->currentMode = pTmpMode;
344 return retval;
345}
346
347Bool
348VidModeLockZoom(int scrnIndex, Bool lock)
349{
350 ScrnInfoPtr pScrn;
351
352 if (!VidModeAvailable(scrnIndex))
353 return FALSE;
354
355 pScrn = xf86Screens[scrnIndex];
356
357 if (xf86Info.dontZoom)
358 return FALSE;
359
360 xf86LockZoom(pScrn->pScreen, lock);
361 return TRUE;
362}
363
364Bool
365VidModeGetMonitor(int scrnIndex, pointer *monitor)
366{
367 ScrnInfoPtr pScrn;
368
369 if (!VidModeAvailable(scrnIndex))
370 return FALSE;
371
372 pScrn = xf86Screens[scrnIndex];
373 *monitor = (pointer) (pScrn->monitor);
374
375 return TRUE;
376}
377
378ModeStatus
379VidModeCheckModeForMonitor(int scrnIndex, pointer mode)
380{
381 ScrnInfoPtr pScrn;
382
383 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
384 return MODE_ERROR;
385
386 pScrn = xf86Screens[scrnIndex];
387
388 return xf86CheckModeForMonitor((DisplayModePtr) mode, pScrn->monitor);
389}
390
391ModeStatus
392VidModeCheckModeForDriver(int scrnIndex, pointer mode)
393{
394 ScrnInfoPtr pScrn;
395
396 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
397 return MODE_ERROR;
398
399 pScrn = xf86Screens[scrnIndex];
400
401 return xf86CheckModeForDriver(pScrn, (DisplayModePtr) mode, 0);
402}
403
404void
405VidModeSetCrtcForMode(int scrnIndex, pointer mode)
406{
407 ScrnInfoPtr pScrn;
408 DisplayModePtr ScreenModes;
409
410 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
411 return;
412
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;
417
418 xf86SetCrtcForModes(pScrn, pScrn->adjustFlags);
419 pScrn->modes = ScreenModes;
420 return;
421}
422
423Bool
424VidModeAddModeline(int scrnIndex, pointer mode)
425{
426 ScrnInfoPtr pScrn;
427
428 if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
429 return FALSE;
430
431 pScrn = xf86Screens[scrnIndex];
432
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;
440
441 return TRUE;
442}
443
444int
445VidModeGetNumOfModes(int scrnIndex)
446{
447 pointer mode = NULL;
448 int dotClock = 0, nummodes = 0;
449
450 if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock))
451 return nummodes;
452
453 do {
454 nummodes++;
455 if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock))
456 return nummodes;
457 } while (TRUE);
458}
459
460Bool
461VidModeSetGamma(int scrnIndex, float red, float green, float blue)
462{
463 ScrnInfoPtr pScrn;
464 Gamma gamma;
465
466 if (!VidModeAvailable(scrnIndex))
467 return FALSE;
468
469 pScrn = xf86Screens[scrnIndex];
470 gamma.red = red;
471 gamma.green = green;
472 gamma.blue = blue;
473 if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success)
474 return FALSE;
475 else
476 return TRUE;
477}
478
479Bool
480VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue)
481{
482 ScrnInfoPtr pScrn;
483
484 if (!VidModeAvailable(scrnIndex))
485 return FALSE;
486
487 pScrn = xf86Screens[scrnIndex];
488 *red = pScrn->gamma.red;
489 *green = pScrn->gamma.green;
490 *blue = pScrn->gamma.blue;
491 return TRUE;
492}
493
494Bool
495VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
496{
497 ScrnInfoPtr pScrn;
498
499 if (!VidModeAvailable(scrnIndex))
500 return FALSE;
501
502 pScrn = xf86Screens[scrnIndex];
503 xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b);
504 return TRUE;
505}
506
507Bool
508VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
509{
510 ScrnInfoPtr pScrn;
511
512 if (!VidModeAvailable(scrnIndex))
513 return FALSE;
514
515 pScrn = xf86Screens[scrnIndex];
516 xf86GetGammaRamp(pScrn->pScreen, size, r, g, b);
517 return TRUE;
518}
519
520int
521VidModeGetGammaRampSize(int scrnIndex)
522{
523 if (!VidModeAvailable(scrnIndex))
524 return 0;
525
526 return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen);
527}
528
529pointer
530VidModeCreateMode(void)
531{
532 DisplayModePtr mode;
533
534 mode = malloc(sizeof(DisplayModeRec));
535 if (mode != NULL) {
536 mode->name = "";
537 mode->VScan = 1; /* divides refresh rate. default = 1 */
538 mode->Private = NULL;
539 mode->next = mode;
540 mode->prev = mode;
541 }
542 return mode;
543}
544
545void
546VidModeCopyMode(pointer modefrom, pointer modeto)
547{
548 memcpy(modeto, modefrom, sizeof(DisplayModeRec));
549}
550
551int
552VidModeGetModeValue(pointer mode, int valtyp)
553{
554 int ret = 0;
555
556 switch (valtyp) {
557 case VIDMODE_H_DISPLAY:
558 ret = ((DisplayModePtr) mode)->HDisplay;
559 break;
560 case VIDMODE_H_SYNCSTART:
561 ret = ((DisplayModePtr) mode)->HSyncStart;
562 break;
563 case VIDMODE_H_SYNCEND:
564 ret = ((DisplayModePtr) mode)->HSyncEnd;
565 break;
566 case VIDMODE_H_TOTAL:
567 ret = ((DisplayModePtr) mode)->HTotal;
568 break;
569 case VIDMODE_H_SKEW:
570 ret = ((DisplayModePtr) mode)->HSkew;
571 break;
572 case VIDMODE_V_DISPLAY:
573 ret = ((DisplayModePtr) mode)->VDisplay;
574 break;
575 case VIDMODE_V_SYNCSTART:
576 ret = ((DisplayModePtr) mode)->VSyncStart;
577 break;
578 case VIDMODE_V_SYNCEND:
579 ret = ((DisplayModePtr) mode)->VSyncEnd;
580 break;
581 case VIDMODE_V_TOTAL:
582 ret = ((DisplayModePtr) mode)->VTotal;
583 break;
584 case VIDMODE_FLAGS:
585 ret = ((DisplayModePtr) mode)->Flags;
586 break;
587 case VIDMODE_CLOCK:
588 ret = ((DisplayModePtr) mode)->Clock;
589 break;
590 }
591 return ret;
592}
593
594void
595VidModeSetModeValue(pointer mode, int valtyp, int val)
596{
597 switch (valtyp) {
598 case VIDMODE_H_DISPLAY:
599 ((DisplayModePtr) mode)->HDisplay = val;
600 break;
601 case VIDMODE_H_SYNCSTART:
602 ((DisplayModePtr) mode)->HSyncStart = val;
603 break;
604 case VIDMODE_H_SYNCEND:
605 ((DisplayModePtr) mode)->HSyncEnd = val;
606 break;
607 case VIDMODE_H_TOTAL:
608 ((DisplayModePtr) mode)->HTotal = val;
609 break;
610 case VIDMODE_H_SKEW:
611 ((DisplayModePtr) mode)->HSkew = val;
612 break;
613 case VIDMODE_V_DISPLAY:
614 ((DisplayModePtr) mode)->VDisplay = val;
615 break;
616 case VIDMODE_V_SYNCSTART:
617 ((DisplayModePtr) mode)->VSyncStart = val;
618 break;
619 case VIDMODE_V_SYNCEND:
620 ((DisplayModePtr) mode)->VSyncEnd = val;
621 break;
622 case VIDMODE_V_TOTAL:
623 ((DisplayModePtr) mode)->VTotal = val;
624 break;
625 case VIDMODE_FLAGS:
626 ((DisplayModePtr) mode)->Flags = val;
627 break;
628 case VIDMODE_CLOCK:
629 ((DisplayModePtr) mode)->Clock = val;
630 break;
631 }
632 return;
633}
634
635vidMonitorValue
636VidModeGetMonitorValue(pointer monitor, int valtyp, int indx)
637{
638 vidMonitorValue ret = { NULL, };
639
640 switch (valtyp) {
641 case VIDMODE_MON_VENDOR:
642 ret.ptr = (((MonPtr) monitor)->vendor);
643 break;
644 case VIDMODE_MON_MODEL:
645 ret.ptr = (((MonPtr) monitor)->model);
646 break;
647 case VIDMODE_MON_NHSYNC:
648 ret.i = ((MonPtr) monitor)->nHsync;
649 break;
650 case VIDMODE_MON_NVREFRESH:
651 ret.i = ((MonPtr) monitor)->nVrefresh;
652 break;
653 case VIDMODE_MON_HSYNC_LO:
654 ret.f = (100.0 * ((MonPtr) monitor)->hsync[indx].lo);
655 break;
656 case VIDMODE_MON_HSYNC_HI:
657 ret.f = (100.0 * ((MonPtr) monitor)->hsync[indx].hi);
658 break;
659 case VIDMODE_MON_VREFRESH_LO:
660 ret.f = (100.0 * ((MonPtr) monitor)->vrefresh[indx].lo);
661 break;
662 case VIDMODE_MON_VREFRESH_HI:
663 ret.f = (100.0 * ((MonPtr) monitor)->vrefresh[indx].hi);
664 break;
665 }
666 return ret;
667}
668
669#endif /* XF86VIDMODE */