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"
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 */
56 /* Modeline "720x576" 29.000 720 736 800 880 576 577 580 625 */
58 720, 576, 52, 32954, /* PAL Video */
59 16, 80, 160, KdSyncPositive
, /* 32.954 */
60 1, 45, 49, KdSyncPositive
, /* 52.727 */
64 {640, 480, 85, 36000, /* VESA */
65 56, 80, 192, KdSyncNegative
, /* 43.269 */
66 1, 25, 29, KdSyncNegative
, /* 85.008 */
68 {640, 480, 75, 31500, /* VESA */
69 16, 120, 200, KdSyncNegative
, /* 37.500 */
70 1, 16, 20, KdSyncNegative
, /* 75.000 */
72 {640, 480, 72, 31500, /* VESA */
73 16, 120, 176, KdSyncNegative
, /* 37.861 */
74 1, 20, 24, KdSyncNegative
, /* 72.809 */
76 {640, 480, 60, 25175, /* VESA */
77 16, 48, 160, KdSyncNegative
, /* 31.469 */
78 10, 33, 45, KdSyncNegative
, /* 59.940 */
82 {800, 600, 85, 56250, /* VESA */
83 32, 152, 248, KdSyncPositive
, /* 53.674 */
84 1, 27, 31, KdSyncPositive
, /* 85.061 */
86 {800, 600, 75, 49500, /* VESA */
87 16, 160, 256, KdSyncPositive
, /* 46.875 */
88 1, 21, 25, KdSyncPositive
, /* 75.000 */
91 #define MONITOR_TIMING_DEFAULT 9
92 {800, 600, 72, 50000, /* VESA */
93 56, 64, 240, KdSyncPositive
, /* 48.077 */
94 37, 23, 66, KdSyncPositive
, /* 72.188 */
96 {800, 600, 60, 40000, /* VESA */
97 40, 88, 256, KdSyncPositive
, /* 37.879 */
98 1, 23, 28, KdSyncPositive
, /* 60.317 */
100 {800, 600, 56, 36000, /* VESA */
101 24, 128, 224, KdSyncPositive
, /* 35.156 */
102 1, 22, 25, KdSyncPositive
, /* 56.250 */
106 {1024, 768, 85, 94500, /* VESA */
107 48, 208, 352, KdSyncPositive
, /* 68.677 */
108 1, 36, 40, KdSyncPositive
, /* 84.997 */
110 {1024, 768, 75, 78750, /* VESA */
111 16, 176, 288, KdSyncPositive
, /* 60.023 */
112 1, 28, 32, KdSyncPositive
, /* 75.029 */
114 {1024, 768, 70, 75000, /* VESA */
115 24, 144, 304, KdSyncNegative
, /* 56.476 */
116 3, 29, 38, KdSyncNegative
, /* 70.069 */
118 {1024, 768, 60, 65000, /* VESA */
119 24, 160, 320, KdSyncNegative
, /* 48.363 */
120 3, 29, 38, KdSyncNegative
, /* 60.004 */
124 {1152, 864, 75, 108000, /* VESA */
125 64, 256, 448, KdSyncPositive
, /* 67.500 */
126 1, 32, 36, KdSyncPositive
, /* 75.000 */
130 {1152, 900, 85, 122500, /* ADDED */
131 48, 208, 384, KdSyncPositive
, /* 79.753 */
132 1, 32, 38, KdSyncPositive
, /* 85.024 */
134 {1152, 900, 75, 108250, /* ADDED */
135 32, 208, 384, KdSyncPositive
, /* 70.475 */
136 1, 32, 38, KdSyncPositive
, /* 75.133 */
138 {1152, 900, 70, 100250, /* ADDED */
139 32, 208, 384, KdSyncPositive
, /* 65.267 */
140 2, 32, 38, KdSyncPositive
, /* 69.581 */
142 {1152, 900, 66, 95000, /* ADDED */
143 32, 208, 384, KdSyncPositive
, /* 61.849 */
144 1, 32, 38, KdSyncPositive
, /* 65.937 */
148 {1280, 854, 103, 12500, /* ADDED */
149 56, 16, 128, KdSyncPositive
, /* 102.554 */
150 1, 216, 12, KdSyncPositive
,
154 {1280, 960, 85, 148500, /* VESA */
155 64, 224, 448, KdSyncPositive
, /* 85.938 */
156 1, 47, 51, KdSyncPositive
, /* 85.002 */
158 {1280, 960, 60, 108000, /* VESA */
159 96, 312, 520, KdSyncPositive
, /* 60.000 */
160 1, 36, 40, KdSyncPositive
, /* 60.000 */
163 /* 1280x1024 modes */
164 {1280, 1024, 85, 157500, /* VESA */
165 64, 224, 448, KdSyncPositive
, /* 91.146 */
166 1, 44, 48, KdSyncPositive
, /* 85.024 */
168 {1280, 1024, 75, 135000, /* VESA */
169 16, 248, 408, KdSyncPositive
, /* 79.976 */
170 1, 38, 42, KdSyncPositive
, /* 75.025 */
172 {1280, 1024, 60, 108000, /* VESA */
173 48, 248, 408, KdSyncPositive
, /* 63.981 */
174 1, 38, 42, KdSyncPositive
, /* 60.020 */
177 /* 1600x1200 modes */
178 {1600, 1200, 85, 229500, /* VESA */
179 64, 304, 560, KdSyncPositive
, /* 106.250 */
180 1, 46, 50, KdSyncPositive
, /* 85.000 */
182 {1600, 1200, 75, 202500, /* VESA */
183 64, 304, 560, KdSyncPositive
, /* 93.750 */
184 1, 46, 50, KdSyncPositive
, /* 75.000 */
186 {1600, 1200, 70, 189000, /* VESA */
187 64, 304, 560, KdSyncPositive
, /* 87.500 */
188 1, 46, 50, KdSyncPositive
, /* 70.000 */
190 {1600, 1200, 65, 175500, /* VESA */
191 64, 304, 560, KdSyncPositive
, /* 81.250 */
192 1, 46, 50, KdSyncPositive
, /* 65.000 */
194 {1600, 1200, 60, 162000, /* VESA */
195 64, 304, 560, KdSyncPositive
, /* 75.000 */
196 1, 46, 50, KdSyncPositive
, /* 60.000 */
199 /* 1792x1344 modes */
200 {1792, 1344, 85, 301500, /* ADDED */
201 96, 352, 672, KdSyncNegative
, /* 122.362 */
202 1, 92, 96, KdSyncPositive
, /* 84.974 */
204 {1792, 1344, 75, 261000, /* VESA */
205 96, 352, 664, KdSyncNegative
, /* 106.270 */
206 1, 69, 73, KdSyncPositive
, /* 74.997 */
208 {1792, 1344, 60, 204750, /* VESA */
209 128, 328, 656, KdSyncNegative
, /* 83.640 */
210 1, 46, 50, KdSyncPositive
, /* 60.000 */
218 /* 1856x1392 modes */
219 {1856, 1392, 85, 330500, /* ADDED */
220 160, 352, 736, KdSyncNegative
, /* 127.508 */
221 1, 104, 108, KdSyncPositive
, /* 85.001 */
223 {1856, 1392, 75, 288000, /* VESA */
224 128, 352, 704, KdSyncNegative
, /* 112.500 */
225 1, 104, 108, KdSyncPositive
, /* 75.000 */
227 {1856, 1392, 60, 218250, /* VESA */
228 96, 352, 672, KdSyncNegative
, /* 86.333 */
229 1, 43, 47, KdSyncPositive
, /* 59.995 */
232 /* 1920x1440 modes */
233 {1920, 1440, 85, 341750, /* ADDED */
234 160, 352, 760, KdSyncNegative
, /* 127.512 */
235 1, 56, 60, KdSyncPositive
, /* 85.012 */
237 {1920, 1440, 75, 297000, /* VESA */
238 144, 352, 720, KdSyncNegative
, /* 112.500 */
239 1, 56, 60, KdSyncPositive
, /* 75.000 */
241 {1920, 1440, 60, 234000, /* VESA */
242 128, 244, 680, KdSyncNegative
, /* 90.000 */
243 1, 56, 60, KdSyncPositive
, /* 60.000 */
247 #define NUM_MONITOR_TIMINGS (sizeof kdMonitorTimings/sizeof kdMonitorTimings[0])
249 const int kdNumMonitorTimings
= NUM_MONITOR_TIMINGS
;
251 const KdMonitorTiming
*
252 KdFindMode(KdScreenInfo
* screen
,
253 Bool (*supported
) (KdScreenInfo
*, const KdMonitorTiming
*))
256 const KdMonitorTiming
*t
;
258 for (i
= 0, t
= kdMonitorTimings
; i
< NUM_MONITOR_TIMINGS
; i
++, t
++) {
259 if ((*supported
) (screen
, t
) &&
260 t
->horizontal
== screen
->width
&&
261 t
->vertical
== screen
->height
&&
262 (!screen
->rate
|| t
->rate
<= screen
->rate
)) {
266 ErrorF("Warning: mode not found, using default\n");
267 return &kdMonitorTimings
[MONITOR_TIMING_DEFAULT
];
270 static const KdMonitorTiming
*
271 kdFindPrevSize(const KdMonitorTiming
* old
)
273 const KdMonitorTiming
*new, *prev
;
275 if (old
== kdMonitorTimings
)
279 * Search for the previous size
281 while (new != kdMonitorTimings
) {
283 if (new->horizontal
!= old
->horizontal
&&
284 new->vertical
!= old
->vertical
) {
289 * Match the refresh rate (<=)
291 while (new != kdMonitorTimings
) {
293 if (prev
->horizontal
== new->horizontal
&&
294 prev
->vertical
== new->vertical
&& prev
->rate
> old
->rate
) {
303 KdTuneMode(KdScreenInfo
* screen
,
304 Bool (*usable
) (KdScreenInfo
*),
305 Bool (*supported
) (KdScreenInfo
*, const KdMonitorTiming
*))
307 const KdMonitorTiming
*t
;
309 while (!(*usable
) (screen
)) {
311 * Fix requested depth and geometry until it works
313 if (screen
->fb
.depth
> 16)
314 screen
->fb
.depth
= 16;
315 else if (screen
->fb
.depth
> 8)
316 screen
->fb
.depth
= 8;
318 t
= kdFindPrevSize(KdFindMode(screen
, supported
));
321 screen
->width
= t
->horizontal
;
322 screen
->height
= t
->vertical
;
323 screen
->rate
= t
->rate
;
331 KdRandRGetInfo(ScreenPtr pScreen
,
333 Bool (*supported
) (ScreenPtr pScreen
, const KdMonitorTiming
*))
335 KdScreenPriv(pScreen
);
336 KdScreenInfo
*screen
= pScreenPriv
->screen
;
338 const KdMonitorTiming
*t
;
340 for (i
= 0, t
= kdMonitorTimings
; i
< NUM_MONITOR_TIMINGS
; i
++, t
++) {
341 if ((*supported
) (pScreen
, t
)) {
342 RRScreenSizePtr pSize
;
344 pSize
= RRRegisterSize(pScreen
,
347 screen
->width_mm
, screen
->height_mm
);
350 if (!RRRegisterRate(pScreen
, pSize
, t
->rate
))
352 if (t
->horizontal
== screen
->width
&&
353 t
->vertical
== screen
->height
&& t
->rate
== screen
->rate
)
354 RRSetCurrentConfig(pScreen
, randr
, t
->rate
, pSize
);
361 const KdMonitorTiming
*
362 KdRandRGetTiming(ScreenPtr pScreen
,
363 Bool (*supported
) (ScreenPtr pScreen
,
364 const KdMonitorTiming
*),
365 int rate
, RRScreenSizePtr pSize
)
368 const KdMonitorTiming
*t
;
370 for (i
= 0, t
= kdMonitorTimings
; i
< NUM_MONITOR_TIMINGS
; i
++, t
++) {
371 if (t
->horizontal
== pSize
->width
&&
372 t
->vertical
== pSize
->height
&&
373 t
->rate
== rate
&& (*supported
) (pScreen
, t
))