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