root/morphix/trunk/ddcxinfo/ddcxinfo-knoppix.c

Revision 2, 23.8 kB (checked in by nextime, 2 years ago)

Initial import, branching from morphix svn

Line 
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "vbe.h"
5 /************* This is derived from ddcxinfo written by *****************\
6 #ident "$Id: ddcxinfo-knoppix.c 1890 2005-09-05 13:58:29Z evaleto $"
7 modified by Klaus Knopper <knoppix@knopper.net> for KNOPPIX Feb. 2003
8 modified to max out the monitor for KNOPPIX July 2003
9 \************************************************************************/
10
11 const char *monitor_start=
12 "Section \"Monitor\"\n"
13 "       Identifier   \"Monitor0\"\n";
14
15 const char *default_monitor_hfreqs=
16 "#      HorizSync    28.0 - 78.0 # Warning: This may fry very old Monitors\n"
17 "       HorizSync    28.0 - 96.0 # Warning: This may fry old Monitors\n";
18
19 const char *default_monitor_vfreqs=
20 "       VertRefresh  50.0 - 75.0 # Very conservative. May flicker.\n"
21 "#      VertRefresh  50.0 - 62.0 # Extreme conservative. Will flicker. TFT default.\n";
22
23 const char *default_modelines=
24 "       #  Default modes distilled from\n"
25 "       #      \"VESA and Industry Standards and Guide for Computer Display Monitor\n"
26 "       #       Timing\", version 1.0, revision 0.8, adopted September 17, 1998.\n"
27 "       #  $XFree86: xc/programs/Xserver/hw/xfree86/etc/vesamodes,v 1.4 1999/11/18 16:52:17 tsi Exp $\n"
28 "       # 640x350 @ 85Hz (VESA) hsync: 37.9kHz\n"
29 "       ModeLine \"640x350\"    31.5  640  672  736  832    350  382  385  445 +hsync -vsync\n"
30 "       # 640x400 @ 85Hz (VESA) hsync: 37.9kHz\n"
31 "       ModeLine \"640x400\"    31.5  640  672  736  832    400  401  404  445 -hsync +vsync\n"
32 "       # 720x400 @ 85Hz (VESA) hsync: 37.9kHz\n"
33 "       ModeLine \"720x400\"    35.5  720  756  828  936    400  401  404  446 -hsync +vsync\n"
34 "       # 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz\n"
35 "       ModeLine \"640x480\"    25.2  640  656  752  800    480  490  492  525 -hsync -vsync\n"
36 "       # 640x480 @ 72Hz (VESA) hsync: 37.9kHz\n"
37 "       ModeLine \"640x480\"    31.5  640  664  704  832    480  489  491  520 -hsync -vsync\n"
38 "       # 640x480 @ 75Hz (VESA) hsync: 37.5kHz\n"
39 "       ModeLine \"640x480\"    31.5  640  656  720  840    480  481  484  500 -hsync -vsync\n"
40 "       # 640x480 @ 85Hz (VESA) hsync: 43.3kHz\n"
41 "       ModeLine \"640x480\"    36.0  640  696  752  832    480  481  484  509 -hsync -vsync\n"
42 "       # 800x600 @ 56Hz (VESA) hsync: 35.2kHz\n"
43 "       ModeLine \"800x600\"    36.0  800  824  896 1024    600  601  603  625 +hsync +vsync\n"
44 "       # 800x600 @ 60Hz (VESA) hsync: 37.9kHz\n"
45 "       ModeLine \"800x600\"    40.0  800  840  968 1056    600  601  605  628 +hsync +vsync\n"
46 "       # 800x600 @ 72Hz (VESA) hsync: 48.1kHz\n"
47 "       ModeLine \"800x600\"    50.0  800  856  976 1040    600  637  643  666 +hsync +vsync\n"
48 "       # 800x600 @ 75Hz (VESA) hsync: 46.9kHz\n"
49 "       ModeLine \"800x600\"    49.5  800  816  896 1056    600  601  604  625 +hsync +vsync\n"
50 "       # 800x600 @ 85Hz (VESA) hsync: 53.7kHz\n"
51 "       ModeLine \"800x600\"    56.3  800  832  896 1048    600  601  604  631 +hsync +vsync\n"
52 "       # 1024x768i @ 43Hz (industry standard) hsync: 35.5kHz\n"
53 "       ModeLine \"1024x768\"   44.9 1024 1032 1208 1264    768  768  776  817 +hsync +vsync Interlace\n"
54 "       # 1024x768 @ 60Hz (VESA) hsync: 48.4kHz\n"
55 "       ModeLine \"1024x768\"   65.0 1024 1048 1184 1344    768  771  777  806 -hsync -vsync\n"
56 "       # 1024x768 @ 70Hz (VESA) hsync: 56.5kHz\n"
57 "       ModeLine \"1024x768\"   75.0 1024 1048 1184 1328    768  771  777  806 -hsync -vsync\n"
58 "       # 1024x768 @ 75Hz (VESA) hsync: 60.0kHz\n"
59 "       ModeLine \"1024x768\"   78.8 1024 1040 1136 1312    768  769  772  800 +hsync +vsync\n"
60 "       # 1024x768 @ 85Hz (VESA) hsync: 68.7kHz\n"
61 "       ModeLine \"1024x768\"   94.5 1024 1072 1168 1376    768  769  772  808 +hsync +vsync\n"
62 "       # 1152x864 @ 75Hz (VESA) hsync: 67.5kHz\n"
63 "       ModeLine \"1152x864\"  108.0 1152 1216 1344 1600    864  865  868  900 +hsync +vsync\n"
64 "       # 1280x960 @ 60Hz (VESA) hsync: 60.0kHz\n"
65 "       ModeLine \"1280x960\"  108.0 1280 1376 1488 1800    960  961  964 1000 +hsync +vsync\n"
66 "       # 1280x960 @ 85Hz (VESA) hsync: 85.9kHz\n"
67 "       ModeLine \"1280x960\"  148.5 1280 1344 1504 1728    960  961  964 1011 +hsync +vsync\n"
68 "       # 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz\n"
69 "       ModeLine \"1280x1024\" 108.0 1280 1328 1440 1688   1024 1025 1028 1066 +hsync +vsync\n"
70 "       # 1280x1024 @ 75Hz (VESA) hsync: 80.0kHz\n"
71 "       ModeLine \"1280x1024\" 135.0 1280 1296 1440 1688   1024 1025 1028 1066 +hsync +vsync\n"
72 "       # 1280x1024 @ 85Hz (VESA) hsync: 91.1kHz\n"
73 "       ModeLine \"1280x1024\" 157.5 1280 1344 1504 1728   1024 1025 1028 1072 +hsync +vsync\n"
74 "       # 1600x1200 @ 60Hz (VESA) hsync: 75.0kHz\n"
75 "       ModeLine \"1600x1200\" 162.0 1600 1664 1856 2160   1200 1201 1204 1250 +hsync +vsync\n"
76 "       # 1600x1200 @ 65Hz (VESA) hsync: 81.3kHz\n"
77 "       ModeLine \"1600x1200\" 175.5 1600 1664 1856 2160   1200 1201 1204 1250 +hsync +vsync\n"
78 "       # 1600x1200 @ 70Hz (VESA) hsync: 87.5kHz\n"
79 "       ModeLine \"1600x1200\" 189.0 1600 1664 1856 2160   1200 1201 1204 1250 +hsync +vsync\n"
80 "       # 1600x1200 @ 75Hz (VESA) hsync: 93.8kHz\n"
81 "       ModeLine \"1600x1200\" 202.5 1600 1664 1856 2160   1200 1201 1204 1250 +hsync +vsync\n"
82 "       # 1600x1200 @ 85Hz (VESA) hsync: 106.3kHz\n"
83 "       ModeLine \"1600x1200\" 229.5 1600 1664 1856 2160   1200 1201 1204 1250 +hsync +vsync\n"
84 "       # 1792x1344 @ 60Hz (VESA) hsync: 83.6kHz\n"
85 "       ModeLine \"1792x1344\" 204.8 1792 1920 2120 2448   1344 1345 1348 1394 -hsync +vsync\n"
86 "       # 1792x1344 @ 75Hz (VESA) hsync: 106.3kHz\n"
87 "       ModeLine \"1792x1344\" 261.0 1792 1888 2104 2456   1344 1345 1348 1417 -hsync +vsync\n"
88 "       # 1856x1392 @ 60Hz (VESA) hsync: 86.3kHz\n"
89 "       ModeLine \"1856x1392\" 218.3 1856 1952 2176 2528   1392 1393 1396 1439 -hsync +vsync\n"
90 "       # 1856x1392 @ 75Hz (VESA) hsync: 112.5kHz\n"
91 "       ModeLine \"1856x1392\" 288.0 1856 1984 2208 2560   1392 1393 1396 1500 -hsync +vsync\n"
92 "       # 1920x1440 @ 60Hz (VESA) hsync: 90.0kHz\n"
93 "       ModeLine \"1920x1440\" 234.0 1920 2048 2256 2600   1440 1441 1444 1500 -hsync +vsync\n"
94 "       # 1920x1440 @ 75Hz (VESA) hsync: 112.5kHz\n"
95 "       ModeLine \"1920x1440\" 297.0 1920 2064 2288 2640   1440 1441 1444 1500 -hsync +vsync\n"
96 "       # Additional modelines\n"
97 "       ModeLine \"1800x1440\"  230    1800 1896 2088 2392  1440 1441 1444 1490 +HSync +VSync\n"
98 "       ModeLine \"1800x1440\"  250    1800 1896 2088 2392  1440 1441 1444 1490 +HSync +VSync\n";
99
100 const char *extended_modelines=
101 "       # Extended modelines with GTF timings\n"
102 "       # 640x480 @ 100.00 Hz (GTF) hsync: 50.90 kHz; pclk: 43.16 MHz\n"
103 "       ModeLine \"640x480\"  43.16  640 680 744 848  480 481 484 509  -HSync +Vsync\n"
104 "       # 768x576 @ 60.00 Hz (GTF) hsync: 35.82 kHz; pclk: 34.96 MHz\n"
105 "       ModeLine \"768x576\"  34.96  768 792 872 976  576 577 580 597  -HSync +Vsync\n"
106 "       # 768x576 @ 72.00 Hz (GTF) hsync: 43.27 kHz; pclk: 42.93 MHz\n"
107 "       ModeLine \"768x576\"  42.93  768 800 880 992  576 577 580 601  -HSync +Vsync\n"
108 "       # 768x576 @ 75.00 Hz (GTF) hsync: 45.15 kHz; pclk: 45.51 MHz\n"
109 "       ModeLine \"768x576\"  45.51  768 808 888 1008  576 577 580 602  -HSync +Vsync\n"
110 "       # 768x576 @ 85.00 Hz (GTF) hsync: 51.42 kHz; pclk: 51.84 MHz\n"
111 "       ModeLine \"768x576\"  51.84  768 808 888 1008  576 577 580 605  -HSync +Vsync\n"
112 "       # 768x576 @ 100.00 Hz (GTF) hsync: 61.10 kHz; pclk: 62.57 MHz\n"
113 "       ModeLine \"768x576\"  62.57  768 816 896 1024  576 577 580 611  -HSync +Vsync\n"
114 "       # 800x600 @ 100.00 Hz (GTF) hsync: 63.60 kHz; pclk: 68.18 MHz\n"
115 "       ModeLine \"800x600\"  68.18  800 848 936 1072  600 601 604 636  -HSync +Vsync\n"
116 "       # 1024x768 @ 100.00 Hz (GTF) hsync: 81.40 kHz; pclk: 113.31 MHz\n"
117 "       ModeLine \"1024x768\"  113.31  1024 1096 1208 1392  768 769 772 814  -HSync +Vsync\n"
118 "       # 1152x864 @ 60.00 Hz (GTF) hsync: 53.70 kHz; pclk: 81.62 MHz\n"
119 "       ModeLine \"1152x864\"  81.62  1152 1216 1336 1520  864 865 868 895  -HSync +Vsync\n"
120 "       # 1152x864 @ 85.00 Hz (GTF) hsync: 77.10 kHz; pclk: 119.65 MHz\n"
121 "       ModeLine \"1152x864\"  119.65  1152 1224 1352 1552  864 865 868 907  -HSync +Vsync\n"
122 "       # 1152x864 @ 100.00 Hz (GTF) hsync: 91.50 kHz; pclk: 143.47 MHz\n"
123 "       ModeLine \"1152x864\"  143.47  1152 1232 1360 1568  864 865 868 915  -HSync +Vsync\n"
124 "       # 1280x800 @ 60.00 Hz (GTF) hsync: 49.68 kHz; pclk: 83.46 MHz\n"
125 "       ModeLine \"1280x800\"  83.46  1280 1344 1480 1680  800 801 804 828  -HSync +Vsync\n"
126 "       # 1280x960 @ 72.00 Hz (GTF) hsync: 72.07 kHz; pclk: 124.54 MHz\n"
127 "       ModeLine \"1280x960\"  124.54  1280 1368 1504 1728  960 961 964 1001  -HSync +Vsync\n"
128 "       # 1280x960 @ 75.00 Hz (GTF) hsync: 75.15 kHz; pclk: 129.86 MHz\n"
129 "       ModeLine \"1280x960\"  129.86  1280 1368 1504 1728  960 961 964 1002  -HSync +Vsync\n"
130 "       # 1280x960 @ 100.00 Hz (GTF) hsync: 101.70 kHz; pclk: 178.99 MHz\n"
131 "       ModeLine \"1280x960\"  178.99  1280 1376 1520 1760  960 961 964 1017  -HSync +Vsync\n"
132 "       # 1280x1024 @ 100.00 Hz (GTF) hsync: 108.50 kHz; pclk: 190.96 MHz\n"
133 "       ModeLine \"1280x1024\"  190.96  1280 1376 1520 1760  1024 1025 1028 1085  -HSync +Vsync\n"
134 "       # 1368x768 @ 60.00 Hz (GTF) hsync: 47.70 kHz; pclk: 85.86 MHz\n"
135 "       Modeline \"1368x768\"  85.86  1368 1440 1584 1800  768 769 772 795  -HSync +Vsync\n"
136 "       # 1400x1050 @ 60.00 Hz (GTF) hsync: 65.22 kHz; pclk: 122.61 MHz\n"
137 "       ModeLine \"1400x1050\"  122.61  1400 1488 1640 1880  1050 1051 1054 1087  -HSync +Vsync\n"
138 "       # 1400x1050 @ 72.00 Hz (GTF) hsync: 78.77 kHz; pclk: 149.34 MHz\n"
139 "       ModeLine \"1400x1050\"  149.34  1400 1496 1648 1896  1050 1051 1054 1094  -HSync +Vsync\n"
140 "       # 1400x1050 @ 75.00 Hz (GTF) hsync: 82.20 kHz; pclk: 155.85 MHz\n"
141 "       ModeLine \"1400x1050\"  155.85  1400 1496 1648 1896  1050 1051 1054 1096  -HSync +Vsync\n"
142 "       # 1400x1050 @ 85.00 Hz (GTF) hsync: 93.76 kHz; pclk: 179.26 MHz\n"
143 "       ModeLine \"1400x1050\"  179.26  1400 1504 1656 1912  1050 1051 1054 1103  -HSync +Vsync\n"
144 "       # 1400x1050 @ 100.00 Hz (GTF) hsync: 111.20 kHz; pclk: 214.39 MHz\n"
145 "       ModeLine \"1400x1050\"  214.39  1400 1512 1664 1928  1050 1051 1054 1112  -HSync +Vsync\n"
146 "       # 1440x900 @ 60.00 Hz (GTF) hsync: 55.92 kHz; pclk: 106.47 MHz\n"
147 "       Modeline \"1440x900\"  106.47  1440 1520 1672 1904  900 901 904 932  -HSync +Vsync\n"
148 "       # 1600x1200 @ 100.00 Hz (GTF) hsync: 127.10 kHz; pclk: 280.64 MHz\n"
149 "       ModeLine \"1600x1200\"  280.64  1600 1728 1904 2208  1200 1201 1204 1271  -HSync +Vsync\n"
150 "       # 1680x1050 @ 60.00 Hz (GTF) hsync: 65.22 kHz; pclk: 147.14 MHz\n"
151 "       ModeLine \"1680x1050\"  147.14  1680 1784 1968 2256  1050 1051 1054 1087  -HSync +Vsync\n"
152 "       # 1920x1200 @ 60.00 Hz (GTF) hsync: 74.52 kHz; pclk: 193.16 MHz\n"
153 "       ModeLine \"1920x1200\"  193.16  1920 2048 2256 2592  1200 1201 1204 1242  -HSync +Vsync\n";
154
155 const char *monitor_end=
156 "EndSection\n";
157
158 #define SHOW_HSYNC 1
159 #define SHOW_VSYNC 2
160 #define SHOW_MODELINES 4
161 #define SHOW_MONITOR 8
162 #define SHOW_MODES 16
163 #define SHOW_MONITOR_ID 32
164 #define SHOW_CARD_ID 64
165 #define SHOW_MONITOR_NOML 128
166
167 int cmpmodeline(const void *a, const void *b)
168 {
169         int hdiff  = ((struct vbe_modeline*)b)->width - ((struct vbe_modeline*)a)->width;
170         int vdiff  = ((struct vbe_modeline*)b)->height - ((struct vbe_modeline*)a)->height;
171         int fdiff = ((struct vbe_modeline*)b)->vfreq - ((struct vbe_modeline*)a)->vfreq;
172         return hdiff?hdiff:vdiff?vdiff:fdiff?fdiff:0;
173 }
174
175 int countmodelines(struct vbe_modeline *m)
176 {
177         int i;
178         for(i=0; m[i].refresh != 0; i++);
179         return i;
180 }
181
182 #define HMIN 640
183 #define HMAX 1920
184 #define VMIN 480
185 #define VMAX 1200
186 #define FMAX 180
187 #define FMIN 49
188
189 #define DEFAULTWIDTH 1024
190 #define DEFAULTHEIGHT 768
191
192 /* Check modelines for extreme values, return 0 if OK */
193 int checkmodelines(struct vbe_modeline *m)
194 {
195         int i;
196         if(!m) return 1;
197         for(i=0; m[i].refresh != 0; i++)
198          {
199                  if(m[i].modeline)
200                   {
201                    if(m[i].width>HMAX) return 1;
202                    if(m[i].width<HMIN)  return 1;
203                    if(m[i].height>VMAX)  return 1;
204                    if(m[i].height<VMIN)  return 1;
205                    if(m[i].vfreq>FMAX)  return 1;
206                    if(m[i].vfreq<FMIN)  return 1;
207                   }
208          }
209         return 0;
210 }
211
212 /* Return position of modeline found, or -1 if none */
213 int findmodeline(struct vbe_modeline *m, int width, int height)
214 {
215         int i;
216         if(!m) return -1;
217         for(i=0; m[i].refresh != 0; i++)
218          {
219           if(!m[i].modeline) continue;
220           if((m[i].width==width)&&(m[i].height==height)) return i;
221          }
222         return -1;
223 }
224
225 void getfreqs(struct vbe_modeline* m, unsigned char *h1, unsigned char *h2,
226              unsigned char *v1, unsigned char *v2)
227 {
228  unsigned char hmin=0, vmin=0, hmax=0, vmax=0;
229  int i;
230  vbe_get_edid_ranges(&hmin, &hmax, &vmin, &vmax);
231  if(!hmin && !hmax && !vmin && !vmax)
232   {
233    for(i = 0; m && (m[i].refresh != 0); i++)
234     {
235      if(m[i].hfreq)
236       {
237        if(hmin > m[i].hfreq) hmin = m[i].hfreq;
238        if(hmax < m[i].hfreq) hmax = m[i].hfreq;
239       }
240      if(m[i].vfreq)
241       {
242        if(vmin > m[i].vfreq) vmin = m[i].vfreq;
243        if(vmax < m[i].vfreq) vmax = m[i].vfreq;
244       }
245     }
246   }
247  *h1=hmin; *h2=hmax; *v1=vmin; *v2=vmax;
248 }
249
250 #define MODELINE_MATCH 1
251 #define MODELINE_FIRST 2
252 #define MODELINE_PERFECT 4
253
254 /* Return 1 if modeline resolution is listed in "standard" modes of Monitor,
255  *        2 if listed at first, 4 if also vfreq matches. */
256 int bestmodeline(struct vbe_edid1_info* e, int width, int height, int freq)
257  {
258   int i, match=0;
259   if(!e) return 0;
260   /* Search in standard timings. */
261   for(i = 0; i < 8; i++)
262    {
263     double aspect = 1;
264     unsigned int x, y;
265     unsigned char xres, vfreq;
266     xres = e->standard_timing[i].xresolution;
267     vfreq = e->standard_timing[i].vfreq;
268     if((xres != vfreq) || ((xres != 0) && (xres !=1)) || ((vfreq != 0) && (vfreq != 1)))
269      {
270       switch(e->standard_timing[i].aspect)
271        {
272         case 1: aspect = 0.750; break;
273         case 2: aspect = 0.800; break;
274         case 3: aspect = 0.625; break;
275         default: aspect = 1.0; break;
276        }
277       x = (xres + 31) * 8;
278       y = x * aspect;
279       if((width == x) && (height == y))
280        {
281         match|=MODELINE_MATCH;
282         if(i==0) match|=MODELINE_FIRST;
283         /* Perfect match */
284         if(freq==((vfreq & 0x3f) + 60)) return (match|MODELINE_PERFECT);
285        }
286      }
287    }
288   return match;
289  }
290
291 void showmodelines(struct vbe_modeline* m)
292 {
293  if(m && countmodelines(m) && (checkmodelines(m)==0))
294   {
295    int maxwidth=0, maxheight=0, maxfreq=0, i;
296    printf("\t# These are the DDC-probed settings reported by your monitor.\n"); fflush(stdout);
297    for(i=0; m[i].refresh != 0; i++)
298     {
299      if(m[i].modeline)
300       {
301        if(maxwidth  < m[i].width)  maxwidth = m[i].width;
302        if(maxheight < m[i].height) maxheight = m[i].height;
303        if(maxfreq   < m[i].vfreq)  maxfreq = m[i].vfreq;
304        printf("\t# %dx%d, %1.1f%sHz; hfreq=%.2f, vfreq=%.2f\n\t%s\n",
305                  m[i].width, m[i].height,
306                  m[i].refresh, m[i].interlaced?"i":"",
307                  m[i].hfreq, m[i].vfreq,
308                  m[i].modeline);
309       }
310     }
311    printf(extended_modelines); fflush(stdout);
312   }
313  else
314   {
315    printf(default_modelines); printf(extended_modelines); fflush(stdout);
316   }
317 }
318
319 void showmonitor(struct vbe_edid1_info* e, struct vbe_modeline* m,
320                  unsigned char hmin, unsigned char hmax, unsigned char vmin,
321                  unsigned char vmax)
322 {
323  printf(monitor_start); fflush(stdout);
324  if(e && !(e->version == 0 && e->revision == 0)
325       && !(e->version == 0xff && e->revision == 0xff))
326   {
327    char manufacturer[4] = { e->manufacturer_name.char1 + 'A' - 1,
328                             e->manufacturer_name.char2 + 'A' - 1,
329                             e->manufacturer_name.char3 + 'A' - 1,
330                             0 };
331     printf("\tVendorName\t\"%s\"\n", manufacturer); fflush(stdout);
332     printf("\tModelName\t\"%s%04x\"\n", manufacturer, e->product_code); fflush(stdout);
333    }
334   /* Are these safe for HorizSync? */
335   if(hmin>=28 && hmin<=150 && hmax >= 28 && hmax <= 150 && hmin <= hmax)
336    {
337     if((hmax - hmin) < 2) hmin = hmax - 2; /* XFree needs a little sloppyness */
338     printf("\tHorizSync %d - %d # DDC-probed\n", hmin, hmax); fflush(stdout);
339    }
340   else
341     printf(default_monitor_hfreqs); fflush(stdout);
342   /* Are these safe for VertRefresh? */
343   if(vmin>=FMIN && vmin<=FMAX && vmax >= FMIN && vmax <= FMAX && vmin <= vmax)
344    {
345     if((vmax - vmin) < 2) vmin = vmax - 2; /* XFree needs a little sloppyness */
346     printf("\tVertRefresh %d - %d # DDC-probed\n", vmin, vmax); fflush(stdout);
347    }
348   else
349    { printf(default_monitor_vfreqs); fflush(stdout); }
350   showmodelines(m);
351   printf(monitor_end); fflush(stdout);
352 }
353
354 void showmonitornoml(struct vbe_edid1_info* e, unsigned char hmin, unsigned char hmax, unsigned char vmin,
355                  unsigned char vmax)
356 {
357  printf(monitor_start); fflush(stdout);
358  if(e && !(e->version == 0 && e->revision == 0)
359       && !(e->version == 0xff && e->revision == 0xff))
360   {
361    char manufacturer[4] = { e->manufacturer_name.char1 + 'A' - 1,
362                             e->manufacturer_name.char2 + 'A' - 1,
363                             e->manufacturer_name.char3 + 'A' - 1,
364                             0 };
365     printf("\tVendorName\t\"%s\"\n", manufacturer); fflush(stdout);
366     printf("\tModelName\t\"%s%04x\"\n", manufacturer, e->product_code); fflush(stdout);
367    }
368   /* Are these safe for HorizSync? */
369   if(hmin>=28 && hmin<=150 && hmax >= 28 && hmax <= 150 && hmin <= hmax)
370    {
371     if((hmax - hmin) < 2) hmin = hmax - 2; /* XFree needs a little sloppyness */
372     printf("\tHorizSync %d - %d # DDC-probed\n", hmin, hmax); fflush(stdout);
373    }
374   else
375     printf(default_monitor_hfreqs); fflush(stdout);
376   /* Are these safe for VertRefresh? */
377   if(vmin>=FMIN && vmin<=FMAX && vmax >= FMIN && vmax <= FMAX && vmin <= vmax)
378    {
379     if((vmax - vmin) < 2) vmin = vmax - 2; /* XFree needs a little sloppyness */
380     printf("\tVertRefresh %d - %d # DDC-probed\n", vmin, vmax); fflush(stdout);
381    }
382   else
383    { printf(default_monitor_vfreqs); fflush(stdout); }
384   printf(monitor_end); fflush(stdout);
385 }
386
387 #define HAS_1920x1200 (1<<0)
388 #define HAS_1680x1050 (1<<1)
389 #define HAS_1600x1200 (1<<2)
390 #define HAS_1400x1050 (1<<3)
391 #define HAS_1280x1024 (1<<4)
392 #define HAS_1152x864  (1<<5)
393 #define HAS_1024x768  (1<<6)
394 #define HAS_800x600   (1<<7)
395 #define HAS_640x480   (1<<8)
396
397 void showmodes(struct vbe_edid1_info* e, struct vbe_modeline* m, char *firstmode)
398 {
399  int i;
400  unsigned int foundmodes=0;
401  unsigned int maxwidth=0, maxheight=0;
402  unsigned int widthlimit=HMAX, heightlimit=VMAX;
403  unsigned int lastwidth=0, lastheight=0; /* for uniq */
404  printf("Modes");
405  if(firstmode)
406   {
407    const char *delim="x@";
408    char *s=strtok(firstmode,delim); /* "800x600" */
409    if(s)
410     {
411      int firstwidth=atoi(s);
412      s=strtok(NULL,delim);
413      if((firstwidth>=HMIN) && (firstwidth<=HMAX) && (s!=NULL))
414       {
415        int firstheight=atoi(s);
416        if((firstheight>=VMIN) && (firstheight<=VMAX))
417         {
418          lastwidth  = maxwidth  = widthlimit  = firstwidth;
419          lastheight = maxheight = heightlimit = firstheight;
420          switch(firstwidth)
421           {
422            case 1920: foundmodes|=HAS_1920x1200; break;
423            case 1680: foundmodes|=HAS_1680x1050; break;
424            case 1600: foundmodes|=HAS_1600x1200; break;
425            case 1400: foundmodes|=HAS_1400x1050; break;
426            case 1280: foundmodes|=HAS_1280x1024; break;
427            case 1152: foundmodes|=HAS_1152x864;  break;
428            case 1024: foundmodes|=HAS_1024x768;  break;
429            case 800:  foundmodes|=HAS_800x600;   break;
430            case 640:  foundmodes|=HAS_640x480;   break;
431           }
432          printf(" \"%dx%d\"", firstwidth, firstheight);
433         }
434       }
435     }
436   }
437  if(m&&countmodelines(m)&&(checkmodelines(m)==0))
438   {
439    for(i=0; m[i].refresh != 0; i++)
440     {
441      if(m[i].modeline)
442       {
443        if((m[i].width > widthlimit)   || (m[i].width<HMIN) ||
444           (m[i].height > heightlimit) || (m[i].height>HMAX)) continue; /* skip too extreme modes */
445        if(m[i].width!=lastwidth || m[i].height != lastheight) /* Skip modes we already have */
446         {
447          if(m[i].width>DEFAULTWIDTH || m[i].height>DEFAULTHEIGHT) /* This may still be too large for small monitors */
448           {
449            /* Only add mode if it is the _first_ standard mode of this Monitor */
450            /* (true for all TFT Displays?)                                   */
451            unsigned int matchmode;
452            matchmode = bestmodeline(e, m[i].width, m[i].height, m[i].vfreq);
453            if((matchmode&MODELINE_FIRST)==0) continue;
454