root/morphix/trunk/ddcxinfo/ddcprobe.c

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

Initial import, branching from morphix svn

Line 
1 #define _GNU_SOURCE
2 #include <sys/types.h>
3 #include <sys/io.h>
4 #include <sys/stat.h>
5 #include <sys/vm86.h>
6 #include <sys/syscall.h>
7 #include <sys/mman.h>
8 #include <assert.h>
9 #include <ctype.h>
10 #include <stdio.h>
11 #include <fcntl.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <signal.h>
16 #include <netinet/in.h>
17 #include "vbe.h"
18 #include "vesamode.h"
19 #include "lrmi.h"
20 #ident "$Id: ddcprobe.c 1815 2005-04-25 08:27:54Z alextreme $"
21
22 char *snip(char *string)
23 {
24         int i;
25        
26         /* This is always a 13 character buffer */
27         /* and it's not always terminated. */
28         string[12] = '\0';
29        
30         while(((i = strlen(string)) > 0) &&
31                (isspace(string[i - 1]) ||
32                 (string[i - 1] == '\n') ||
33                 (string[i - 1] == '\r'))) {
34                 string[i - 1] = '\0';
35         }
36         return string;
37 }
38
39 int main(int argc, char **argv)
40 {
41         struct vbe_info *vbe_info = NULL;
42         struct vbe_edid1_info *edid_info = NULL;
43         u_int16_t *mode_list = NULL;
44         char manufacturer[4];
45         int i;
46
47         assert(sizeof(struct vbe_info) == 512);
48         assert(sizeof(struct vbe_edid1_info) == 256);
49         assert(sizeof(struct vbe_edid_detailed_timing) == 18);
50         assert(sizeof(struct vbe_edid_monitor_descriptor) == 18);
51
52         vbe_info = vbe_get_vbe_info();
53         if(vbe_info == NULL) {
54                 printf("VESA BIOS Extensions not detected.\n");
55                 exit(0);
56         }
57
58         /* Signature. */
59         printf("%c%c%c%c %d.%d detected.\n",
60                vbe_info->signature[0], vbe_info->signature[1],
61                vbe_info->signature[2], vbe_info->signature[3],
62                vbe_info->version[1], vbe_info->version[0]);
63
64         /* OEM Strings. */
65         printf("OEM Name: %s\n", vbe_info->oem_name.string);
66         if(vbe_info->version[1] >= 3) {
67                 printf("Vendor Name: %s\n",
68                        vbe_info->vendor_name.string);
69                 printf("Product Name: %s\n",
70                        vbe_info->product_name.string);
71                 printf("Product Revision: %s\n",
72                        vbe_info->product_revision.string);
73         }
74
75        if (strcasestr(vbe_info->oem_name.string, "intel")
76            && strstr(vbe_info->oem_name.string, "810")) {
77                printf("Intel 810 VESA video memory = %d * 64k blocks = %dkb. Use 4MB video memory.\n",
78                       vbe_info->memory_size, vbe_info->memory_size * 64);
79                printf("Memory installed = 64 * 64k blocks = 4096kb\n");
80        } else
81                printf("Memory installed = %d * 64k blocks = %dkb\n",
82                       vbe_info->memory_size, vbe_info->memory_size * 64);
83
84         /* List supported standard modes. */
85         mode_list = vbe_info->mode_list.list;
86         if(*mode_list != 0xffff) {
87                 printf("Supported standard modes:\n");
88         }
89         for(;*mode_list != 0xffff; mode_list++) {
90                 int i;
91                 for(i = 0; known_vesa_modes[i].x != 0; i++) {
92                         if(known_vesa_modes[i].number == *mode_list) {
93                                 printf("\t%s\n", known_vesa_modes[i].text);
94                         }
95                 }
96         }
97
98         if(!vbe_get_edid_supported()) {
99                 printf("EDID read not supported by video card.\n");
100                 exit(0);
101         }
102
103         edid_info = vbe_get_edid_info();
104
105         /* Interpret results. */
106         if((edid_info == NULL) || (edid_info->version == 0)) {
107                 printf("EDID read failed. (No DDC-capable monitor attached?)\n");
108                 exit(0);
109         }
110
111         if ((edid_info->version == 0xff && edid_info->revision == 0xff)
112             || (edid_info->version == 0 && edid_info->revision == 0)) {
113                 printf("EDID read failed, returned empty data\n");
114                 exit(0);
115         }           
116
117         printf("EDID ver. %d rev. %d.\n",
118                edid_info->version, edid_info->revision);
119
120         manufacturer[0] = edid_info->manufacturer_name.char1 + 'A' - 1;
121         manufacturer[1] = edid_info->manufacturer_name.char2 + 'A' - 1;
122         manufacturer[2] = edid_info->manufacturer_name.char3 + 'A' - 1;
123         manufacturer[3] = '\0';
124         printf("Manufacturer: %s\n", manufacturer);
125         printf("ID: %04x\n", edid_info->product_code);
126         printf("EISA ID: %s%04x\n", manufacturer, edid_info->product_code);
127        
128         if(edid_info->serial_number != 0xffffffff) {
129                 if(strcmp(manufacturer, "MAG") == 0) {
130                         edid_info->serial_number -= 0x7000000;
131                 }
132                 if(strcmp(manufacturer, "OQI") == 0) {
133                         edid_info->serial_number -= 456150000;
134                 }
135                 if(strcmp(manufacturer, "VSC") == 0) {
136                         edid_info->serial_number -= 640000000;
137                 }
138         }
139         printf("Serial number: %08x.\n", edid_info->serial_number);
140
141         printf("Manufactured in week %d of %d.\n",
142                edid_info->week, edid_info->year + 1990);
143
144         printf("Input signal type: %s%s%s%s.\n",
145                edid_info->video_input_definition.separate_sync ?
146                "separate sync, " : "",
147                edid_info->video_input_definition.composite_sync ?
148                "composite sync, " : "",
149                edid_info->video_input_definition.sync_on_green ?
150                "sync on green, " : "",
151                edid_info->video_input_definition.digital ?
152                "digital signal" : "analog signal");
153
154         printf("Screen size max %d cm horizontal, %d cm vertical.\n",
155                edid_info->max_size_horizontal,
156                edid_info->max_size_vertical);
157
158         printf("Gamma: %f.\n", edid_info->gamma / 100.0 + 1);
159
160         printf("DPMS flags: %s, %s%s, %s%s, %s%s.\n",
161                edid_info->feature_support.rgb ? "RGB" : "non-RGB",
162                edid_info->feature_support.active_off ? "" : "no ", "active off",
163                edid_info->feature_support.suspend ? "" : "no ", "suspend",
164                edid_info->feature_support.standby ? "" : "no ", "standby");
165
166         printf("Established timings:\n");
167         if(edid_info->established_timings.timing_720x400_70)
168                 printf("\t720x400 @ 70 Hz (VGA 640x400, IBM)\n");
169         if(edid_info->established_timings.timing_720x400_88)
170                 printf("\t720x400 @ 88 Hz (XGA2)\n");
171         if(edid_info->established_timings.timing_640x480_60)
172                 printf("\t640x480 @ 60 Hz (VGA)\n");
173         if(edid_info->established_timings.timing_640x480_67)
174                 printf("\t640x480 @ 67 Hz (Mac II, Apple)\n");
175         if(edid_info->established_timings.timing_640x480_72)
176                 printf("\t640x480 @ 72 Hz (VESA)\n");
177         if(edid_info->established_timings.timing_640x480_75)
178                 printf("\t640x480 @ 75 Hz (VESA)\n");
179         if(edid_info->established_timings.timing_800x600_56)
180                 printf("\t800x600 @ 56 Hz (VESA)\n");
181         if(edid_info->established_timings.timing_800x600_60)
182                 printf("\t800x600 @ 60 Hz (VESA)\n");
183         if(edid_info->established_timings.timing_800x600_72)
184                 printf("\t800x600 @ 72 Hz (VESA)\n");
185         if(edid_info->established_timings.timing_800x600_75)
186                 printf("\t800x600 @ 75 Hz (VESA)\n");
187         if(edid_info->established_timings.timing_832x624_75)
188                 printf("\t832x624 @ 75 Hz (Mac II)\n");
189         if(edid_info->established_timings.timing_1024x768_87i)
190                 printf("\t1024x768 @ 87 Hz Interlaced (8514A)\n");
191         if(edid_info->established_timings.timing_1024x768_60)
192                 printf("\t1024x768 @ 60 Hz (VESA)\n");
193         if(edid_info->established_timings.timing_1024x768_70)
194                 printf("\t1024x768 @ 70 Hz (VESA)\n");
195         if(edid_info->established_timings.timing_1024x768_75)
196                 printf("\t1024x768 @ 75 Hz (VESA)\n");
197         if(edid_info->established_timings.timing_1280x1024_75)
198                 printf("\t1280x1024 @ 75 Hz (VESA)\n");
199
200         /* Standard timings. */
201         for(i = 0; i < 8; i++) {
202                 double aspect = 1;
203                 unsigned int x, y;
204                 unsigned char xres, vfreq;
205                 xres = edid_info->standard_timing[i].xresolution;
206                 vfreq = edid_info->standard_timing[i].vfreq;
207                 if((xres != vfreq) ||
208                    ((xres != 0) && (xres != 1)) ||
209                    ((vfreq != 0) && (vfreq != 1))) {
210                         switch(edid_info->standard_timing[i].aspect) {
211                                 case 0: aspect = 1; break; /*undefined*/
212                                 case 1: aspect = 0.750; break;
213                                 case 2: aspect = 0.800; break;
214                                 case 3: aspect = 0.625; break;
215                         }
216                         x = (xres + 31) * 8;
217                         y = x * aspect;
218                         printf("Standard timing %d: %d Hz, %dx%d\n", i,
219                                (vfreq & 0x3f) + 60, x, y);
220                 }
221         }
222
223         /* Detailed timing information. */
224         for(i = 0; i < 4; i++) {
225                 struct vbe_edid_monitor_descriptor *monitor = NULL;
226                 struct vbe_edid_detailed_timing *timing = NULL;
227
228                 timing = &edid_info->monitor_details.detailed_timing[i];
229                 monitor = &edid_info->monitor_details.monitor_descriptor[i];
230
231                 if((monitor->zero_flag_1 != 0) || (monitor->zero_flag_2 != 0)) {
232                         printf("Detailed timing %d:\n", i);
233                         printf("\tPixel clock: %d\n",
234                                VBE_EDID_DETAILED_TIMING_PIXEL_CLOCK(*timing));
235                         printf("\tHorizontal active time (pixel width): %d\n",
236                                VBE_EDID_DETAILED_TIMING_HORIZONTAL_ACTIVE(*timing));
237                         printf("\tHorizontal blank time (pixel width): %d\n",
238                                VBE_EDID_DETAILED_TIMING_HORIZONTAL_BLANKING(*timing));
239                         printf("\tVertical active time (pixel height): %d\n",
240                                VBE_EDID_DETAILED_TIMING_VERTICAL_ACTIVE(*timing));
241                         printf("\tVertical blank time (pixel height): %d\n",
242                                VBE_EDID_DETAILED_TIMING_VERTICAL_BLANKING(*timing));
243                         printf("\tHorizontal sync offset: %d\n",
244                                VBE_EDID_DETAILED_TIMING_HSYNC_OFFSET(*timing));
245                         printf("\tHorizontal sync pulse width: %d\n",
246                                VBE_EDID_DETAILED_TIMING_HSYNC_PULSE_WIDTH(*timing));
247                         printf("\tVertical sync offset: %d\n",
248                                VBE_EDID_DETAILED_TIMING_VSYNC_OFFSET(*timing));
249                         printf("\tVertical sync pulse width: %d\n",
250                                VBE_EDID_DETAILED_TIMING_VSYNC_PULSE_WIDTH(*timing));
251                         printf("\tDimensions: %dx%d\n",
252                                VBE_EDID_DETAILED_TIMING_HIMAGE_SIZE(*timing),
253                                VBE_EDID_DETAILED_TIMING_VIMAGE_SIZE(*timing));
254                 } else
255                 if(monitor->type == vbe_edid_monitor_descriptor_serial) {
256                         printf("Monitor details %d:\n", i);
257                         printf("\tSerial number: %s\n",
258                                snip(monitor->data.string));
259                 } else
260                 if(monitor->type == vbe_edid_monitor_descriptor_ascii) {
261                         printf("Monitor details %d:\n", i);
262                         printf("\tASCII String: %s:\n",
263                                snip(monitor->data.string));
264                 } else
265                 if(monitor->type == vbe_edid_monitor_descriptor_name) {
266                         printf("Monitor details %d:\n", i);
267                         printf("\tName: %s\n",
268                                snip(monitor->data.string));
269                 } else
270                 if(monitor->type == vbe_edid_monitor_descriptor_range) {
271                         printf("Monitor details %d:\n", i);
272                         printf("\tTiming ranges: "
273                                "horizontal = %d - %d, vertical = %d - %d\n",
274                                monitor->data.range_data.horizontal_min,
275                                monitor->data.range_data.horizontal_max,
276                                monitor->data.range_data.vertical_min,
277                                monitor->data.range_data.vertical_max);
278                 }
279         }
280         return 0;
281 }
Note: See TracBrowser for help on using the browser.