2 * Copyright 1999 SuSE, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of SuSE not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. SuSE makes no representations about the
11 * suitability of this software for any purpose. It is provided "as is"
12 * without express or implied warranty.
14 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
16 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Author: Keith Packard, SuSE, Inc.
25 #include <kdrive-config.h>
29 const KdMonitorTiming kdMonitorTimings
[] = {
31 /* FP BP BLANK POLARITY */
35 * Modeline "320x240" 5.7222 320 337 340 352 240 241 244 254"
37 { 320, 240, 64, 16256,
38 17, 12, 32, KdSyncNegative
,
39 1, 11, 14, KdSyncNegative
,
42 /* Other VESA modes */
43 { 640, 350, 85, 31500, /* VESA */
44 32, 96, 192, KdSyncPositive
, /* 26.413 */
45 32, 60, 95, KdSyncNegative
, /* 59.354 */
47 { 640, 400, 60, 31500, /* VESA */
48 32, 96, 192, KdSyncNegative
, /* 26.413 */
49 1, 41, 45, KdSyncPositive
, /* 59.354 */
51 { 720, 400, 85, 35500, /* VESA */
52 36, 108, 216, KdSyncNegative
, /* 37.927 */
53 1, 42, 46, KdSyncPositive
, /* 85.039 */
57 /* Modeline "720x576" 29.000 720 736 800 880 576 577 580 625 */
59 720, 576, 52, 32954, /* PAL Video */
60 16, 80, 160, KdSyncPositive
, /* 32.954 */
61 1, 45, 49, KdSyncPositive
, /* 52.727 */
65 { 640, 480, 85, 36000, /* VESA */
66 56, 80, 192, KdSyncNegative
, /* 43.269 */
67 1, 25, 29, KdSyncNegative
, /* 85.008 */
69 { 640, 480, 75, 31500, /* VESA */
70 16, 120, 200, KdSyncNegative
, /* 37.500 */
71 1, 16, 20, KdSyncNegative
, /* 75.000 */
73 { 640, 480, 72, 31500, /* VESA */
74 16, 120, 176, KdSyncNegative
, /* 37.861 */
75 1, 20, 24, KdSyncNegative
, /* 72.809 */
77 { 640, 480, 60, 25175, /* VESA */
78 16, 48, 160, KdSyncNegative
, /* 31.469 */
79 10, 33, 45, KdSyncNegative
, /* 59.940 */
83 { 800, 600, 85, 56250, /* VESA */
84 32, 152, 248, KdSyncPositive
, /* 53.674 */
85 1, 27, 31, KdSyncPositive
, /* 85.061 */
87 { 800, 600, 75, 49500, /* VESA */
88 16, 160, 256, KdSyncPositive
, /* 46.875 */
89 1, 21, 25, KdSyncPositive
, /* 75.000 */
92 #define MONITOR_TIMING_DEFAULT 9
93 { 800, 600, 72, 50000, /* VESA */
94 56, 64, 240, KdSyncPositive
, /* 48.077 */
95 37, 23, 66, KdSyncPositive
, /* 72.188 */
97 { 800, 600, 60, 40000, /* VESA */
98 40, 88, 256, KdSyncPositive
, /* 37.879 */
99 1, 23, 28, KdSyncPositive
, /* 60.317 */
101 { 800, 600, 56, 36000, /* VESA */
102 24, 128, 224, KdSyncPositive
, /* 35.156 */
103 1, 22, 25, KdSyncPositive
, /* 56.250 */
107 { 1024, 768, 85, 94500, /* VESA */
108 48, 208, 352, KdSyncPositive
, /* 68.677 */
109 1, 36, 40, KdSyncPositive
, /* 84.997 */
111 { 1024, 768, 75, 78750, /* VESA */
112 16, 176, 288, KdSyncPositive
, /* 60.023 */
113 1, 28, 32, KdSyncPositive
, /* 75.029 */
115 { 1024, 768, 70, 75000, /* VESA */
116 24, 144, 304, KdSyncNegative
, /* 56.476 */
117 3, 29, 38, KdSyncNegative
, /* 70.069 */
119 { 1024, 768, 60, 65000, /* VESA */
120 24, 160, 320, KdSyncNegative
, /* 48.363 */
121 3, 29, 38, KdSyncNegative
, /* 60.004 */
125 { 1152, 864, 75, 108000, /* VESA */
126 64, 256, 448, KdSyncPositive
, /* 67.500 */
127 1, 32, 36, KdSyncPositive
, /* 75.000 */
131 { 1152, 900, 85, 122500, /* ADDED */
132 48, 208, 384, KdSyncPositive
, /* 79.753 */
133 1, 32, 38, KdSyncPositive
, /* 85.024 */
135 { 1152, 900, 75, 108250, /* ADDED */
136 32, 208, 384, KdSyncPositive
, /* 70.475 */
137 1, 32, 38, KdSyncPositive
, /* 75.133 */
139 { 1152, 900, 70, 100250, /* ADDED */
140 32, 208, 384, KdSyncPositive
, /* 65.267 */
141 2, 32, 38, KdSyncPositive
, /* 69.581 */
143 { 1152, 900, 66, 95000, /* ADDED */
144 32, 208, 384, KdSyncPositive
, /* 61.849 */
145 1, 32, 38, KdSyncPositive
, /* 65.937 */
149 { 1280, 854, 103, 12500, /* ADDED */
150 56, 16, 128, KdSyncPositive
, /* 102.554 */
151 1, 216, 12, KdSyncPositive
,
155 { 1280, 960, 85, 148500, /* VESA */
156 64, 224, 448, KdSyncPositive
, /* 85.938 */
157 1, 47, 51, KdSyncPositive
, /* 85.002 */
159 { 1280, 960, 60, 108000, /* VESA */
160 96, 312, 520, KdSyncPositive
, /* 60.000 */
161 1, 36, 40, KdSyncPositive
, /* 60.000 */
164 /* 1280x1024 modes */
165 { 1280, 1024, 85, 157500, /* VESA */
166 64, 224, 448, KdSyncPositive
, /* 91.146 */
167 1, 44, 48, KdSyncPositive
, /* 85.024 */
169 { 1280, 1024, 75, 135000, /* VESA */
170 16, 248, 408, KdSyncPositive
, /* 79.976 */
171 1, 38, 42, KdSyncPositive
, /* 75.025 */
173 { 1280, 1024, 60, 108000, /* VESA */
174 48, 248, 408, KdSyncPositive
, /* 63.981 */
175 1, 38, 42, KdSyncPositive
, /* 60.020 */
178 /* 1600x1200 modes */
179 { 1600, 1200, 85, 229500, /* VESA */
180 64, 304, 560, KdSyncPositive
, /* 106.250 */
181 1, 46, 50, KdSyncPositive
, /* 85.000 */
183 { 1600, 1200, 75, 202500, /* VESA */
184 64, 304, 560, KdSyncPositive
, /* 93.750 */
185 1, 46, 50, KdSyncPositive
, /* 75.000 */
187 { 1600, 1200, 70, 189000, /* VESA */
188 64, 304, 560, KdSyncPositive
, /* 87.500 */
189 1, 46, 50, KdSyncPositive
, /* 70.000 */
191 { 1600, 1200, 65, 175500, /* VESA */
192 64, 304, 560, KdSyncPositive
, /* 81.250 */
193 1, 46, 50, KdSyncPositive
, /* 65.000 */
195 { 1600, 1200, 60, 162000, /* VESA */
196 64, 304, 560, KdSyncPositive
, /* 75.000 */
197 1, 46, 50, KdSyncPositive
, /* 60.000 */
200 /* 1792x1344 modes */
201 { 1792, 1344, 85, 301500, /* ADDED */
202 96, 352, 672, KdSyncNegative
, /* 122.362 */
203 1, 92, 96, KdSyncPositive
, /* 84.974 */
205 { 1792, 1344, 75, 261000, /* VESA */
206 96, 352, 664, KdSyncNegative
, /* 106.270 */
207 1, 69, 73, KdSyncPositive
, /* 74.997 */
209 { 1792, 1344, 60, 204750, /* VESA */
210 128, 328, 656, KdSyncNegative
, /* 83.640 */
211 1, 46, 50, KdSyncPositive
, /* 60.000 */
219 /* 1856x1392 modes */
220 { 1856, 1392, 85, 330500, /* ADDED */
221 160, 352, 736, KdSyncNegative
, /* 127.508 */
222 1, 104, 108, KdSyncPositive
, /* 85.001 */
224 { 1856, 1392, 75, 288000, /* VESA */
225 128, 352, 704, KdSyncNegative
, /* 112.500 */
226 1, 104, 108, KdSyncPositive
, /* 75.000 */
228 { 1856, 1392, 60, 218250, /* VESA */
229 96, 352, 672, KdSyncNegative
, /* 86.333 */
230 1, 43, 47, KdSyncPositive
, /* 59.995 */
233 /* 1920x1440 modes */
234 { 1920, 1440, 85, 341750, /* ADDED */
235 160, 352, 760, KdSyncNegative
, /* 127.512 */
236 1, 56, 60, KdSyncPositive
, /* 85.012 */
238 { 1920, 1440, 75, 297000, /* VESA */
239 144, 352, 720, KdSyncNegative
, /* 112.500 */
240 1, 56, 60, KdSyncPositive
, /* 75.000 */
242 { 1920, 1440, 60, 234000, /* VESA */
243 128, 244, 680, KdSyncNegative
, /* 90.000 */
244 1, 56, 60, KdSyncPositive
, /* 60.000 */
248 #define NUM_MONITOR_TIMINGS (sizeof kdMonitorTimings/sizeof kdMonitorTimings[0])
250 const int kdNumMonitorTimings
= NUM_MONITOR_TIMINGS
;
252 const KdMonitorTiming
*
253 KdFindMode (KdScreenInfo
*screen
,
254 Bool (*supported
) (KdScreenInfo
*,
255 const KdMonitorTiming
*))
258 const KdMonitorTiming
*t
;
260 for (i
= 0, t
= kdMonitorTimings
; i
< NUM_MONITOR_TIMINGS
; i
++, t
++)
262 if ((*supported
) (screen
, t
) &&
263 t
->horizontal
== screen
->width
&&
264 t
->vertical
== screen
->height
&&
265 (!screen
->rate
|| t
->rate
<= screen
->rate
))
270 ErrorF("Warning: mode not found, using default\n");
271 return &kdMonitorTimings
[MONITOR_TIMING_DEFAULT
];
274 static const KdMonitorTiming
*
275 kdFindPrevSize (const KdMonitorTiming
*old
)
277 const KdMonitorTiming
*new, *prev
;
279 if (old
== kdMonitorTimings
)
283 * Search for the previous size
285 while (new != kdMonitorTimings
)
288 if (new->horizontal
!= old
->horizontal
&&
289 new->vertical
!= old
->vertical
)
295 * Match the refresh rate (<=)
297 while (new != kdMonitorTimings
)
300 if (prev
->horizontal
== new->horizontal
&&
301 prev
->vertical
== new->vertical
&&
302 prev
->rate
> old
->rate
)
312 KdTuneMode (KdScreenInfo
*screen
,
313 Bool (*usable
) (KdScreenInfo
*),
314 Bool (*supported
) (KdScreenInfo
*,
315 const KdMonitorTiming
*))
317 const KdMonitorTiming
*t
;
319 while (!(*usable
) (screen
))
322 * Fix requested depth and geometry until it works
324 if (screen
->fb
[1].depth
)
325 screen
->fb
[1].depth
= 0;
326 else if (screen
->fb
[0].depth
> 16)
327 screen
->fb
[0].depth
= 16;
328 else if (screen
->fb
[0].depth
> 8)
329 screen
->fb
[0].depth
= 8;
332 t
= kdFindPrevSize (KdFindMode (screen
, supported
));
335 screen
->width
= t
->horizontal
;
336 screen
->height
= t
->vertical
;
337 screen
->rate
= t
->rate
;
345 KdRandRGetInfo (ScreenPtr pScreen
,
347 Bool (*supported
) (ScreenPtr pScreen
,
348 const KdMonitorTiming
*))
350 KdScreenPriv(pScreen
);
351 KdScreenInfo
*screen
= pScreenPriv
->screen
;
353 const KdMonitorTiming
*t
;
355 for (i
= 0, t
= kdMonitorTimings
; i
< NUM_MONITOR_TIMINGS
; i
++, t
++)
357 if ((*supported
) (pScreen
, t
))
359 RRScreenSizePtr pSize
;
361 pSize
= RRRegisterSize (pScreen
,
368 if (!RRRegisterRate (pScreen
, pSize
, t
->rate
))
370 if (t
->horizontal
== screen
->width
&&
371 t
->vertical
== screen
->height
&&
372 t
->rate
== screen
->rate
)
373 RRSetCurrentConfig (pScreen
, randr
, t
->rate
, pSize
);
380 const KdMonitorTiming
*
381 KdRandRGetTiming (ScreenPtr pScreen
,
382 Bool (*supported
) (ScreenPtr pScreen
,
383 const KdMonitorTiming
*),
385 RRScreenSizePtr pSize
)
388 const KdMonitorTiming
*t
;
390 for (i
= 0, t
= kdMonitorTimings
; i
< NUM_MONITOR_TIMINGS
; i
++, t
++)
392 if (t
->horizontal
== pSize
->width
&&
393 t
->vertical
== pSize
->height
&&
395 (*supported
) (pScreen
, t
))