/[gentoo-src]/Xorgautoconfig/Xorgautoconfig.c
Gentoo

Contents of /Xorgautoconfig/Xorgautoconfig.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations) (download) (as text)
Mon Apr 18 01:31:50 2005 UTC (9 years, 4 months ago) by pylon
Branch: MAIN
Changes since 1.1: +58 -22 lines
File MIME type: text/x-csrc
Patches by JoseJX from bug #84468.

1 pylon 1.1 /* Xorgautoconfig: versatile xorg.conf creation tool for PowerPC
2     *
3     * Copyright (C) 2005 Lars Weiler <pylon@gentoo.org>
4     *
5     * This xorg.conf creation tool is a fork from Xautoconfig-0.23
6     * (http://ftp.penguinppc.org/projects/xautocfg/)
7     *
8     * The original header-comment contained:
9     * Copyright (C) 2002-2004 Dan Burcaw <dan@ydl.net>
10     * Copyright (C) 1999-2001 Tom Rini <trini@kernel.crashing.org>
11     *
12     * Thanks for this good start for a X.Org configurator!
13     *
14     */
15    
16     #define _GNU_SOURCE
17     #include <stdio.h>
18     #include <stdlib.h>
19     #include <assert.h>
20     #include <ctype.h>
21     #include <signal.h>
22     #include <fcntl.h>
23     #include <string.h>
24     #include <unistd.h>
25     #include <sys/ioctl.h>
26     #include <sys/types.h>
27     #include <sys/stat.h>
28     #include <sys/syscall.h>
29     #include <sys/mman.h>
30     #include <netinet/in.h>
31     #include <linux/fb.h>
32     #include <byteswap.h>
33 pylon 1.2 #include <dirent.h>
34 pylon 1.1
35     #include "ddcprobe/common.h"
36     #include "ddcprobe/vesamode.h"
37     #include "Xorgtext.h"
38    
39     extern int bus, dev, func;
40     extern void findVideoDevice(void);
41     extern void help();
42     extern void usage();
43     extern char * macMachineType(void);
44    
45     struct monitor_sync
46     {
47     int h_min;
48     int h_max;
49     int v_min;
50     int v_max;
51     };
52    
53     int main(int argc, char **argv) {
54     FILE * f;
55     int i, depth, fd;
56     int rc = 0, offb = 0, fbdepth = 0, fbdev = 0, nv = 0;
57     unsigned int xsstart, xsend, xtotal = 0;
58     unsigned int ysstart, ysend, ytotal = 0;
59     double drate, vrate, hrate;
60     unsigned int htotal, vtotal;
61     char manufacturer[4];
62    
63     struct monitor_sync sync;
64     struct fb_fix_screeninfo fix;
65     struct fb_var_screeninfo var;
66     struct edid1_info *edid_info = NULL;
67    
68     const char * name = "/dev/fb0";
69     unsigned char *mem;
70     char *macid;
71     char *eisaid;
72    
73     if (!(fd = open(name, O_RDONLY)))
74     rc = 2; /* Failure */
75    
76     if (!rc && ioctl(fd, FBIOGET_FSCREENINFO, &fix))
77     rc = 2; /* Failure */
78    
79     if (!rc && ioctl(fd, FBIOGET_VSCREENINFO, &var))
80     rc = 2; /* Failure */
81    
82     close(fd);
83    
84     /* 640x480 framebuffer typically implies a CRT, so lets bump */
85     /* the resolution up to 800x600 to be a bit more sane */
86     if (var.xres == 640 && var.yres == 480) {
87     var.xres = 800;
88     var.yres = 600;
89     }
90    
91     if (rc) {
92     fprintf(stderr, "Can't access %s. Exiting.\n", name);
93     return -1;
94     }
95    
96     if (argc == 2)
97     {
98     if (!strcmp(argv[1], "--fbdepth"))
99     fbdepth = 1;
100     else if (!strcmp(argv[1], "--fbdev"))
101     fbdev = 1;
102     else if (!strcmp(argv[1], "--safe"))
103     fbdev = fbdepth = 1;
104     else if (!strcmp(argv[1], "--help")) {
105     usage();
106     exit(0);
107     } else {
108     usage();
109     exit(0);
110     }
111     } else if (argc > 2) {
112     usage();
113     exit(0);
114    
115     }
116    
117     /* Check to see what type of Mac we're on.*/
118     /* e.g. PowerBook1,1 */
119     macid = macMachineType();
120    
121     sync.h_min = 0;
122     sync.h_max = 0;
123     sync.v_min = 0;
124     sync.v_max = 0;
125    
126     /* Check to see if EDID is available */
127     if ( (sizeof(struct edid1_info) == 256) &&
128     (sizeof(struct edid_monitor_descriptor) == 18) &&
129     get_edid_supported())
130     {
131     edid_info = get_edid_info();
132    
133     if ( !(edid_info == NULL) &&
134     !(edid_info->version == 0) &&
135     !(edid_info->version == 0xff && edid_info->revision == 0xff) &&
136     !(edid_info->version == 0 && edid_info->revision == 0))
137     {
138     manufacturer[0] = edid_info->manufacturer_name.char1 + 'A' - 1;
139     manufacturer[1] = edid_info->manufacturer_name.char2 + 'A' - 1;
140     manufacturer[2] = edid_info->manufacturer_name.char3 + 'A' - 1;
141     manufacturer[3] = '\0';
142     eisaid = malloc(sizeof(manufacturer) + sizeof(edid_info->product_code));
143     sprintf(eisaid, "%s%04x", manufacturer, edid_info->product_code);
144    
145     for (i = 0; i < 4; i++)
146     {
147     struct edid_monitor_descriptor *monitor = NULL;
148    
149     monitor = &edid_info->monitor_details.monitor_descriptor[i];
150    
151     if (monitor->type == edid_monitor_descriptor_range)
152     {
153     sync.h_min = monitor->data.range_data.horizontal_min;
154     sync.h_max = monitor->data.range_data.horizontal_max;
155     sync.v_min = monitor->data.range_data.vertical_min;
156     sync.v_max = monitor->data.range_data.vertical_max;
157     }
158     }
159     /* On certain Apple LCD panels, set vertical min and max */
160     if ((eisaid) && (!strcmp(eisaid, "APP1592") ||
161     !strcmp(eisaid, "APPf401") ||
162     !strcmp(eisaid, "APP1792") ||
163     !strcmp(eisaid, "APP1992") ||
164     !strcmp(eisaid, "APP1692") ||
165     !strcmp(eisaid, "APP1892")))
166     sync.v_min = 50;
167     sync.v_max = 60;
168     }
169     }
170    
171     /* More or less taken from Geert Uytterhoeven's fbset (GPL'ed as well..) */
172     htotal = var.left_margin+var.xres+var.right_margin+var.hsync_len;
173     vtotal = var.upper_margin+var.yres+var.lower_margin+var.vsync_len;
174     drate = (1E12/var.pixclock);
175     hrate = drate/htotal;
176     vrate = hrate/vtotal;
177     xsstart = var.xres+var.right_margin;
178     xsend = xsstart+var.hsync_len;
179     xtotal = xsend+var.left_margin;
180     ysstart = var.yres+var.lower_margin;
181     ysend = ysstart+var.vsync_len;
182     ytotal = ysend+var.upper_margin;
183     if (var.bits_per_pixel == 8)
184     depth = 8;
185     else
186     depth = var.red.length+var.green.length+var.blue.length;
187    
188     /* look for nvidia and offb */
189     if (fix.id)
190     {
191     mem = strdup(fix.id);
192     while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) {
193     mem[i - 1] = '\0';
194     }
195     if (strstr(fix.id, "NVDA") != NULL)
196     nv = 1;
197    
198     if (!strncmp(fix.id, "OFfb", 4))
199     offb = 1;
200     }
201    
202     findVideoDevice(); /* For BusID */
203    
204     /* Let's be nice and backup an existing xorg.conf */
205     if ((f = fopen("/etc/X11/xorg.conf", "r"))) {
206     system("mv /etc/X11/xorg.conf /etc/X11/xorg.xorgautoconfig");
207     }
208    
209     if (!(f = fopen("/etc/X11/xorg.conf", "w"))) {
210     fprintf(stderr, "Can't write to /etc/X11/xorg.conf. Exiting.\n");
211     return -1;;
212     }
213    
214    
215     /*** BEGIN xorg.conf ***/
216     fprintf(f, "%s", header);
217    
218 pylon 1.2 /* Set fontpaths */
219     DIR *fontdir = opendir(FONTPATH);
220     DIR *testdir;
221     char path[256];
222     struct dirent *fontpath;
223    
224     /* Add x fontserver note */
225     fprintf(f, "%s", fontpath_xfs);
226     if(fontdir != NULL) {
227     while ((fontpath = readdir (fontdir))) {
228     if((fontpath->d_name)[0] != '.') {
229     /* Only add directories */
230     strcpy(path, FONTPATH);
231     strcat(path, fontpath->d_name);
232     strcat(path, "/");
233     testdir = opendir(path);
234     if(testdir != NULL) {
235     fprintf(f, "\tFontPath\t\"%s\"\n",
236     path);
237     if(!strncmp(fontpath->d_name,"75dpi",5) ||
238     !strncmp(fontpath->d_name,"100dpi",6)){
239     fprintf(f, "\tFontPath\t\"%s:unscaled\"\n",
240     path);
241     }
242     closedir(testdir);
243     }
244     }
245     }
246     closedir(fontdir);
247     }
248     else {
249     fprintf(f, "%s", fontpath_gentoo);
250     }
251     fprintf(f, "EndSection\n\n");
252 pylon 1.1
253     /* modules section */
254     fprintf(f, "%s", modules_section);
255    
256     /* extensions section */
257     fprintf(f, "%s", extensions_section);
258    
259     /* serverflags section */
260     fprintf(f, "%s", serverflags_section);
261    
262     /* input dev section */
263     fprintf(f, "%s", inputdev_section);
264    
265     /* keyboard */
266     fprintf(f, "%s", keyboard_linux);
267    
268     /* mouse */
269     fprintf(f, "%s", mouse_section);
270     fprintf(f, "IMPS/2\"\n");
271     fprintf(f, " Option \"Device\" \"/dev/input/mice\"\n");
272     fprintf(f, "EndSection\n\n");
273    
274     /* monitor section */
275     if (!offb)
276     fprintf(f, "%s", monitor_section);
277     else
278     fprintf(f, "%s", monitor_section_nomodes);
279    
280     /* Use EDID's horizsync / vert refresh first, otherwise try to be sane */
281     if (sync.h_min && sync.h_max && sync.v_min && sync.v_max)
282     {
283     fprintf(f, "\tHorizSync %d-%d\n\tVertRefresh %d-%d\n",
284     sync.h_min, sync.h_max, sync.v_min, sync.v_max);
285     } else if (!strncmp(macid, "PowerMac4,2", 11)) {
286     fprintf(f, "\tHorizSync 28-49 \n\tVertRefresh 50-60\n");
287     } else if (sync.v_min && sync.v_max) {
288     /* Apple Studio/Cinema Display case */
289     fprintf(f, "\tHorizSync 30-130\n\tVertRefresh %d-%d\n",
290     sync.v_min, sync.v_max);
291     } else {
292     if(var.xres <= 640)
293     fprintf(f, " HorizSync 28-33\n VertRefresh 43-72\n");
294     else if(var.xres <= 800)
295     fprintf(f, " HorizSync 28-50\n VertRefresh 43-75\n");
296     else if(var.xres <= 1024)
297     fprintf(f, " HorizSync 30-70\n VertRefresh 50-160\n");
298     else if(var.xres <= 1152)
299     fprintf(f, " HorizSync 30-100\n VertRefresh 50-160\n");
300     else
301     fprintf(f, " HorizSync 30-130\n VertRefresh 50-160\n");
302     }
303    
304     if (!offb)
305     {
306     fprintf(f, "%s", modes_section);
307     fprintf(f, " # D: %5.3f MHz, H: %5.3f kHz, V: %5.3f Hz\n", drate/1E6,
308     hrate/1E3, vrate);
309     fprintf(f, " Modeline \"%dx%d\" %5.3f %d %d %d %d %d %d %d %d ",
310     var.xres, var.yres, drate/1E6, var.xres, xsstart, xsend,
311     xtotal, var.yres, ysstart, ysend, ytotal);
312     if (var.vmode & FB_VMODE_INTERLACED)
313     fprintf(f, " Interlace");
314     if (var.vmode & FB_VMODE_DOUBLE)
315     fprintf(f, " DoubleScan");
316     if (var.sync & FB_SYNC_HOR_HIGH_ACT)
317     fprintf(f, " +HSync");
318     else
319     fprintf(f, " -HSync");
320     if (var.sync & FB_SYNC_VERT_HIGH_ACT)
321     fprintf(f, " +VSync");
322     else
323     fprintf(f, " -VSync");
324     if (var.sync & FB_SYNC_COMP_HIGH_ACT)
325     fprintf(f, " Composite");
326     if (var.sync & FB_SYNC_BROADCAST)
327     fprintf(f, " bcast");
328     }
329     fprintf(f, "%s", device_start);
330     depth = 16;
331    
332     /* See if we know where the card is, if not... */
333     if (nv) {
334     if (!strncmp(macid, "PowerMac4,2", 11) || !strncmp(macid, "PowerMac4,5", 11))
335     fprintf(f, " Option \"FlatPanel\"\n");
336 pylon 1.2 fprintf(f, "%s", driver_nv);
337     fprintf(f, " Driver\t\t\"nv\"\n");
338 pylon 1.1 } else if((fbdev) || (bus == 0 && dev == 0 && func == 0)) {
339     if (!fbdev) {
340     fprintf(f, " # We couldn't determine the BusID of your ");
341     fprintf(f, "video card. So we will use\n# the fbdev driver\n");
342     }
343     fprintf(f, " #Option \"ShadowFB\" \"true\"\n");
344     fprintf(f, " #Option \"fbdev\" \"%s\"\n", name);
345 pylon 1.2 fprintf(f, " Driver\t\t\"fbdev\"\n");
346 pylon 1.1 fprintf(f, " #BusID \"0:0:0\"\n");
347     depth = 15;
348     } else {
349     /* Try and guess what video card is behind /dev/fb0 */
350     switch(fix.accel) {
351     /* ATI Mach64 Family cards */
352     case 6:
353     case 8:
354     case 9:
355     case 10:
356     fprintf(f, "%s", driver_on_opts);
357 pylon 1.2 fprintf(f, " Driver\t\t\"ati\"\n");
358 pylon 1.1 break;
359     /* IMS Twin Turbo */
360     case 14:
361     fprintf(f, "%s", driver_off_opts);
362 pylon 1.2 fprintf(f, " Driver\t\t\"imstt\"\n");
363 pylon 1.1 break;
364     /* Matrox Family */
365     case 16:
366     case 17:
367     case 18:
368     case 20:
369     case 21:
370     case 26:
371     fprintf(f, "%s", driver_off_opts);
372 pylon 1.2 fprintf(f, " Driver\t\t\"mga\"\n");
373 pylon 1.1 break;
374     /* Chips&Technology 6555x */
375     /* Apparently this is broken...
376     case 30:
377     fprintf(f, "%s", driver_off_opts);
378 pylon 1.2 fprintf(f, " Driver\t\t\"chips\"\n");
379 pylon 1.1 break;
380     */
381     /* VooDoo 3 / Banshee */
382     case 31:
383     fprintf(f, "%s", driver_off_opts);
384 pylon 1.2 fprintf(f, " Driver\t\t\"tdfx\"\n");
385 pylon 1.1 break;
386     /* ATI Rage 128 Family */
387     case 32:
388 pylon 1.2 fprintf(f, "%s", driver_r128);
389     fprintf(f, " Driver\t\t\"r128\"\n");
390 pylon 1.1 break;
391     /* ATI Radeon */
392     case 38:
393 pylon 1.2 fprintf(f, "%s", driver_radeon);
394     fprintf(f, " Driver\t\t\"radeon\"\n");
395 pylon 1.1 break;
396     default:
397 pylon 1.2 /* FIXME still broken? */
398 pylon 1.1 /* radeon seems to be broken on VE (aka 7000) */
399     if ((!strncmp(fix.id, "ATI Radeon", 10)) &&
400     (strncmp(fix.id, "ATI Radeon VE", 13))) {
401 pylon 1.2 fprintf(f, "%s", driver_radeon);
402     fprintf(f, " Driver\t\t\"radeon\"\n");
403 pylon 1.1 } else if (!strncmp(fix.id, "Rage128", 7)) {
404 pylon 1.2 fprintf(f, "%s", driver_r128);
405     fprintf(f, " Driver\t\t\"r128\"\n");
406 pylon 1.1 } else if (!strncmp(fix.id, "Rage Mobility M3", 16)) {
407 pylon 1.2 fprintf(f, "%s", driver_r128);
408     fprintf(f, " Driver\t\t\"r128\"\n");
409 pylon 1.1 } else {
410     fprintf(f, " #Option \"ShadowFB\"");
411     fprintf(f, " \"true\"\n");
412 pylon 1.2 fprintf(f, " Driver\t\t\"fbdev\"\n");
413 pylon 1.1 depth = 15;
414     }
415     break;
416     }
417     fprintf(f, " BusID \"PCI:%d:%d:%d\"\n", bus, dev, func);
418     }
419     fprintf(f, "%s", screen_section);
420     fprintf(f, "%d\n", depth);
421     if(fbdepth && depth != var.bits_per_pixel)
422     fprintf(f," DefaultFbBpp %d\n", var.bits_per_pixel);
423    
424     /* Print this out for 8 / 16 / 24 */
425     for (i = 8;i <= 24;i = i + 8)
426     {
427     fprintf(f, " SubSection \"Display\"\n");
428     fprintf(f, " Depth %d\n", i);
429    
430     /* If they've got 32bit use it, otherwise use 24 */
431     if (depth == 24 && depth != var.bits_per_pixel)
432     fprintf(f, " FbBpp %d\n",
433     var.bits_per_pixel);
434    
435     fprintf(f, " Modes \"%dx%d\"\n", var.xres,
436     var.yres);
437     fprintf(f, " EndSubSection\n");
438     }
439    
440     /* To catch depth = 15, common :( */
441     if(depth == 15) {
442     fprintf(f, " SubSection \"Display\"\n");
443     fprintf(f, " Depth %d\n", depth);
444    
445     fprintf(f, " FbBpp %d\n",
446     var.bits_per_pixel);
447    
448     fprintf(f, " Modes \"%dx%d\"\n", var.xres,
449     var.yres);
450     fprintf(f, " EndSubSection\n");
451     }
452    
453     fprintf(f, "EndSection\n");
454     fprintf(f, "%s", dri_section);
455 pylon 1.2 /*** END Xorg.conf ***/
456 pylon 1.1
457     fclose(f);
458    
459 pylon 1.2 fprintf(stdout, "Wrote /etc/X11/xorg.conf\n");
460     fprintf(stdout, "Please check the configuration file for additional options\n");
461 pylon 1.1
462     return 0;
463     }

  ViewVC Help
Powered by ViewVC 1.1.20