First import
[xorg_rtime.git] / xorg-server-1.4 / hw / kdrive / src / kmode.c
blobd02cb55e1fc3dd86319e2af526671bb67c95fe50
1 /*
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.
24 #ifdef HAVE_CONFIG_H
25 #include <kdrive-config.h>
26 #endif
27 #include "kdrive.h"
29 const KdMonitorTiming kdMonitorTimings[] = {
30 /* H V Hz KHz */
31 /* FP BP BLANK POLARITY */
33 /* IPAQ modeline:
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 */
64 /* 640x480 modes */
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 */
82 /* 800x600 modes */
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 */
91 /* DEFAULT */
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 */
106 /* 1024x768 modes */
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 */
124 /* 1152x864 mode */
125 { 1152, 864, 75, 108000, /* VESA */
126 64, 256, 448, KdSyncPositive, /* 67.500 */
127 1, 32, 36, KdSyncPositive, /* 75.000 */
130 /* 1152x900 modes */
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 */
148 /* 1280x854 modes */
149 { 1280, 854, 103, 12500, /* ADDED */
150 56, 16, 128, KdSyncPositive, /* 102.554 */
151 1, 216, 12, KdSyncPositive,
154 /* 1280x960 modes */
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 */
214 #if 0
215 { 1800, 1012, 75 },
216 { 1906, 1072, 68 },
217 #endif
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 *))
257 int i;
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))
267 return t;
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)
280 return 0;
281 new = old;
283 * Search for the previous size
285 while (new != kdMonitorTimings)
287 new--;
288 if (new->horizontal != old->horizontal &&
289 new->vertical != old->vertical)
291 break;
295 * Match the refresh rate (<=)
297 while (new != kdMonitorTimings)
299 prev = new - 1;
300 if (prev->horizontal == new->horizontal &&
301 prev->vertical == new->vertical &&
302 prev->rate > old->rate)
304 break;
306 new--;
308 return new;
311 Bool
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;
330 else
332 t = kdFindPrevSize (KdFindMode (screen, supported));
333 if (!t)
334 return FALSE;
335 screen->width = t->horizontal;
336 screen->height = t->vertical;
337 screen->rate = t->rate;
340 return TRUE;
343 #ifdef RANDR
344 Bool
345 KdRandRGetInfo (ScreenPtr pScreen,
346 int randr,
347 Bool (*supported) (ScreenPtr pScreen,
348 const KdMonitorTiming *))
350 KdScreenPriv(pScreen);
351 KdScreenInfo *screen = pScreenPriv->screen;
352 int i;
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,
362 t->horizontal,
363 t->vertical,
364 screen->width_mm,
365 screen->height_mm);
366 if (!pSize)
367 return FALSE;
368 if (!RRRegisterRate (pScreen, pSize, t->rate))
369 return FALSE;
370 if (t->horizontal == screen->width &&
371 t->vertical == screen->height &&
372 t->rate == screen->rate)
373 RRSetCurrentConfig (pScreen, randr, t->rate, pSize);
377 return TRUE;
380 const KdMonitorTiming *
381 KdRandRGetTiming (ScreenPtr pScreen,
382 Bool (*supported) (ScreenPtr pScreen,
383 const KdMonitorTiming *),
384 int rate,
385 RRScreenSizePtr pSize)
387 int i;
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 &&
394 t->rate == rate &&
395 (*supported) (pScreen, t))
396 return t;
398 return 0;
400 #endif