Original post is here: eklausmeier.goip.de
Some computer monitors either do not provide correct EDID, or no EDID at all. An example monitor is LG E2340T. In this case you can provide a hand-crafted EDID file in xorg.conf
. For setting the correct screen resolution in the EDID file you can either use a hex-editor, or use below short C program.
[more_WP_Tag] The C program reads a "half-way" working EDID file and changes resolution to the required values. It does this by modifying the bytes at positions (56, 58, 59, 61) and (74, 76, 77, 79).
1// This program was written by Gordian Edenhofer on 04-May-2014
2// It is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
3// Simple EDID Manipulation Tool
4// Usage: semt [Inputfile] [X-Resolution] [Y-Resolution] [Outputfile] [Options]
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9
10int main (int argc, char *argv[]) {
11 int i, c, x_res, y_res, checksum = 0, debug=0;
12 unsigned char edid[128];
13 FILE *fp;
14
15 while ((c = getopt(argc,argv,"dvh")) != -1) {
16 // ...
17 }
18
19 if (argc-optind != 4) {
20 printf("%s: is meant to be used with the following arguments [Inputfile] [X-Resolution] [Y-Resolution] [Outputfile]\n",argv[0]);
21 return 1;
22 }
23
24 if ((fp = fopen(argv[optind],"r")) == NULL) { ... }
25 if (fread( edid, 1, 128, fp ) != 128) { ... }
26 if (fclose(fp) != 0) { ... }
27
28 x_res = atoi(argv[optind+1]);
29 y_res = atoi(argv[optind+2]);
30
31 // Dumping X-Resolution to EDID
32 edid[56] = x_res%256;
33 edid[58] = (x_res/256)*16;
34 edid[74] = x_res%256;
35 edid[76] = (x_res/256)*16;
36
37 // Dumping Y-Resolution to EDID
38 edid[59] = y_res%256;
39 edid[61] = (y_res/256)*16;
40 edid[77] = y_res%256;
41 edid[79] = (y_res/256)*16;
42 y_res = atoi(argv[optind+2]);
43
44 // Dumping X-Resolution to EDID
45 edid[56] = x_res%256;
46 edid[58] = (x_res/256)*16;
47 edid[74] = x_res%256;
48 edid[76] = (x_res/256)*16;
49
50 // Dumping Y-Resolution to EDID
51 edid[59] = y_res%256;
52 edid[61] = (y_res/256)*16;
53 edid[77] = y_res%256;
54 edid[79] = (y_res/256)*16;
55
56 // Calculating and writing the checksum
57 for (i=0; i<=126; ++i)
58 checksum += edid[i];
59 checksum %= 256;
60 edid[127] = (256-checksum)%256;
61
62 if ((fp = fopen(argv[optind+3],"w")) == NULL) { ... }
63 if (fwrite(edid,1,128,fp) != 128) { ... }
64 if (fclose(fp) != 0) { ... }
65
66 return 0;
67}
The complete source code for semt.c
is in GitHub. An example EDID file is in edid.bin
.
The difficulty was to come up with the correct bytes to change. The program parse-edid
in read-edid was a very helpful guide here. parse-edid
is contained in Debian package read-edid
.
Using the modified EDID in xorg.conf
goes like this:
Section "Screen"
Identifier "Screen0"
Device "Device0"
Monitor "Monitor0"
DefaultDepth 24
Option "CustomEDID" "CRT-1:/etc/X11/LG2.bin"
# Option "UseEdid" "False"
Option "TwinView" "0"
Option "metamodes" "1920x1080 +0+0"
SubSection "Display"
Depth 24
EndSubSection
EndSection
Section "Device"
Identifier "Device0"
# Option "NoLogo" "True"
EndSection
Use either CRT-0 or CRT-1 depending on which connector of the graphic card the monitor is plugged on.
More on EDID and fixing stuff in xorg.conf: Workaround buggy HDMI audio with EDID modification. EDID standard is here: EDID standard.
Added 12-Jul-2015: There is an AUR package for semt: aur.archlinux.org/packages/semt/.