diff --git a/.gitignore b/.gitignore index cd531cf..56048a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ # ---> C +#vim +*.swp + # Prerequisites *.d diff --git a/edid_stockach.json b/edid_stockach.json index d51df62..a4dee2b 100644 --- a/edid_stockach.json +++ b/edid_stockach.json @@ -10,11 +10,28 @@ }, "video_input_parameters": { "input_type": "analog", - "levels": 3, + "levels": { + "upper": 0.7, + "lower": 0.0 + }, "blank_to_black": false, "seperate_sync": true, "composite_sync": false, "sync_on_green": false, - "vsync_serrated": false + "vsync_serrated": false, + "horizontal_screen_size": 53, + "vertical_screen_size": 30, + "gamma": 2.2, + "features": { + "dpms": { + "standby_supported": true, + "suspend_supported": true, + "active_off_supported": true + }, + "display_type": "analog_non_rgb_color", + "standard_srgb": false, + "preferred_timing_mode": true, + "continuous_timings": false + } } -} \ No newline at end of file +} diff --git a/edid.json b/edid_wädi.json similarity index 94% rename from edid.json rename to edid_wädi.json index e2a46e8..fca701f 100644 --- a/edid.json +++ b/edid_wädi.json @@ -20,7 +20,7 @@ "sync_on_green": true, "vsync_serrated": false, "horizontal_screen_size": 38, - "vertical_screen_size": 30 + "vertical_screen_size": 30, "gamma": 2.2 } } diff --git a/main b/main new file mode 100755 index 0000000..0eb9f1d Binary files /dev/null and b/main differ diff --git a/main.c b/main.c index 1f0d722..5fca178 100644 --- a/main.c +++ b/main.c @@ -9,6 +9,12 @@ #define EDID_BYTES_OFFSET_HEADER_MANUFACTURER_ID 8 #define EDID_BYTES_OFFSET_HEADER_PRODUCT_CODE 10 +enum edid_analog_display_t { + EDID_DISPLAY_TYPE_MONOCHROME_OR_GRAYSCALE = 0, + EDID_DISPLAY_TYPE_RGB_COLOR = 1, + EDID_DISPLAY_TYPE_NON_RGB_COLOR = 2, + EDID_DISPLAY_TYPE_UNDEFINED = 3 +}; typedef struct __attribute__ (( packed )) { uint8_t resolution; @@ -46,17 +52,17 @@ typedef struct __attribute__ (( packed )) { uint8_t input_type : 1; // 0 for analog } analog; } video_input_parameters; // 1 byte - uint8_t h_screen_size; - uint8_t v_screen_size; + uint8_t horizontal_screen_size; + uint8_t vertical_screen_size; uint8_t gamma; struct __attribute__ (( packed )) { - uint8_t dpms_standby : 1; - uint8_t dpms_suspend : 1; - uint8_t dpms_active_off : 1; - uint8_t display_type : 2; - uint8_t standard_srgb : 1; - uint8_t preferred_timing_mode : 1; - uint8_t continuous_timings : 1; + uint8_t continuous_timings : 1; + uint8_t preferred_timing_mode : 1; + uint8_t standard_srgb : 1; + uint8_t display_type : 2; + uint8_t dpms_active_off_supported : 1; + uint8_t dpms_suspend_supported : 1; + uint8_t dpms_standby_supported : 1; } features; } basic_display_parameters; /*! Chromaticity coordinates. 10-bit CIE 1931 xy coordinates for red, green, @@ -187,6 +193,8 @@ static int generate_header(edid_t* edid, unsigned char* json_str, size_t json_le ID.\n"); return 1; } + // %Q mallocs a string + free(multi_use_str); // Product code json_scanf(json_str, json_len, "{header: {product_code: %d}", &multi_use_int); edid->header.product_code = 0xFFFF & multi_use_int; @@ -214,9 +222,9 @@ static int generate_header(edid_t* edid, unsigned char* json_str, size_t json_le return 0; } -static int generate_video_input_parameters( edid_t* edid, - unsigned char* json_str, - size_t json_len) +static int generate_basic_display_parameters( edid_t* edid, + unsigned char* json_str, + size_t json_len) { char* multi_use_str; float multi_use_flt0; @@ -232,10 +240,12 @@ static int generate_video_input_parameters( edid_t* edid, edid->basic_display_parameters.video_input_parameters .analog.input_type = 0; // Levels - json_scanf( json_str, json_len, "{video_input_parameters: {levels: {upper: %f}}}", - &multi_use_flt0); - json_scanf( json_str, json_len, "{video_input_parameters: {levels: {lower: %f}}}", - &multi_use_flt1); + json_scanf( json_str, json_len, + "{video_input_parameters: {levels: {upper: %f}}}", + &multi_use_flt0); + json_scanf( json_str, json_len, + "{video_input_parameters: {levels: {lower: %f}}}", + &multi_use_flt1); if (multi_use_flt0 == 0.7f && multi_use_flt1 == -0.3f) { multi_use_int = 0; } else if (multi_use_flt0 == 0.714f && multi_use_flt1 == -0.286f) { @@ -248,36 +258,35 @@ static int generate_video_input_parameters( edid_t* edid, printf("Error: The levels %f/%f are not conforming to the standard.\n", multi_use_flt0, multi_use_flt1); } - printf("level> %d\n", multi_use_int); edid->basic_display_parameters.video_input_parameters .analog.levels = 0x3 & multi_use_int; // Blank to black json_scanf( json_str, json_len, - "{video_input_parameters: {blank_to_black: %B}", + "{video_input_parameters: {blank_to_black: %B}}", &multi_use_bool); edid->basic_display_parameters.video_input_parameters .analog.blank_to_black = 0x1 & multi_use_bool; // Seperate sync json_scanf( json_str, json_len, - "{video_input_parameters: {seperate_sync: %B}", + "{video_input_parameters: {seperate_sync: %B}}", &multi_use_bool); edid->basic_display_parameters.video_input_parameters .analog.seperate_sync = 0x1 & multi_use_bool; // Composite sync json_scanf( json_str, json_len, - "{video_input_parameters: {composite_sync: %B}", + "{video_input_parameters: {composite_sync: %B}}", &multi_use_bool); edid->basic_display_parameters.video_input_parameters .analog.composite_sync = 0x1 & multi_use_bool; // Sync on green json_scanf( json_str, json_len, - "{video_input_parameters: {sync_on_green: %B}", + "{video_input_parameters: {sync_on_green: %B}}", &multi_use_bool); edid->basic_display_parameters.video_input_parameters .analog.sync_on_green = 0x1 & multi_use_bool; // Vsync serrated json_scanf( json_str, json_len, - "{video_input_parameters: {blank_to_black: %B}", + "{video_input_parameters: {blank_to_black: %B}}", &multi_use_bool); edid->basic_display_parameters.video_input_parameters .analog.blank_to_black = 0x1 & multi_use_bool; @@ -289,9 +298,107 @@ static int generate_video_input_parameters( edid_t* edid, the video input params.\n"); return 2; } + // %Q mallocs a string + free(multi_use_str); + // Horizontal screen size + json_scanf( json_str, json_len, + "{video_input_parameters: {horizontal_screen_size: %d}}", + &multi_use_int); + edid->basic_display_parameters + .horizontal_screen_size = multi_use_int; + // Vertical screen size + json_scanf( json_str, json_len, + "{video_input_parameters: {vertical_screen_size: %d}}", + &multi_use_int); + edid->basic_display_parameters + .vertical_screen_size = multi_use_int; + // Horizontal screen size + json_scanf( json_str, json_len, + "{video_input_parameters: {gamma: %f}}", + &multi_use_flt0); + edid->basic_display_parameters + .gamma = (multi_use_flt0-1)*100; + // Display Power Management Signaling (DPMS) + // Standby + json_scanf( json_str, json_len, + "{video_input_parameters: {features: {dpms: \ + {standby_supported: %B}}}}", + &multi_use_bool); + edid->basic_display_parameters + .features.dpms_standby_supported = 0x1 & multi_use_bool; + // Suspend + json_scanf( json_str, json_len, + "{video_input_parameters: {features: {dpms: \ + {suspend_supported: %B}}}}", + &multi_use_bool); + edid->basic_display_parameters + .features.dpms_suspend_supported = 0x1 & multi_use_bool; + // Active-off + json_scanf( json_str, json_len, + "{video_input_parameters: {features: {dpms: \ + {active_off_supported: %B}}}}", + &multi_use_bool); + edid->basic_display_parameters + .features.dpms_active_off_supported = 0x1 & multi_use_bool; + // Display type + char a_str[] = "analog"; + char d_str[] = "digital"; + json_scanf( json_str, json_len, + "{video_input_parameters: {features: {display_type: %Q}}}", + &multi_use_str); + // Create substrings for comparison + memcpy(a_str, multi_use_str, strlen(a_str)); + memcpy(d_str, multi_use_str, strlen(d_str)); + if (strcmp(a_str, "analog") == 0) { + // Remove "analog_" + memcpy( multi_use_str, multi_use_str+strlen(a_str)+1, + strlen(multi_use_str)-strlen(a_str)); + if (strcmp(multi_use_str, "monochrome_or_grayscale") == 0) { + edid->basic_display_parameters + .features.display_type = 0x3 & EDID_DISPLAY_TYPE_MONOCHROME_OR_GRAYSCALE; + } else if (strcmp(multi_use_str, "rgb_color") == 0) { + edid->basic_display_parameters + .features.display_type = 0x3 & ~EDID_DISPLAY_TYPE_RGB_COLOR; + } else if (strcmp(multi_use_str, "non_rgb_color") == 0) { + edid->basic_display_parameters + .features.display_type = 0x3 & ~EDID_DISPLAY_TYPE_NON_RGB_COLOR; + } else if (strcmp(multi_use_str, "undefined") == 0) { + edid->basic_display_parameters + .features.display_type = 0x3 & EDID_DISPLAY_TYPE_UNDEFINED; + } else { + printf("Error: Unknown analog display_type.\n"); + return 3; + } + } else if (strcmp(d_str, "digital") == 0) { + printf("Error: Digital format is not supported yet.\n"); + return 4; + } else { + printf("Error: JSON format is wrong. First word needs of display_type \ + should either be analog or digital.\n"); + } + // %Q mallocs a string, which needs to be freed + free(multi_use_str); + // Standard sRGB + json_scanf( json_str, json_len, + "{video_input_parameters: {features: {standard_srgb: %B}}}", + &multi_use_bool); + edid->basic_display_parameters + .features.standard_srgb = 0x1 & multi_use_bool; + // Prefered timing mode + json_scanf( json_str, json_len, + "{video_input_parameters: {features: {preferred_timing_mode: %B}}}", + &multi_use_bool); + edid->basic_display_parameters + .features.preferred_timing_mode = 0x1 & multi_use_bool; + // Continuous timings + json_scanf( json_str, json_len, + "{video_input_parameters: {features: {continuous_timings: %B}}}", + &multi_use_bool); + edid->basic_display_parameters + .features.continuous_timings = 0x1 & multi_use_bool; } else { - printf("One of either edid or json_str is NULL.\n"); - return 3; + printf("Error: One of either edid or json_str is NULL.\n"); + return 5; } return 0; } @@ -304,14 +411,14 @@ int main(void) printf("size> %d bytes\n", sizeof(edith)); generate_preamble(&edith); unsigned char* mystr = NULL; - size_t len = file_to_str(&mystr, "edid.json"); + size_t len = file_to_str(&mystr, "edid_stockach.json"); if (mystr) { printf("%s\n", mystr); printf("len> %d\n", len); //free(mystr); } generate_header(&edith, mystr, len); - generate_video_input_parameters(&edith, mystr, len); + generate_basic_display_parameters(&edith, mystr, len); disp_buf((uint8_t*)&edith, EDID_LENGTH); return 0; }