From: Nicolas B. <nbo...@us...> - 2006-02-23 21:49:06
|
Update of /cvsroot/ddccontrol/ddccontrol/src/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31930/src/lib Modified Files: conf.c ddcci.c ddcci.h monitor_db.c monitor_db.h Log Message: Fallback to generic profiles when a monitor is not supported in the database (displaying a big warning inviting the users to send their dumps to ddccontrol-users). Index: ddcci.h =================================================================== RCS file: /cvsroot/ddccontrol/ddccontrol/src/lib/ddcci.h,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- ddcci.h 21 Sep 2005 20:45:37 -0000 1.20 +++ ddcci.h 23 Feb 2006 21:48:56 -0000 1.21 @@ -32,10 +32,29 @@ #include <time.h> #include <sys/time.h> -#include "monitor_db.h" - struct profile; +enum monitor_type { +unk = 0, +lcd = 1, +crt = 2 +}; + +/* Structure to store CAPS vcp entry (control and related values) */ +struct vcp_entry { + int values_len; /* -1 if values are not specified */ + unsigned short* values; +}; + +/* Structure to store CAPS */ +struct caps { + struct vcp_entry* vcp[256]; /* vcp entries */ + enum monitor_type type; + char* raw_caps; /* raw text caps */ +}; + +#include "monitor_db.h" + struct monitor { int fd; unsigned int addr; @@ -43,6 +62,7 @@ unsigned char digital; /* 0 - digital, 1 - analog */ struct timeval last; struct monitor_db* db; + struct caps caps; struct profile* profiles; /* profiles available for this monitor. Filled by get_all_profiles. */ @@ -53,6 +73,11 @@ #endif } type; int probing; /* are we probing? */ + + int fallback; + /* 0 - the db is designed for this monitor + 1 - we are using a manufacturer standard profile (warn the user) + 2 - we are using the VESA generic profile (warn the user) */ }; /* Struct used to return monitor data probed by ddcci_probe */ @@ -79,7 +104,9 @@ int ddcci_readctrl(struct monitor* mon, unsigned char ctrl, unsigned short *value, unsigned short *maximum); -int ddcci_caps(struct monitor* mon, unsigned char *buffer, unsigned int buflen); +int ddcci_parse_caps(const char* caps_str, struct caps* caps, int add); + +int ddcci_caps(struct monitor* mon); /* verbosity level (0 - normal, 1 - encoded data, 2 - ddc/ci frames) */ void ddcci_verbosity(int verbosity); Index: conf.c =================================================================== RCS file: /cvsroot/ddccontrol/ddccontrol/src/lib/conf.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- conf.c 14 Feb 2006 21:59:05 -0000 1.5 +++ conf.c 23 Feb 2006 21:48:56 -0000 1.6 @@ -179,8 +179,6 @@ if (!filename) return 0; - free(filename); - writer = xmlNewTextWriterFilename(filename, 0); DDCCI_RETURN_IF_RUN(writer == NULL, 0, _("Cannot create the xml writer\n"), {xmlFreeTextWriter(writer);}) Index: monitor_db.h =================================================================== RCS file: /cvsroot/ddccontrol/ddccontrol/src/lib/monitor_db.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- monitor_db.h 23 Feb 2006 12:51:08 -0000 1.11 +++ monitor_db.h 23 Feb 2006 21:48:56 -0000 1.12 @@ -21,17 +21,13 @@ #ifndef MONITOR_DB_H #define MONITOR_DB_H +#include "ddcci.h" + #include <libxml/xmlstring.h> /* Current database version */ #define DBVERSION 3 -/* Structure to store CAPS entry (control and related values) */ -struct caps_entry { - int values_len; /* -1 if values are not specified */ - unsigned short* values; -}; - enum control_type { value = 0, command = 1, @@ -88,12 +84,10 @@ xmlChar* name; enum init_type init; - struct caps_entry* caps[256]; /* CAPS */ - struct group_db* group_list; }; -struct monitor_db* ddcci_create_db(const char* pnpname, const char* default_caps, int faulttolerance); +struct monitor_db* ddcci_create_db(const char* pnpname, struct caps* caps, int faulttolerance); void ddcci_free_db(struct monitor_db* mon_db); int ddcci_init_db(char* usedatadir); Index: monitor_db.c =================================================================== RCS file: /cvsroot/ddccontrol/ddccontrol/src/lib/monitor_db.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- monitor_db.c 23 Feb 2006 12:51:08 -0000 1.29 +++ monitor_db.c 23 Feb 2006 21:48:56 -0000 1.30 @@ -47,121 +47,6 @@ int get_verbosity(); /* Defined in ddcci.c */ -/* See documentation Appendix D. - * Returns : - * -1 if an error occured - * number of controls added - * - * add: if true: add caps_str to caps, otherwise remove caps_str from the caps. - */ -int ddcci_parse_caps(const char* caps_str, struct caps_entry** caps, int add) -{ -// printf("Parsing CAPS (%s).\n", caps_str); - int pos = 0; /* position in caps_str */ - - int level = 0; /* CAPS parenthesis level */ - int vcp = 0; /* Current CAPS section is vcp */ - - char buf[8]; - char* endptr; - int ind = -1; - long val = -1; - int i; - int removeprevious = 0; - - int num = 0; - - for (pos = 0; caps_str[pos] != 0; pos++) - { - if (caps_str[pos] == '(') { - level++; - } - else if (caps_str[pos] == ')') - { - level--; - if (level == 1) { - vcp = 0; - } - } - else if (caps_str[pos] != ' ') - { - if ((level == 1) && (strncmp(caps_str+pos, "vcp", 3) == 0)) { - vcp = 1; - pos += 2; - } - else if ((vcp == 1) && (level == 2)) { - if (!add && ((removeprevious == 1) || (caps[ind] && caps[ind]->values_len == 0))) { - if(caps[ind]) { - if (caps[ind]->values) { - free(caps[ind]->values); - } - free(caps[ind]); - caps[ind] = NULL; - } - } - buf[0] = caps_str[pos]; - buf[1] = caps_str[++pos]; - buf[2] = 0; - ind = strtol(buf, &endptr, 16); - DDCCI_RETURN_IF(*endptr != 0, -1, _("Can't convert value to int, invalid CAPS.")); - if (add) { - caps[ind] = malloc(sizeof(struct caps_entry)); - caps[ind]->values_len = -1; - caps[ind]->values = NULL; - } - else { - removeprevious = 1; - } - num++; - } - else if ((vcp == 1) && (level == 3)) { - i = 0; - while ((caps_str[pos+i] != ' ') && (caps_str[pos+i] != ')')) { - buf[i] = caps_str[pos+i]; - i++; - } - buf[i] = 0; - val = strtol(buf, &endptr, 16); - DDCCI_RETURN_IF(*endptr != 0, -1, _("Can't convert value to int, invalid CAPS.")); - if (add) { - if (caps[ind]->values_len == -1) { - caps[ind]->values_len = 1; - } - else { - caps[ind]->values_len++; - } - caps[ind]->values = realloc(caps[ind]->values, caps[ind]->values_len*sizeof(unsigned short)); - caps[ind]->values[caps[ind]->values_len-1] = val; - } - else { - if (caps[ind]->values_len > 0) { - removeprevious = 0; - int j = 0; - for (i = 0; i < caps[ind]->values_len; i++) { - if (caps[ind]->values[i] != val) { - caps[ind]->values[j++] = caps[ind]->values[i]; - } - } - caps[ind]->values_len--; - } - } - } - } - } - - if (!add && ((removeprevious == 1) || (caps[ind] && caps[ind]->values_len == 0))) { - if(caps[ind]) { - if (caps[ind]->values) { - free(caps[ind]->values); - } - free(caps[ind]); - caps[ind] = NULL; - } - } - - return num; -} - /* End of CAPS structs/functions */ int ddcci_get_value_list(xmlNodePtr options_control, xmlNodePtr mon_control, struct control_db *current_control, int command, int faulttolerance) @@ -281,7 +166,7 @@ } int ddcci_add_controls_to_subgroup(xmlNodePtr control, xmlNodePtr mon_control, - struct subgroup_db *current_group, struct caps_entry** caps, char* defined, char *matchedcontrols, int faulttolerance) { + struct subgroup_db *current_group, struct vcp_entry** vcp, char* defined, char *matchedcontrols, int faulttolerance) { xmlNodePtr cur; xmlChar *mon_ctrlid; xmlChar *options_ctrlid, *options_ctrlname; @@ -349,7 +234,7 @@ matchedcontrols[i] = 1; - if (caps[current_control->address] == NULL) { + if (vcp[current_control->address] == NULL) { if (get_verbosity()) { printf(_("Control %s has been discarded by the caps string.\n"), options_ctrlid); } @@ -447,7 +332,7 @@ * prof_caps: CAPS read from one of the profile (NULL if none has been read yet) */ int ddcci_create_db_protected( - struct monitor_db* mon_db, const char* pnpname, int recursionlevel, + struct monitor_db* mon_db, const char* pnpname, struct caps* caps, int recursionlevel, char* defined, int faulttolerance) { xmlDocPtr mon_doc; @@ -579,9 +464,9 @@ xmlChar* add = xmlGetProp(mon_child, BAD_CAST "add"); DDCCI_DB_RETURN_IF(!remove && !add, 0, _("Can't find add or remove property in caps."), mon_child); if (remove) - DDCCI_DB_RETURN_IF(ddcci_parse_caps(remove, mon_db->caps, 0) <= 0, 0, _("Invalid remove caps."), mon_child); + DDCCI_DB_RETURN_IF(ddcci_parse_caps(remove, caps, 0) <= 0, 0, _("Invalid remove caps."), mon_child); if (add) - DDCCI_DB_RETURN_IF(ddcci_parse_caps(add, mon_db->caps, 1) <= 0, 0, _("Invalid add caps."), mon_child); + DDCCI_DB_RETURN_IF(ddcci_parse_caps(add, caps, 1) <= 0, 0, _("Invalid add caps."), mon_child); } else if (!xmlStrcmp(mon_child->name, (const xmlChar *) "include")) { controls_or_include = 1; @@ -593,7 +478,7 @@ xmlChar* file = xmlGetProp(mon_child, BAD_CAST "file"); DDCCI_DB_RETURN_IF(file == NULL, 0, _("Can't find file property."), mon_child); - if (!ddcci_create_db_protected(mon_db, file, recursionlevel+1, defined, faulttolerance)) { + if (!ddcci_create_db_protected(mon_db, file, caps, recursionlevel+1, defined, faulttolerance)) { xmlFree(file); return 0; } @@ -646,7 +531,7 @@ control = subgroup->xmlChildrenNode; DDCCI_DB_RETURN_IF( - !ddcci_add_controls_to_subgroup(control, mon_control, current_subgroup, mon_db->caps, + !ddcci_add_controls_to_subgroup(control, mon_control, current_subgroup, caps->vcp, defined, matchedcontrols, faulttolerance), 0, _("Error enumerating controls in subgroup."), control); current_subgroup = current_subgroup->next; } @@ -718,18 +603,16 @@ * - 0 : fail on every database error " - 1 : do not fail on minor errors */ -struct monitor_db* ddcci_create_db(const char* pnpname, const char* default_caps, int faulttolerance) +struct monitor_db* ddcci_create_db(const char* pnpname, struct caps* caps, int faulttolerance) { struct monitor_db* mon_db = malloc(sizeof(struct monitor_db)); memset(mon_db, 0, sizeof(struct monitor_db)); - ddcci_parse_caps(default_caps, mon_db->caps, 1); - /* defined controls, when including another file, we don't define the same control 2 times. */ char defined[256]; memset(defined, 0, 256*sizeof(char)); - if (!ddcci_create_db_protected(mon_db, pnpname, 0, defined, faulttolerance)) { + if (!ddcci_create_db_protected(mon_db, pnpname, caps, 0, defined, faulttolerance)) { free(mon_db); mon_db = NULL; } @@ -805,16 +688,6 @@ free(ogroup); } - int i; - for (i = 0; i < 256; i++) { - if(monitor->caps[i]) { - if (monitor->caps[i]->values) { - free(monitor->caps[i]->values); - } - free(monitor->caps[i]); - } - } - free(monitor); } Index: ddcci.c =================================================================== RCS file: /cvsroot/ddccontrol/ddccontrol/src/lib/ddcci.c,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- ddcci.c 22 Feb 2006 13:27:07 -0000 1.30 +++ ddcci.c 23 Feb 2006 21:48:56 -0000 1.31 @@ -559,6 +559,139 @@ return -1; } +/* See documentation Appendix D. + * Returns : + * -1 if an error occured + * number of controls added + * + * add: if true: add caps_str to caps, otherwise remove caps_str from the caps. + */ +int ddcci_parse_caps(const char* caps_str, struct caps* caps, int add) +{ +// printf("Parsing CAPS (%s).\n", caps_str); + int pos = 0; /* position in caps_str */ + + int level = 0; /* CAPS parenthesis level */ + int svcp = 0; /* Current CAPS section is vcp */ + int stype = 0; /* Current CAPS section is type */ + + char buf[8]; + char* endptr; + int ind = -1; + long val = -1; + int i; + int removeprevious = 0; + + int num = 0; + + for (pos = 0; caps_str[pos] != 0; pos++) + { + if (caps_str[pos] == '(') { + level++; + } + else if (caps_str[pos] == ')') + { + level--; + if (level == 1) { + svcp = 0; + stype = 0; + } + } + else if (caps_str[pos] != ' ') + { + if (level == 1) { + if (strncmp(caps_str+pos, "vcp", 3) == 0) { + svcp = 1; + pos += 2; + } + else if (strncmp(caps_str+pos, "type", 4) == 0) { + stype = 1; + pos += 3; + } + } + else if ((stype == 1) && (level == 2)) { + if (strncmp(caps_str+pos, "lcd", 3) == 0) { + caps->type = lcd; + pos += 2; + } + else if (strncmp(caps_str+pos, "crt", 3) == 0) { + caps->type = crt; + pos += 2; + } + } + else if ((svcp == 1) && (level == 2)) { + if (!add && ((removeprevious == 1) || (caps->vcp[ind] && caps->vcp[ind]->values_len == 0))) { + if(caps->vcp[ind]) { + if (caps->vcp[ind]->values) { + free(caps->vcp[ind]->values); + } + free(caps->vcp[ind]); + caps->vcp[ind] = NULL; + } + } + buf[0] = caps_str[pos]; + buf[1] = caps_str[++pos]; + buf[2] = 0; + ind = strtol(buf, &endptr, 16); + DDCCI_RETURN_IF(*endptr != 0, -1, _("Can't convert value to int, invalid CAPS.")); + if (add) { + caps->vcp[ind] = malloc(sizeof(struct vcp_entry)); + caps->vcp[ind]->values_len = -1; + caps->vcp[ind]->values = NULL; + } + else { + removeprevious = 1; + } + num++; + } + else if ((svcp == 1) && (level == 3)) { + i = 0; + while ((caps_str[pos+i] != ' ') && (caps_str[pos+i] != ')')) { + buf[i] = caps_str[pos+i]; + i++; + } + buf[i] = 0; + val = strtol(buf, &endptr, 16); + DDCCI_RETURN_IF(*endptr != 0, -1, _("Can't convert value to int, invalid CAPS.")); + if (add) { + if (caps->vcp[ind]->values_len == -1) { + caps->vcp[ind]->values_len = 1; + } + else { + caps->vcp[ind]->values_len++; + } + caps->vcp[ind]->values = realloc(caps->vcp[ind]->values, caps->vcp[ind]->values_len*sizeof(unsigned short)); + caps->vcp[ind]->values[caps->vcp[ind]->values_len-1] = val; + } + else { + if (caps->vcp[ind]->values_len > 0) { + removeprevious = 0; + int j = 0; + for (i = 0; i < caps->vcp[ind]->values_len; i++) { + if (caps->vcp[ind]->values[i] != val) { + caps->vcp[ind]->values[j++] = caps->vcp[ind]->values[i]; + } + } + caps->vcp[ind]->values_len--; + } + } + } + } + } + + if (!add && ((removeprevious == 1) || (caps->vcp[ind] && caps->vcp[ind]->values_len == 0))) { + if(caps->vcp[ind]) { + if (caps->vcp[ind]->values) { + free(caps->vcp[ind]->values); + } + free(caps->vcp[ind]); + caps->vcp[ind] = NULL; + } + } + + return num; +} + /* read capabilities raw data of ddc/ci at address addr starting at offset to buf */ static int ddcci_raw_caps(struct monitor* mon, unsigned int offset, unsigned char *buf, unsigned char len) { @@ -576,8 +709,9 @@ return ddcci_read(mon, buf, len); } -int ddcci_caps(struct monitor* mon, unsigned char *buffer, unsigned int buflen) +int ddcci_caps(struct monitor* mon) { + mon->caps.raw_caps = (char*)malloc(16); int bufferpos = 0; unsigned char buf[64]; /* 64 bytes chunk (was 35, but 173P+ send 43 bytes chunks) */ int offset = 0; @@ -585,7 +719,7 @@ int retries = 3; do { - buffer[bufferpos] = 0; + mon->caps.raw_caps[bufferpos] = 0; if (retries == 0) { return -1; } @@ -605,14 +739,9 @@ continue; } + mon->caps.raw_caps = (char*)realloc(mon->caps.raw_caps, bufferpos + len - 2); for (i = 3; i < len; i++) { - buffer[bufferpos++] = buf[i]; - if (bufferpos >= buflen) { - if (!mon->probing || verbosity) { - fprintf(stderr, _("Buffer too small to contain caps.\n")); - } - return -1; - } + mon->caps.raw_caps[bufferpos++] = buf[i]; } offset += len - 3; @@ -620,7 +749,9 @@ retries = 3; } while (len != 3); - buffer[bufferpos] = 0; + mon->caps.raw_caps[bufferpos] = 0; + + ddcci_parse_caps(mon->caps.raw_caps, &mon->caps, 1); return bufferpos; } @@ -749,37 +880,45 @@ return -2; } - unsigned char buf[1024]; - - if (ddcci_caps(mon, buf, 1024) > -1) { - mon->db = ddcci_create_db(mon->pnpid, buf, 1); - } - else { - mon->db = ddcci_create_db(mon->pnpid, "", 1); - } + ddcci_caps(mon); + mon->db = ddcci_create_db(mon->pnpid, &mon->caps, 1); + mon->fallback = 0; /* No fallback */ - if (mon->db) { - if (mon->db->init == samsung) { - if (ddcci_writectrl(mon, DDCCI_CTRL, DDCCI_CTRL_ENABLE, 0) < 0) { - return -1; - } + if (!mon->db) { + /* Fallback on manufacturer generic profile */ + char buffer[7]; + buffer[0] = 0; + strncat(buffer, mon->pnpid, 3); /* copy manufacturer id */ + switch(mon->caps.type) { + case lcd: + strcat(buffer, "lcd"); + mon->db = ddcci_create_db(buffer, &mon->caps, 1); + mon->fallback = 1; + break; + case crt: + strcat(buffer, "crt"); + mon->db = ddcci_create_db(buffer, &mon->caps, 1); + mon->fallback = 1; + break; + case unk: + break; } - else { - if (ddcci_command(mon, DDCCI_COMMAND_PRESENCE) < 0) { - return -1; - } + + if (!mon->db) { + /* Fallback on VESA generic profile */ + mon->db = ddcci_create_db("VESA", &mon->caps, 1); + mon->fallback = 2; } } - else { /* Alternate way of init mode detecting for unsupported monitors */ - if (strncmp(mon->pnpid, "SAM", 3) == 0) { - if (ddcci_writectrl(mon, DDCCI_CTRL, DDCCI_CTRL_ENABLE, 0) < 0) { - return -1; - } + + if ((mon->db) && (mon->db->init == samsung)) { + if (ddcci_writectrl(mon, DDCCI_CTRL, DDCCI_CTRL_ENABLE, 0) < 0) { + return -1; } - else { - if (ddcci_command(mon, DDCCI_COMMAND_PRESENCE) < 0) { - return -1; - } + } + else { + if (ddcci_command(mon, DDCCI_COMMAND_PRESENCE) < 0) { + return -1; } } @@ -821,6 +960,16 @@ } } + int i; + for (i = 0; i < 256; i++) { + if(mon->caps.vcp[i]) { + if (mon->caps.vcp[i]->values) { + free(mon->caps.vcp[i]->values); + } + free(mon->caps.vcp[i]); + } + } + if (mon->profiles) { ddcci_free_profile(mon->profiles); } |