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 #include "extinit.h"
46
47 #ifdef XF86VIDMODE
48 #include "vidmodestr.h"
49 #include "xf86Privstr.h"
50 #include "xf86Extensions.h"
51 #include "xf86cmap.h"
52
53 static vidMonitorValue
xf86VidModeGetMonitorValue(ScreenPtr pScreen,int valtyp,int indx)54 xf86VidModeGetMonitorValue(ScreenPtr pScreen, int valtyp, int indx)
55 {
56 vidMonitorValue ret = { NULL, };
57 MonPtr monitor;
58 ScrnInfoPtr pScrn;
59
60 pScrn = xf86ScreenToScrn(pScreen);
61 monitor = pScrn->monitor;
62
63 switch (valtyp) {
64 case VIDMODE_MON_VENDOR:
65 ret.ptr = monitor->vendor;
66 break;
67 case VIDMODE_MON_MODEL:
68 ret.ptr = monitor->model;
69 break;
70 case VIDMODE_MON_NHSYNC:
71 ret.i = monitor->nHsync;
72 break;
73 case VIDMODE_MON_NVREFRESH:
74 ret.i = monitor->nVrefresh;
75 break;
76 case VIDMODE_MON_HSYNC_LO:
77 ret.f = (100.0 * monitor->hsync[indx].lo);
78 break;
79 case VIDMODE_MON_HSYNC_HI:
80 ret.f = (100.0 * monitor->hsync[indx].hi);
81 break;
82 case VIDMODE_MON_VREFRESH_LO:
83 ret.f = (100.0 * monitor->vrefresh[indx].lo);
84 break;
85 case VIDMODE_MON_VREFRESH_HI:
86 ret.f = (100.0 * monitor->vrefresh[indx].hi);
87 break;
88 }
89 return ret;
90 }
91
92 static Bool
xf86VidModeGetCurrentModeline(ScreenPtr pScreen,DisplayModePtr * mode,int * dotClock)93 xf86VidModeGetCurrentModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
94 {
95 ScrnInfoPtr pScrn;
96
97 pScrn = xf86ScreenToScrn(pScreen);
98
99 if (pScrn->currentMode) {
100 *mode = pScrn->currentMode;
101 *dotClock = pScrn->currentMode->Clock;
102
103 return TRUE;
104 }
105 return FALSE;
106 }
107
108 static int
xf86VidModeGetDotClock(ScreenPtr pScreen,int Clock)109 xf86VidModeGetDotClock(ScreenPtr pScreen, int Clock)
110 {
111 ScrnInfoPtr pScrn;
112
113 pScrn = xf86ScreenToScrn(pScreen);
114 if ((pScrn->progClock) || (Clock >= MAXCLOCKS))
115 return Clock;
116 else
117 return pScrn->clock[Clock];
118 }
119
120 static int
xf86VidModeGetNumOfClocks(ScreenPtr pScreen,Bool * progClock)121 xf86VidModeGetNumOfClocks(ScreenPtr pScreen, Bool *progClock)
122 {
123 ScrnInfoPtr pScrn;
124
125 pScrn = xf86ScreenToScrn(pScreen);
126 if (pScrn->progClock) {
127 *progClock = TRUE;
128 return 0;
129 }
130 else {
131 *progClock = FALSE;
132 return pScrn->numClocks;
133 }
134 }
135
136 static Bool
xf86VidModeGetClocks(ScreenPtr pScreen,int * Clocks)137 xf86VidModeGetClocks(ScreenPtr pScreen, int *Clocks)
138 {
139 ScrnInfoPtr pScrn;
140 int i;
141
142 pScrn = xf86ScreenToScrn(pScreen);
143
144 if (pScrn->progClock)
145 return FALSE;
146
147 for (i = 0; i < pScrn->numClocks; i++)
148 *Clocks++ = pScrn->clock[i];
149
150 return TRUE;
151 }
152
153 static Bool
xf86VidModeGetNextModeline(ScreenPtr pScreen,DisplayModePtr * mode,int * dotClock)154 xf86VidModeGetNextModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
155 {
156 VidModePtr pVidMode;
157 DisplayModePtr p;
158
159 pVidMode = VidModeGetPtr(pScreen);
160
161 for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
162 if (p->status == MODE_OK) {
163 pVidMode->Next = p->next;
164 *mode = p;
165 *dotClock = xf86VidModeGetDotClock(pScreen, p->Clock);
166 return TRUE;
167 }
168 }
169
170 return FALSE;
171 }
172
173 static Bool
xf86VidModeGetFirstModeline(ScreenPtr pScreen,DisplayModePtr * mode,int * dotClock)174 xf86VidModeGetFirstModeline(ScreenPtr pScreen, DisplayModePtr *mode, int *dotClock)
175 {
176 ScrnInfoPtr pScrn;
177 VidModePtr pVidMode;
178
179 pScrn = xf86ScreenToScrn(pScreen);
180 if (pScrn->modes == NULL)
181 return FALSE;
182
183 pVidMode = VidModeGetPtr(pScreen);
184 pVidMode->First = pScrn->modes;
185 pVidMode->Next = pVidMode->First->next;
186
187 if (pVidMode->First->status == MODE_OK) {
188 *mode = pVidMode->First;
189 *dotClock = xf86VidModeGetDotClock(pScreen, pVidMode->First->Clock);
190 return TRUE;
191 }
192
193 return xf86VidModeGetNextModeline(pScreen, mode, dotClock);
194 }
195
196 static Bool
xf86VidModeDeleteModeline(ScreenPtr pScreen,DisplayModePtr mode)197 xf86VidModeDeleteModeline(ScreenPtr pScreen, DisplayModePtr mode)
198 {
199 ScrnInfoPtr pScrn;
200
201 if (mode == NULL)
202 return FALSE;
203
204 pScrn = xf86ScreenToScrn(pScreen);
205 xf86DeleteMode(&(pScrn->modes), mode);
206 return TRUE;
207 }
208
209 static Bool
xf86VidModeZoomViewport(ScreenPtr pScreen,int zoom)210 xf86VidModeZoomViewport(ScreenPtr pScreen, int zoom)
211 {
212 xf86ZoomViewport(pScreen, zoom);
213 return TRUE;
214 }
215
216 static Bool
xf86VidModeSetViewPort(ScreenPtr pScreen,int x,int y)217 xf86VidModeSetViewPort(ScreenPtr pScreen, int x, int y)
218 {
219 ScrnInfoPtr pScrn;
220
221 pScrn = xf86ScreenToScrn(pScreen);
222 pScrn->frameX0 = min(max(x, 0),
223 pScrn->virtualX - pScrn->currentMode->HDisplay);
224 pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
225 pScrn->frameY0 = min(max(y, 0),
226 pScrn->virtualY - pScrn->currentMode->VDisplay);
227 pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1;
228 if (pScrn->AdjustFrame != NULL)
229 (pScrn->AdjustFrame) (pScrn, pScrn->frameX0, pScrn->frameY0);
230
231 return TRUE;
232 }
233
234 static Bool
xf86VidModeGetViewPort(ScreenPtr pScreen,int * x,int * y)235 xf86VidModeGetViewPort(ScreenPtr pScreen, int *x, int *y)
236 {
237 ScrnInfoPtr pScrn;
238
239 pScrn = xf86ScreenToScrn(pScreen);
240 *x = pScrn->frameX0;
241 *y = pScrn->frameY0;
242 return TRUE;
243 }
244
245 static Bool
xf86VidModeSwitchMode(ScreenPtr pScreen,DisplayModePtr mode)246 xf86VidModeSwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
247 {
248 ScrnInfoPtr pScrn;
249 DisplayModePtr pTmpMode;
250 Bool retval;
251
252 pScrn = xf86ScreenToScrn(pScreen);
253 /* save in case we fail */
254 pTmpMode = pScrn->currentMode;
255 /* Force a mode switch */
256 pScrn->currentMode = NULL;
257 retval = xf86SwitchMode(pScrn->pScreen, mode);
258 /* we failed: restore it */
259 if (retval == FALSE)
260 pScrn->currentMode = pTmpMode;
261 return retval;
262 }
263
264 static Bool
xf86VidModeLockZoom(ScreenPtr pScreen,Bool lock)265 xf86VidModeLockZoom(ScreenPtr pScreen, Bool lock)
266 {
267 if (xf86Info.dontZoom)
268 return FALSE;
269
270 xf86LockZoom(pScreen, lock);
271 return TRUE;
272 }
273
274 static ModeStatus
xf86VidModeCheckModeForMonitor(ScreenPtr pScreen,DisplayModePtr mode)275 xf86VidModeCheckModeForMonitor(ScreenPtr pScreen, DisplayModePtr mode)
276 {
277 ScrnInfoPtr pScrn;
278
279 if (mode == NULL)
280 return MODE_ERROR;
281
282 pScrn = xf86ScreenToScrn(pScreen);
283
284 return xf86CheckModeForMonitor(mode, pScrn->monitor);
285 }
286
287 static ModeStatus
xf86VidModeCheckModeForDriver(ScreenPtr pScreen,DisplayModePtr mode)288 xf86VidModeCheckModeForDriver(ScreenPtr pScreen, DisplayModePtr mode)
289 {
290 ScrnInfoPtr pScrn;
291
292 if (mode == NULL)
293 return MODE_ERROR;
294
295 pScrn = xf86ScreenToScrn(pScreen);
296
297 return xf86CheckModeForDriver(pScrn, mode, 0);
298 }
299
300 static void
xf86VidModeSetCrtcForMode(ScreenPtr pScreen,DisplayModePtr mode)301 xf86VidModeSetCrtcForMode(ScreenPtr pScreen, DisplayModePtr mode)
302 {
303 ScrnInfoPtr pScrn;
304 DisplayModePtr ScreenModes;
305
306 if (mode == NULL)
307 return;
308
309 /* Ugly hack so that the xf86Mode.c function can be used without change */
310 pScrn = xf86ScreenToScrn(pScreen);
311 ScreenModes = pScrn->modes;
312 pScrn->modes = mode;
313
314 xf86SetCrtcForModes(pScrn, pScrn->adjustFlags);
315 pScrn->modes = ScreenModes;
316 return;
317 }
318
319 static Bool
xf86VidModeAddModeline(ScreenPtr pScreen,DisplayModePtr mode)320 xf86VidModeAddModeline(ScreenPtr pScreen, DisplayModePtr mode)
321 {
322 ScrnInfoPtr pScrn;
323
324 if (mode == NULL)
325 return FALSE;
326
327 pScrn = xf86ScreenToScrn(pScreen);
328
329 mode->name = strdup(""); /* freed by deletemode */
330 mode->status = MODE_OK;
331 mode->next = pScrn->modes->next;
332 mode->prev = pScrn->modes;
333 pScrn->modes->next = mode;
334 if (mode->next != NULL)
335 mode->next->prev = mode;
336
337 return TRUE;
338 }
339
340 static int
xf86VidModeGetNumOfModes(ScreenPtr pScreen)341 xf86VidModeGetNumOfModes(ScreenPtr pScreen)
342 {
343 DisplayModePtr mode = NULL;
344 int dotClock = 0, nummodes = 0;
345
346 if (!xf86VidModeGetFirstModeline(pScreen, &mode, &dotClock))
347 return nummodes;
348
349 do {
350 nummodes++;
351 if (!xf86VidModeGetNextModeline(pScreen, &mode, &dotClock))
352 return nummodes;
353 } while (TRUE);
354 }
355
356 static Bool
xf86VidModeSetGamma(ScreenPtr pScreen,float red,float green,float blue)357 xf86VidModeSetGamma(ScreenPtr pScreen, float red, float green, float blue)
358 {
359 Gamma gamma;
360
361 gamma.red = red;
362 gamma.green = green;
363 gamma.blue = blue;
364 if (xf86ChangeGamma(pScreen, gamma) != Success)
365 return FALSE;
366 else
367 return TRUE;
368 }
369
370 static Bool
xf86VidModeGetGamma(ScreenPtr pScreen,float * red,float * green,float * blue)371 xf86VidModeGetGamma(ScreenPtr pScreen, float *red, float *green, float *blue)
372 {
373 ScrnInfoPtr pScrn;
374
375 pScrn = xf86ScreenToScrn(pScreen);
376 *red = pScrn->gamma.red;
377 *green = pScrn->gamma.green;
378 *blue = pScrn->gamma.blue;
379 return TRUE;
380 }
381
382 static Bool
xf86VidModeSetGammaRamp(ScreenPtr pScreen,int size,CARD16 * r,CARD16 * g,CARD16 * b)383 xf86VidModeSetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
384 {
385 xf86ChangeGammaRamp(pScreen, size, r, g, b);
386 return TRUE;
387 }
388
389 static Bool
xf86VidModeGetGammaRamp(ScreenPtr pScreen,int size,CARD16 * r,CARD16 * g,CARD16 * b)390 xf86VidModeGetGammaRamp(ScreenPtr pScreen, int size, CARD16 *r, CARD16 *g, CARD16 *b)
391 {
392 xf86GetGammaRamp(pScreen, size, r, g, b);
393 return TRUE;
394 }
395
396 static Bool
xf86VidModeInit(ScreenPtr pScreen)397 xf86VidModeInit(ScreenPtr pScreen)
398 {
399 VidModePtr pVidMode;
400
401 if (!xf86GetVidModeEnabled()) {
402 DebugF("!xf86GetVidModeEnabled()\n");
403 return FALSE;
404 }
405
406 pVidMode = VidModeInit(pScreen);
407 if (!pVidMode)
408 return FALSE;
409
410 pVidMode->Flags = 0;
411 pVidMode->Next = NULL;
412
413 pVidMode->GetMonitorValue = xf86VidModeGetMonitorValue;
414 pVidMode->GetCurrentModeline = xf86VidModeGetCurrentModeline;
415 pVidMode->GetFirstModeline = xf86VidModeGetFirstModeline;
416 pVidMode->GetNextModeline = xf86VidModeGetNextModeline;
417 pVidMode->DeleteModeline = xf86VidModeDeleteModeline;
418 pVidMode->ZoomViewport = xf86VidModeZoomViewport;
419 pVidMode->GetViewPort = xf86VidModeGetViewPort;
420 pVidMode->SetViewPort = xf86VidModeSetViewPort;
421 pVidMode->SwitchMode = xf86VidModeSwitchMode;
422 pVidMode->LockZoom = xf86VidModeLockZoom;
423 pVidMode->GetNumOfClocks = xf86VidModeGetNumOfClocks;
424 pVidMode->GetClocks = xf86VidModeGetClocks;
425 pVidMode->CheckModeForMonitor = xf86VidModeCheckModeForMonitor;
426 pVidMode->CheckModeForDriver = xf86VidModeCheckModeForDriver;
427 pVidMode->SetCrtcForMode = xf86VidModeSetCrtcForMode;
428 pVidMode->AddModeline = xf86VidModeAddModeline;
429 pVidMode->GetDotClock = xf86VidModeGetDotClock;
430 pVidMode->GetNumOfModes = xf86VidModeGetNumOfModes;
431 pVidMode->SetGamma = xf86VidModeSetGamma;
432 pVidMode->GetGamma = xf86VidModeGetGamma;
433 pVidMode->SetGammaRamp = xf86VidModeSetGammaRamp;
434 pVidMode->GetGammaRamp = xf86VidModeGetGammaRamp;
435 pVidMode->GetGammaRampSize = xf86GetGammaRampSize; /* use xf86cmap API directly */
436
437 return TRUE;
438 }
439
440 void
XFree86VidModeExtensionInit(void)441 XFree86VidModeExtensionInit(void)
442 {
443 int i;
444 Bool enabled = FALSE;
445
446 DebugF("XFree86VidModeExtensionInit");
447
448 /* This means that the DDX doesn't want the vidmode extension enabled */
449 if (!xf86GetVidModeEnabled())
450 return;
451
452 for (i = 0; i < screenInfo.numScreens; i++) {
453 if (xf86VidModeInit (screenInfo.screens[i]))
454 enabled = TRUE;
455 }
456 /* This means that the DDX doesn't want the vidmode extension enabled */
457 if (!enabled)
458 return;
459
460 VidModeAddExtension(xf86GetVidModeAllowNonLocal());
461 }
462
463 #endif /* XF86VIDMODE */
464