Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ddcutil-service for openSUSE:Factory checked in at 2024-08-22 18:13:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ddcutil-service (Old) and /work/SRC/openSUSE:Factory/.ddcutil-service.new.2698 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ddcutil-service" Thu Aug 22 18:13:46 2024 rev:8 rq:1195209 version:1.0.11 Changes: -------- --- /work/SRC/openSUSE:Factory/ddcutil-service/ddcutil-service.changes 2024-06-14 19:07:06.250459408 +0200 +++ /work/SRC/openSUSE:Factory/.ddcutil-service.new.2698/ddcutil-service.changes 2024-08-22 18:14:09.599879262 +0200 @@ -1,0 +2,10 @@ +Thu Aug 22 01:18:47 UTC 2024 - Michael Hamilton <mich...@actrix.gen.nz> + +- 1.0.11 + - Alter the detect-function for ddcutil 2.5.1 (generates more logging/warning info). + - Add a DETECT_ALL option to control whether disabled/powered-off VDU's are to be included in the results from detect. + - Reduce the number of messages generated when polling for hotplug events. + - Fixes to API documentation. + + +------------------------------------------------------------------- Old: ---- ddcutil-service-1.0.9.tar.gz New: ---- ddcutil-service-1.0.11.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ddcutil-service.spec ++++++ --- /var/tmp/diff_new_pack.G8kss2/_old 2024-08-22 18:14:10.355910707 +0200 +++ /var/tmp/diff_new_pack.G8kss2/_new 2024-08-22 18:14:10.359910873 +0200 @@ -18,7 +18,7 @@ Name: ddcutil-service -Version: 1.0.9 +Version: 1.0.11 Release: 0 Summary: D-Bus service for libddcutil VESA DDC Monitor Virtual Control Panel License: GPL-2.0-or-later ++++++ ddcutil-service-1.0.9.tar.gz -> ddcutil-service-1.0.11.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ddcutil-service-1.0.9/Makefile new/ddcutil-service-1.0.11/Makefile --- old/ddcutil-service-1.0.9/Makefile 2024-06-14 03:32:23.000000000 +0200 +++ new/ddcutil-service-1.0.11/Makefile 2024-08-22 03:59:06.000000000 +0200 @@ -5,7 +5,7 @@ CFLAGS_DDCUTIL = $(shell pkg-config --cflags --libs ddcutil) # Uncomment to compile against a developer local libddcutil #CFLAGS_DDCUTIL = -isystem $(HOME)/Downloads/ddcutil-2.1.5-dev/src/public -L $(HOME)/Downloads/ddcutil-2.1.5-dev/src/.libs -lddcutil -CFLAGS_DDCUTIL = -isystem $(HOME)/Downloads/ddcutil-2.1.5-dev-clion/build/src/public -isystem $(HOME)/Downloads/ddcutil-2.1.5-dev-clion/src/public -L $(HOME)/Downloads/ddcutil-2.1.5-dev-clion/build/src/.libs -lddcutil +#CFLAGS_DDCUTIL = -isystem $(HOME)/Downloads/ddcutil-2.1.5-dev-clion/build/src/public -isystem $(HOME)/Downloads/ddcutil-2.1.5-dev-clion/src/public -L $(HOME)/Downloads/ddcutil-2.1.5-dev-clion/build/src/.libs -lddcutil #CFLAGS_DDCUTIL = -isystem $(HOME)/Downloads/ddcutil-2.1.4-dev/src/public -L $(HOME)/Downloads/ddcutil-2.1.4-dev/src/.libs -lddcutil #CFLAGS_DDCUTIL = -isystem $(HOME)/Downloads/ddcutil-2.0.0/src/public -L $(HOME)/Downloads/ddcutil-2.0.0/src/.libs -lddcutil @@ -22,7 +22,7 @@ SERVICE_FILE = com.ddcutil.DdcutilService.service SERVICES_DIR = $(PREFIX)/share/dbus-1/services -all: $(SOURCE) $(EXE) $(HTML) +all: $(SOURCE) $(EXE) $(CLIENT_EXE) $(HTML) $(EXE): $(SOURCE) gcc $< -o $@ $(CFLAGS) $(CFLAGS_GIO) $(CFLAGS_DDCUTIL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ddcutil-service-1.0.9/README.md new/ddcutil-service-1.0.11/README.md --- old/ddcutil-service-1.0.9/README.md 2024-06-14 03:32:23.000000000 +0200 +++ new/ddcutil-service-1.0.11/README.md 2024-08-22 03:59:06.000000000 +0200 @@ -17,7 +17,7 @@ 4. click on `com.ddcutil.DdcutilService` 5. open the *Object Path* `com/ddcutil/DdcutilService` and navigate down to the `com.ddcutil.DdcutilInterface` -7. Double-click methods and properties to run or view them. +6. Double-click methods and properties to run or view them. Method inputs can be supplied as CSV, for example, Method Input to `GetVcp` could be @@ -30,7 +30,7 @@ Several bash and python scripts that demonstrate using the service are included in the [examples](https://github.com/digitaltrails/ddcutil-service/tree/master/examples) -folder. They cover the use of the `dbus-send` command line utiltity +folder. They cover the use of the `dbus-send` command line utility and the python `dasbus` and `QtDBus` libraries. The service was developed with the assistance of amendments to [libddcutil](https://www.ddcutil.com/) by @rockowitz. @@ -64,7 +64,7 @@ - https://software.opensuse.org/package/ddcutil-service -The same page also provides links to unoffical builds I've done for Leap. +The same page also provides links to unofficial builds I've done for Leap. ##### AUR (Arch Linux User Repository): @@ -121,7 +121,7 @@ man page `ddcutil-client.1`). Packaging and deployment of the client is optional. If `busctl` or `dbus-send` is available, they will be about as fast. A purpose built client is mostly a convenience for those that might -want a syntatically straight forward command line interface. +want a syntactically straight forward command line interface. ### Acknowledgements @@ -139,6 +139,11 @@ granting the [Open Source development license]( https://jb.gg/OpenSourceSupport). ### Version History +- 1.0.11 + - Alter the detect-function for ddcutil 2.5.1 (generates more logging/warning info). + - Add a DETECT_ALL option to control whether disabled/powered-off VDU's are to be included in the results from detect. + - Reduce the number of messages generated when polling for hotplug events. + - Fixes to API documentation. - 1.0.9 - Fixed a GetCapabilitiesMetadata bug that caused some VCP features to lack metadata values. - Fixed the return of feature-name and feature-description from GetVcpMetadata. @@ -165,7 +170,7 @@ - 1.0.3 - Reduce unnecessary logging. - Improve the description of the service's signals in ddcutil-service.1. - - Correct the typo in option name --perfer-drm (it was mistakenly called --prefer-dma). + - Correct the typo in option name --prefer-drm (it was mistakenly called --prefer-dma). - For simple VCP-features, only return the low-byte, for some VDUs the high-byte might contain junk. - 1.0.2 - Added VcpValueChanged D-Bus signal which triggers if the SetVcp method succeeds. This is to allow diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ddcutil-service-1.0.9/ddcutil-client.1 new/ddcutil-service-1.0.11/ddcutil-client.1 --- old/ddcutil-service-1.0.9/ddcutil-client.1 2024-06-14 03:32:23.000000000 +0200 +++ new/ddcutil-service-1.0.11/ddcutil-client.1 2024-08-22 03:59:06.000000000 +0200 @@ -56,6 +56,43 @@ .B \-r, \-\-raw Force getvcp to return SNC-features as raw 16-bit values (SNCs default to 8-bit bits). .TP +.B \-v, --version +Query the service interface version (property \fBServiceInterfaceVersion\fP). +.TP +.B \-V, --ddcutil-version +Query the ddcutil/libddcutil version (property \fBDdcutilVersion\fP). +.TP +.B \-y, --dynamic-sleep +Query or set ddcutil dynamic sleep setting (property \fBDdcutilDynamicSleep\fP). +.TP +.B \-i, --info-logging +Query or set info logging (property \fBServiceInfoLogging\fP). +.TP +.B \-s, --signal +Query or set service hotplug signals (property \fBServiceEmitSignals\fP). +.TP +.B \-l, --locked +Query if service parameters are locked (property \fBServiceParametersLocked\fP). +.TP +.B \-u, --status-values +List all ddcutil status values (property \fBStatusValues\fP). +.TP +.B \-p, --display-events +List all display event types (property \fBDisplayEventTypes\fP). +.TP +.B \-f, --service-flags +List all service flag options (property \fBServiceFlagOptions\fP). +.TP +.B \-t, --poll-interval +Hotplug/connectivity poll seconds >=30, 0 to query (property \fBServicePollInterval\fP). +.TP +.B \-c, --cascade-interval +Hotplug/connectivity cascade seconds >=0.5, 0 to query (property \fBServicePollCascadeInterval\fP). +.TP +.B \-o, --output-level +Ddcutil output level (property \fBDdcutilOutputLevel\fP). + +.TP If neither display number nor EDID are provided, the display number will default to 1. .SH EXAMPLES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ddcutil-service-1.0.9/ddcutil-client.c new/ddcutil-service-1.0.11/ddcutil-client.c --- old/ddcutil-service-1.0.9/ddcutil-client.c 2024-06-14 03:32:23.000000000 +0200 +++ new/ddcutil-service-1.0.11/ddcutil-client.c 2024-08-22 03:59:06.000000000 +0200 @@ -25,6 +25,7 @@ #include <glib.h> #include <stdlib.h> #include <string.h> +#include <errno.h> /** * Status numbers that might be returned from main() @@ -52,6 +53,8 @@ static char *const DBUS_OBJECT_PATH = "/com/ddcutil/DdcutilObject"; static char *const DBUS_INTERFACE_NAME = "com.ddcutil.DdcutilInterface"; +static GDBusConnection *connection = NULL; + static char *boolean_value(int bool) { return bool ? "true" : "false"; } @@ -415,12 +418,73 @@ } g_variant_iter_free(array_iter); - g_variant_unref(result); return ddcutil_status == 0 ? COMPLETED_WITHOUT_ERROR : SERVICE_ERROR; } /** + * @brief print a service property value to stdout + * @param connection open service connection + * @param property_name name of property + * @return status returned by the service + */ +static cmd_status_t print_property(GDBusConnection *connection, char *property_name) { + GVariant *result; + GVariant *property_value; + GError *error = NULL; + result = g_dbus_connection_call_sync(connection, + DBUS_BUS_NAME, + DBUS_OBJECT_PATH, + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new("(ss)", DBUS_INTERFACE_NAME, property_name), + G_VARIANT_TYPE("(v)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (error == NULL) { + g_variant_get(result, "(v)", &property_value); + gchar *property_str = g_variant_print(property_value, TRUE); + g_print("%s: %s\n", property_name, property_str); + g_free(property_str); + g_variant_unref(property_value); + g_variant_unref(result); + } + return handle_dbus_error("print_property", error); +} + +/** + * @brief set a service property value + * @param connection an open connection to the service + * @param property_name the property name to be set + * @param property_value the new value as an appropriate GVariant + * @return status returned from the service + */ +static cmd_status_t set_property(GDBusConnection *connection, char *property_name, GVariant *property_value) { + GError *error = NULL; + //GVariant *value = g_variant_new_int32(property_value); + GVariant *result = g_dbus_connection_call_sync( + connection, + DBUS_BUS_NAME, + DBUS_OBJECT_PATH, + "org.freedesktop.DBus.Properties", + "Set", + g_variant_new("(ssv)", DBUS_INTERFACE_NAME, property_name, property_value), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error + ); + if (error == NULL) { + g_variant_unref(property_value); + g_variant_unref(result); + } + return handle_dbus_error("set_property", error); +} + +/** * Parse a command line int argument using strtol * @param input_str the command line argument * @param base base, such as 10 for decimal or 16 for hex @@ -437,57 +501,122 @@ /** * Parse an validate the display number string and base64 encoded edid (combo) - * @param display_number_str display number string, may be NULL + * @param display_number_ptr display number, may be -1 if not supplied * @param edid_base64 EDID, may be the empty string - * @param display_number output integer display number * @return COMPLETED_WITHOUT_ERROR or SYNTAX_ERROR */ -static cmd_status_t parse_display_and_edid(char *display_number_str, char *edid_base64, int *display_number) { +static cmd_status_t parse_display_and_edid(gint *display_number_ptr, char *edid_base64) { if (strlen(edid_base64) > 0 && strlen(edid_base64) < 12) { g_printerr("ERROR: Invalid EDID. It must be at least 12 characters long.\n"); return SYNTAX_ERROR; } - if (display_number_str != NULL && strlen(edid_base64) > 0) { + if (*display_number_ptr != -1 && strlen(edid_base64) > 0) { g_printerr("ERROR: Pass only one of Display Number or EDID, not both.\n"); return SYNTAX_ERROR; } - if (strlen(edid_base64) > 0) { - *display_number = -1; // Using EDID + if (strlen(edid_base64) > 0) { // Using EDID g_print("edid_base64_encoded: %s\n", edid_base64); } else { // Using Display Number, default to 1 if none passed - cmd_status_t parse_status = COMPLETED_WITHOUT_ERROR; - if (display_number_str != NULL) { - int parsed_display_number = parse_int(display_number_str, 10, &parse_status); - if (parse_status != 0) { - g_printerr("ERROR: Invalid Display Number. It must be in decimal format (e.g., 1).\n"); - return parse_status; - } - *display_number = parsed_display_number; - } else { - *display_number = 1; + if (*display_number_ptr == -1) { + *display_number_ptr = 1; } - g_print("display_number: %d\n", *display_number); + g_print("display_number: %d\n", *display_number_ptr); } return COMPLETED_WITHOUT_ERROR; } +/** + * @brief Return the service property name for the command line option that gets/sets the property. + * @param option_name command line option name, may be long or short form. + * @return the service property name corresponding to option_namw, or NULL if no match was found. + */ +static char *get_service_property_name(const gchar *option_name) { + if (g_str_equal(option_name, "--info-logging") || g_str_equal(option_name, "-i")) { + return "ServiceInfoLogging"; + } else if (g_str_equal(option_name, "--signal") || g_str_equal(option_name, "-s")) { + return "ServiceEmitConnectivitySignals"; + } else if (g_str_equal(option_name, "--dynamic-sleep") || g_str_equal(option_name, "-y")) { + return "DdcutilDynamicSleep"; + } + return NULL; +} + +/** + * @brief GOptionEntry get/set callback for handling get/set boolean options on service properties + * @param option_name command line option name, might be the long or short name + * @param value new value, if setting, NULL if getting + * @param data not used (option group related) + * @param error not used + * @return TRUE if handled without error, otherwise FAlSE + */ +static gboolean handle_boolean_prop(const gchar *option_name, const gchar *value, gpointer data, GError **error) { + char *service_property_name = get_service_property_name(option_name); + if (service_property_name == NULL) { + g_printerr("ERROR: unrecognised option name %s\n", option_name); + return FALSE; + } + if (value != NULL) { + g_print("Set service property: %s\n", service_property_name); + if (g_str_equal(value, "on") || g_str_equal(value, "true") || g_str_equal(value, "enable")) { + set_property(connection, service_property_name, g_variant_new_boolean(TRUE)); + } else if (g_str_equal(value, "off") || g_str_equal(value, "false") || g_str_equal(value, "disable")) { + set_property(connection, service_property_name, g_variant_new_boolean(FALSE)); + } else { + g_printerr("ERROR: invalid value for %s, should be on/off true/false enable/disable.\n", option_name); + } + } + print_property(connection, service_property_name); + return TRUE; +} + int main(int argc, char *argv[]) { GError *error = NULL; GOptionContext *context; - gchar *display_number_str = NULL; + gint display_number = -1; gchar *edid_txt = ""; gchar **remaining_args = NULL; gint raw = 0; + gint version = 0; + gint ddversion = 0; + gint locked = 0; + gint status_values = 0; + gint display_event_types = 0; + gint service_flag_options = 0; + gint poll_interval = -1; + double cascade_interval = DBL_MAX; + gint output_level = -2; + gint attributes_detect = 0; + + connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); + if (!connection) { + g_printerr("ERROR: Error connecting to session bus: %s\n", error->message); + g_error_free(error); + return DBUS_ERROR; + } GOptionEntry entries[] = { - {"display", 'd', 0, G_OPTION_ARG_STRING, &display_number_str, "Display number", "DISPLAY_NUMBER"}, - {"edid", 'e', 0, G_OPTION_ARG_STRING, &edid_txt, "EDID", "EDID"}, - {"raw", 'r', 0, G_OPTION_ARG_NONE, &raw, "getvcp returns SNC-features as raw 16-bit values", NULL}, - {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining_args, NULL, NULL}, + {"display", 'd', 0, G_OPTION_ARG_INT, &display_number, "Display number"}, + {"edid", 'e', 0, G_OPTION_ARG_STRING, &edid_txt, "EDID"}, + {"raw", 'r', 0, G_OPTION_ARG_NONE, &raw, "getvcp returns SNC-features as raw 16-bit values"}, + {"version", 'v', 0, G_OPTION_ARG_NONE, &version, "query the service interface version"}, + {"ddcutil-version", 'V', 0, G_OPTION_ARG_NONE, &ddversion, "query the ddcutil/libddcutil version"}, + {"dynamic-sleep", 'y', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, &handle_boolean_prop, "query or set ddcutil dynamic sleep"}, + {"info-logging", 'i', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, &handle_boolean_prop, "query or set info logging"}, + {"signal", 's', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, &handle_boolean_prop, "query or set service hotplug signals"}, + {"locked", 'l', 0, G_OPTION_ARG_NONE, &locked, "query if service parameters are locked"}, + {"attributes-detect",'a', 0, G_OPTION_ARG_NONE, &attributes_detect, "list all attributes returned by detect"}, + {"status-values", 'u', 0, G_OPTION_ARG_NONE, &status_values, "list all ddcutil status values"}, + {"display-events", 'p', 0, G_OPTION_ARG_NONE, &display_event_types, "list all display event types"}, + {"service-flags", 'f', 0, G_OPTION_ARG_NONE, &service_flag_options, "list all service flag options"}, + {"poll-interval", 't', 0, G_OPTION_ARG_INT, &poll_interval, "hotplug/connectivity poll seconds >=30, 0 to query"}, + {"cascade-interval", 'c', 0, G_OPTION_ARG_DOUBLE, &cascade_interval, "hotplug/connectivity cascade seconds >=0.5, 0 to query"}, + {"output-level", 'o', 0, G_OPTION_ARG_INT, &output_level, "ddcutil output level, -1 to query"}, + {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining_args}, {NULL} }; - context = g_option_context_new("detect | capabilities | capabilities-terse | getvcp 0xNN | setvcp 0xNN n"); + context = g_option_context_new( + "[detect | capabilities | capabilities-terse | getvcp 0xNN | setvcp 0xNN n]"); g_option_context_add_main_entries(context, entries, NULL); if (!g_option_context_parse(context, &argc, &argv, &error)) { g_printerr("ERROR: Error parsing options: %s\n", error->message); @@ -495,95 +624,130 @@ return SYNTAX_ERROR; } - if (!remaining_args || !remaining_args[0]) { - g_printerr("ERROR: You must provide a method (detect, getvcp, or setvcp) and appropriate arguments.\n"); - return SYNTAX_ERROR; + cmd_status_t exit_status; + if (version != 0) { + exit_status = print_property(connection, "ServiceInterfaceVersion"); } - - gchar *method = remaining_args[0]; - - GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); - if (!connection) { - g_printerr("ERROR: Error connecting to session bus: %s\n", error->message); - g_error_free(error); - return DBUS_ERROR; + if (ddversion != 0) { + exit_status = print_property(connection, "DdcutilVersion"); + } + if (locked != 0) { + exit_status = print_property(connection, "ServiceParametersLocked"); + } + if (status_values != 0) { + exit_status = print_property(connection, "StatusValues"); + } + if (display_event_types != 0) { + exit_status = print_property(connection, "DisplayEventTypes"); + } + if (service_flag_options != 0) { + exit_status = print_property(connection, "ServiceFlagOptions"); + } + if (attributes_detect != 0) { + exit_status = print_property(connection, "AttributesReturnedByDetect"); + } + if (poll_interval != -1) { + if (poll_interval >= 30) { + exit_status = set_property(connection, "ServicePollInterval", g_variant_new_uint32(poll_interval)); + print_property(connection, "ServicePollInterval"); + } else { + exit_status = print_property(connection, "ServicePollInterval"); + } + } + if (cascade_interval != DBL_MAX) { + if (cascade_interval >= 0.2) { + exit_status = set_property(connection, "ServicePollCascadeInterval", g_variant_new_double(cascade_interval)); + print_property(connection, "ServicePollCascadeInterval"); + } else { + exit_status = print_property(connection, "ServicePollCascadeInterval"); + } + } + if (output_level != -2) { + if (output_level >= 0) { + exit_status = set_property(connection, "DdcutilOutputLevel", g_variant_new_uint32(output_level)); + print_property(connection, "DdcutilOutputLevel"); + } else { + exit_status = print_property(connection, "DdcutilOutputLevel"); + } } - cmd_status_t exit_status; + if (remaining_args != NULL) { + gchar *method = remaining_args[0]; - if (g_strcmp0(method, "detect") == 0) { - exit_status = call_detect(connection); - } else if (g_strcmp0(method, "setvcp") == 0) { - int display_number = -1; - exit_status = parse_display_and_edid(display_number_str, edid_txt, &display_number); - if (exit_status == COMPLETED_WITHOUT_ERROR) { - if (!remaining_args[1] || !remaining_args[2]) { - g_printerr("ERROR: You must provide a VCP code and a new value for setvcp.\n"); - exit_status = SYNTAX_ERROR; - } else { - guint8 vcp_code = (guint8) parse_int(remaining_args[1], 16, &exit_status); - if (exit_status != 0) { - g_printerr("ERROR: Invalid VCP code. It must be in hex format (e.g. 0x10).\n"); + if (!remaining_args || !remaining_args[0]) { + g_printerr("ERROR: You must provide a method (detect, getvcp, or setvcp) and appropriate arguments.\n"); + exit_status = SYNTAX_ERROR; + } else if (g_strcmp0(method, "detect") == 0) { + exit_status = call_detect(connection); + } else if (g_strcmp0(method, "setvcp") == 0) { + exit_status = parse_display_and_edid(&display_number, edid_txt); + if (exit_status == COMPLETED_WITHOUT_ERROR) { + if (!remaining_args[1] || !remaining_args[2]) { + g_printerr("ERROR: You must provide a VCP code and a new value for setvcp.\n"); + exit_status = SYNTAX_ERROR; } else { - guint16 vcp_new_value = (guint16) parse_int(remaining_args[2], 10, &exit_status); + guint8 vcp_code = (guint8) parse_int(remaining_args[1], 16, &exit_status); if (exit_status != 0) { - g_printerr("ERROR: Invalid new value. It must be in decimal (e.g. 80).\n"); + g_printerr("ERROR: Invalid VCP code. It must be in hex format (e.g. 0x10).\n"); } else { - exit_status = call_set_vcp(connection, display_number, edid_txt, vcp_code, vcp_new_value); + guint16 vcp_new_value = (guint16) parse_int(remaining_args[2], 10, &exit_status); + if (exit_status != 0) { + g_printerr("ERROR: Invalid new value. It must be in decimal (e.g. 80).\n"); + } else { + exit_status = call_set_vcp(connection, display_number, edid_txt, vcp_code, vcp_new_value); + } } } } - } - } else if (g_strcmp0(method, "getvcp") == 0) { - int display_number = -1; - exit_status = parse_display_and_edid(display_number_str, edid_txt, &display_number); - if (exit_status == COMPLETED_WITHOUT_ERROR) { - if (!remaining_args[1]) { - g_printerr("ERROR: You must provide a VCP code for getvcp.\n"); - exit_status = SYNTAX_ERROR; - } else { - guint8 vcp_code = (guint8) parse_int(remaining_args[1], 16, &exit_status); - if (exit_status != 0) { - g_printerr("ERROR: Invalid VCP code. It must be in hex format (e.g. 0x10).\n"); + } else if (g_strcmp0(method, "getvcp") == 0) { + exit_status = parse_display_and_edid(&display_number, edid_txt); + if (exit_status == COMPLETED_WITHOUT_ERROR) { + if (!remaining_args[1]) { + g_printerr("ERROR: You must provide a VCP code for getvcp.\n"); + exit_status = SYNTAX_ERROR; } else { - exit_status = call_get_vcp(connection, display_number, edid_txt, vcp_code, - raw ? RETURN_RAW_VALUES : 0); + guint8 vcp_code = (guint8) parse_int(remaining_args[1], 16, &exit_status); + if (exit_status != 0) { + g_printerr("ERROR: Invalid VCP code. It must be in hex format (e.g. 0x10).\n"); + } else { + exit_status = call_get_vcp(connection, display_number, edid_txt, vcp_code, + raw ? RETURN_RAW_VALUES : 0); + } } } - } - } else if (g_strcmp0(method, "getvcp-metadata") == 0) { - int display_number = -1; - exit_status = parse_display_and_edid(display_number_str, edid_txt, &display_number); - if (exit_status == COMPLETED_WITHOUT_ERROR) { - if (!remaining_args[1]) { - g_printerr("ERROR: You must provide a VCP code for getvcp-metadata.\n"); - exit_status = SYNTAX_ERROR; - } else { - guint8 vcp_code = (guint8) parse_int(remaining_args[1], 16, &exit_status); - if (exit_status != 0) { - g_printerr("ERROR: Invalid VCP code. It must be in hex format (e.g. 0x10).\n"); + } else if (g_strcmp0(method, "getvcp-metadata") == 0) { + int display_number = -1; + exit_status = parse_display_and_edid(&display_number, edid_txt); + if (exit_status == COMPLETED_WITHOUT_ERROR) { + if (!remaining_args[1]) { + g_printerr("ERROR: You must provide a VCP code for getvcp-metadata.\n"); + exit_status = SYNTAX_ERROR; } else { - exit_status = call_get_vcp_metadata(connection, display_number, edid_txt, vcp_code); + guint8 vcp_code = (guint8) parse_int(remaining_args[1], 16, &exit_status); + if (exit_status != 0) { + g_printerr("ERROR: Invalid VCP code. It must be in hex format (e.g. 0x10).\n"); + } else { + exit_status = call_get_vcp_metadata(connection, display_number, edid_txt, vcp_code); + } } } + } else if (g_strcmp0(method, "capabilities") == 0) { + int display_number = -1; + exit_status = parse_display_and_edid(&display_number, edid_txt); + if (exit_status == COMPLETED_WITHOUT_ERROR) { + exit_status = call_capabilities_metadata(connection, display_number, edid_txt); + } + } else if (g_strcmp0(method, "capabilities-terse") == 0) { + int display_number = -1; + exit_status = parse_display_and_edid(&display_number, edid_txt); + if (exit_status == COMPLETED_WITHOUT_ERROR) { + exit_status = call_capabilities(connection, display_number, edid_txt); + } + } else { + g_printerr("ERROR: Unknown command: %s\n", method); + exit_status = SYNTAX_ERROR; } - } else if (g_strcmp0(method, "capabilities") == 0) { - int display_number = -1; - exit_status = parse_display_and_edid(display_number_str, edid_txt, &display_number); - if (exit_status == COMPLETED_WITHOUT_ERROR) { - exit_status = call_capabilities_metadata(connection, display_number, edid_txt); - } - } else if (g_strcmp0(method, "capabilities-terse") == 0) { - int display_number = -1; - exit_status = parse_display_and_edid(display_number_str, edid_txt, &display_number); - if (exit_status == COMPLETED_WITHOUT_ERROR) { - exit_status = call_capabilities(connection, display_number, edid_txt); - } - } else { - g_printerr("ERROR: Unknown command: %s\n", method); - exit_status = SYNTAX_ERROR; } - g_object_unref(connection); return exit_status; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ddcutil-service-1.0.9/ddcutil-service.7 new/ddcutil-service-1.0.11/ddcutil-service.7 --- old/ddcutil-service-1.0.9/ddcutil-service.7 2024-06-14 03:32:23.000000000 +0200 +++ new/ddcutil-service-1.0.11/ddcutil-service.7 2024-08-22 03:59:06.000000000 +0200 @@ -2,12 +2,12 @@ .\" Title: com.ddcutil.DdcutilInterface .\" Author: Michael Hamilton .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> -.\" Date: 06/11/2024 +.\" Date: 07/02/2024 .\" Manual: Miscellaneous .\" Source: ddcutil-service .\" Language: English .\" -.TH "COM\&.DDCUTIL\&.DDCU" "7" "06/11/2024" "ddcutil\-service" "Miscellaneous" +.TH "COM\&.DDCUTIL\&.DDCU" "7" "07/02/2024" "ddcutil\-service" "Miscellaneous" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -250,7 +250,7 @@ .PP IN u \fIflags\fR: .RS 4 -If set to 1, any invalid VDUs will be included in the results\&. +If set to 8 (DETECT_ALL), any invalid VDUs will be included in the results\&. .RE .PP OUT i \fInumber_of_displays\fR: @@ -324,7 +324,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE @@ -379,7 +379,7 @@ .PP The method\*(Aqs \fIflags\fR -parameter can be set to 2 (RETURN_RAW_VALUE), see ddcutil\-service\&.1 LIMITATIONS for an explanation\&. +parameter can be set to 2 (RETURN_RAW_VALUES), see ddcutil\-service\&.1 LIMITATIONS for an explanation\&. .PP IN i \fIdisplay_number\fR: .RS 4 @@ -398,7 +398,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE @@ -467,7 +467,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE @@ -537,7 +537,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE @@ -594,7 +594,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE @@ -674,7 +674,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE @@ -732,7 +732,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE @@ -807,7 +807,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE @@ -854,7 +854,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE @@ -915,7 +915,7 @@ .PP IN u \fIflags\fR: .RS 4 -If 1, the +If 1 (EDID_PREFIX), the \fIedid_txt\fR is matched as a unique prefix of the EDID\&. .RE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ddcutil-service-1.0.9/ddcutil-service.c new/ddcutil-service-1.0.11/ddcutil-service.c --- old/ddcutil-service-1.0.9/ddcutil-service.c 2024-06-14 03:32:23.000000000 +0200 +++ new/ddcutil-service-1.0.11/ddcutil-service.c 2024-08-22 03:59:06.000000000 +0200 @@ -58,7 +58,7 @@ #include <ddcutil_status_codes.h> #include <ddcutil_macros.h> -#define DDCUTIL_DBUS_INTERFACE_VERSION_STRING "1.0.9" +#define DDCUTIL_DBUS_INTERFACE_VERSION_STRING "1.0.11" #define DDCUTIL_DBUS_DOMAIN "com.ddcutil.DdcutilService" #if DDCUTIL_VMAJOR == 2 && DDCUTIL_VMINOR == 0 && DDCUTIL_VMICRO < 2 @@ -153,7 +153,7 @@ <!-- Detect: - @flags: If set to 1, any invalid VDUs will be included in the results. + @flags: If set to 8 (DETECT_ALL), any invalid VDUs will be included in the results. @number_of_displays: The number of VDUs detected (the length of @detected_displays). @detected_displays: An array of structures describing the VDUs. @error_status: A libddcutil DDCRC error status. DDCRC_OK (zero) if no errors have occurred. @@ -180,7 +180,7 @@ @display_number: The libddcutil/ddcutil display number to query @edid_txt: The base-64 encoded EDID of the display @vcp_code: The VPC-code to query, for example, 16 (0x10) is brightness. - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @vcp_current_value: The current numeric value as a unified 16 bit integer. @vcp_max_value: The maximum possible value, to allow for easy calculation of current/max. @vcp_formatted_value: A formatted version of the value including related info such as the max-value. @@ -215,7 +215,7 @@ @display_number: the libddcutil/ddcutil display number to query @edid_txt: the base-64 encoded EDID of the display @vcp_code: the VPC-code to query. - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @vcp_current_value: An array of VCP-codes and values. @error_status: A libddcutil DDCRC error status. DDCRC_OK (zero) if no errors have occurred. @error_message: Text message for error_status. @@ -226,7 +226,7 @@ Each entry in @vcp_current_value array is a VCP-code along with its current, maximum and formatted values (the same as those returned by GetVcp). - The method's @flags parameter can be set to 2 (RETURN_RAW_VALUE), + The method's @flags parameter can be set to 2 (RETURN_RAW_VALUES), see ddcutil-service.1 LIMITATIONS for an explanation. --> <method name='GetMultipleVcp'> @@ -245,7 +245,7 @@ @edid_txt: the base-64 encoded EDID of the display @vcp_code: the VPC-code to query. @vcp_new_value: the numeric value as a 16 bit integer. - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @error_status: A libddcutil DDCRC error status. DDCRC_OK (zero) if no errors have occurred. @error_message: Text message for error_status. @@ -274,7 +274,7 @@ @vcp_code: the VPC-code to query. @vcp_new_value: the numeric value as a 16 bit integer. @client_context: a client-context string that will be returned with the VcpValueChanged signal. - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @error_status: A libddcutil DDCRC error status. DDCRC_OK (zero) if no errors have occurred. @error_message: Text message for error_status. @@ -302,7 +302,7 @@ @display_number: the libddcutil/ddcutil display number to query @edid_txt: the base-64 encoded EDID of the display @vcp_code: the VPC-code to query. - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @feature_name: the feature name for the VCP-code @feature_description: the feature description, if any, of the VCP-code. @is_read_only: True if the feature is read-only. @@ -335,7 +335,7 @@ GetCapabilitiesString: @display_number: the libddcutil/ddcutil display number to query @edid_txt: the base-64 encoded EDID of the display - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @capabilities_text: the capability string for the VDU. @error_status: A libddcutil DDCRC error status. DDCRC_OK (zero) if no errors have occurred. @error_message: Text message for error_status. @@ -356,7 +356,7 @@ GetCapabilitiesMetadata: @display_number: the libddcutil/ddcutil display number to query @edid_txt: the base-64 encoded EDID of the display - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @model_name: parsed model name string @mccs_major: MCCS major version number byte. @mccs_minor: MCCS minor version number byte. @@ -392,7 +392,7 @@ GetDisplayState: @display_number: the libddcutil/ddcutil display number to query @edid_txt: the base-64 encoded EDID of the display - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @status: A libddcutil display status. @message: Text message for display status. @@ -418,7 +418,7 @@ @display_number: the libddcutil/ddcutil display number to query @edid_txt: the base-64 encoded EDID of the display @vcp_code: the VPC-code to query, for example, 16 (0x10) is brightness. - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @current_multiplier: the sleep multiplier. @error_status: A libddcutil DDCRC error status. DDCRC_OK (zero) if no errors have occurred. @error_message: Text message for error_status. @@ -441,7 +441,7 @@ @display_number: The libddcutil/ddcutil display number to query @edid_txt: The base-64 encoded EDID of the display @vcp_code: The VPC-code to query, for example, 16 (0x10) is brightness. - @flags: If 1, the @edid_txt is matched as a unique prefix of the EDID. + @flags: If 1 (EDID_PREFIX), the @edid_txt is matched as a unique prefix of the EDID. @new_multiplier: The sleep multiplier. @error_status: A libddcutil DDCRC error status. DDCRC_OK (zero) if no errors have occurred. @error_message: Text message for error_status. @@ -680,6 +680,11 @@ */ static gboolean return_raw_values = FALSE; +/** + * True if service info logging is currently enabled. + */ +static gboolean service_info_logging = FALSE; + /* ---------------------------------------------------------------------------------------------------- * Bit flags that can be passed in the service method flags argument. */ @@ -687,16 +692,17 @@ EDID_PREFIX = 1, // Indicates the EDID passed to the service is a unique prefix (substr) of the actual EDID. RETURN_RAW_VALUES = 2, // GetVcp GetMultipleVcp NO_VERIFY = 4, // SetVcp - + DETECT_ALL = 8, // Detect all VDUs, including those that are not powered up. } Flags_Enum_Type; /** * Iterable definitions of Flags_Enum_Type values/names (for return from a service property). */ -static const int flag_options[] = {EDID_PREFIX,RETURN_RAW_VALUES, NO_VERIFY,}; +static const int flag_options[] = {EDID_PREFIX,RETURN_RAW_VALUES, NO_VERIFY, DETECT_ALL, }; static const char* flag_options_names[] = {G_STRINGIFY(EDID_PREFIX), G_STRINGIFY(RETURN_RAW_VALUES), - G_STRINGIFY(NO_VERIFY),}; + G_STRINGIFY(NO_VERIFY), + G_STRINGIFY(DETECT_ALL),}; G_STATIC_ASSERT(G_N_ELEMENTS(flag_options) == G_N_ELEMENTS(flag_options_names)); // Boilerplate @@ -902,6 +908,7 @@ * @return the new enabled state */ static bool enable_service_info_logging(bool enable, bool overwrite) { + service_info_logging = enable; if (enable) { // WARNING g_setenv/g_unsetenv stopped working, using setenv/unsetenv instead. // Possible interaction with other logging options, maybe from libddcutil - weird @@ -952,14 +959,28 @@ */ static DDCA_Status get_display_info_list(bool include_invalid, DDCA_Display_Info_List** dlist_loc, char *msg_prefix) { DDCA_Status detect_status = ddca_get_display_info_list2(include_invalid, dlist_loc); - if (detect_status == DDCRC_OTHER) { // A non-error? Documented as "other error (for use during development)" - if (msg_prefix != NULL) { - char *detect_message_text = get_status_message(detect_status); - g_warning("%s: treating as OK ddca_get_display_info_list2 status=%d message=%s", - msg_prefix, detect_status, detect_message_text); - free(detect_message_text); + + // Pre libddcutil 2.1.5 ddca_get_display_info_list2 could return DDCRC_OTHER if some VDUs were invalid, + // For libddcutil 2.1.5+ ddca_get_display_info_list2 will return DDCRC_OK, but set error_detail if some VDUs are invalid. + DDCA_Error_Detail *error_detail = ddca_get_error_detail(); + if (error_detail != NULL) { // libddcutil 2.1.5 and abouve + if (error_detail->status_code == DDCRC_OTHER) { + if (msg_prefix != NULL) { + char *detect_message_text = get_status_message(error_detail->status_code); + g_warning("%s: treating as OK ddca_get_display_info_list2 status=%d message=%s detail=%s", + msg_prefix, error_detail->status_code, detect_message_text, error_detail->detail); + free(detect_message_text); + } + detect_status = DDCRC_OK; // change to DDCRC_OK, just in case } - detect_status = DDCRC_OK; + ddca_free_error_detail(error_detail); + } + if (detect_status == DDCRC_OTHER) { // Pre libddcutil 2.1.5 - probably also safe post 2.1.5 + char *detect_message_text = get_status_message(detect_status); + g_warning("%s: treating as OK ddca_get_display_info_list2 status=%d message=%s", + msg_prefix, detect_status, detect_message_text); + free(detect_message_text); + detect_status = DDCRC_OK; // change to DDCRC_OK } return detect_status; } @@ -975,7 +996,7 @@ * @param edid_encoded text encoded edid * @param dlist ddcutil list of displays (will need to be freed after use) * @param dinfo pointer into the list for the matched display - * @param edid_is_prefix match edidby unique prefix + * @param edid_is_prefix match edid by unique prefix * @return success status */ static DDCA_Status get_display_info(const int display_number, const char* edid_encoded, @@ -1101,7 +1122,8 @@ } else { DDCA_Display_Info_List *dlist = NULL; - detect_status = get_display_info_list(flags != 0, &dlist, "Detect"); + const int detect_all = (flags & DETECT_ALL) || (flags & EDID_PREFIX); // Accept either because of old API error + detect_status = get_display_info_list(detect_all, &dlist, "Detect"); detect_message_text = get_status_message(detect_status); if (detect_status != DDCRC_OK) { g_warning("Detect: ddca_get_display_info_list2 failed status=%d message=%s", @@ -2282,7 +2304,17 @@ bool event_is_ready = FALSE; if (now_in_micros >= next_poll_time) { g_debug("Poll for display connection changes"); + // Masking the logging is a bit hacky - it depends on internal knowledge of how libddcutil is logging. + // The author of libddcutil regards the normal messages as quite important, so they should normally be logged. + // A compromise: when the service is not logging debug/info, change the syslog mask, and then restore it. + int old_mask = 0; + if (!service_info_logging) { + old_mask = setlogmask(LOG_UPTO(LOG_WARNING)); // Temporarily disable notice msgs from libddcutil + } const DDCA_Status detect_status = ddca_redetect_displays(); // Do not call too frequently, delays the main-loop + if (!service_info_logging) { + setlogmask(old_mask); // Restore original logging mask + } if (detect_status == DDCRC_OK) { DDCA_Display_Info_List* dlist; const DDCA_Status info_status = get_display_info_list(1, &dlist, NULL); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ddcutil-service-1.0.9/ddcutil-service.spec new/ddcutil-service-1.0.11/ddcutil-service.spec --- old/ddcutil-service-1.0.9/ddcutil-service.spec 2024-06-14 03:32:23.000000000 +0200 +++ new/ddcutil-service-1.0.11/ddcutil-service.spec 2024-08-22 03:59:06.000000000 +0200 @@ -18,7 +18,7 @@ Name: ddcutil-service -Version: 1.0.9 +Version: 1.0.11 Release: 0 Summary: D-Bus service for libddcutil VESA DDC Monitor Virtual Control Panel License: GPL-2.0-or-later diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ddcutil-service-1.0.9/docs/html/ddcutil-service.1.html new/ddcutil-service-1.0.11/docs/html/ddcutil-service.1.html --- old/ddcutil-service-1.0.9/docs/html/ddcutil-service.1.html 2024-06-14 03:32:23.000000000 +0200 +++ new/ddcutil-service-1.0.11/docs/html/ddcutil-service.1.html 2024-08-22 03:59:06.000000000 +0200 @@ -1,5 +1,5 @@ <!-- Creator : groff version 1.23.0 --> -<!-- CreationDate: Tue Jun 11 16:36:56 2024 --> +<!-- CreationDate: Tue Jul 2 16:41:23 2024 --> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> @@ -808,51 +808,49 @@ <p style="margin-left:9%; margin-top: 1em">Some VDUs are -not standards compliant. In some cases, non-compliance can -vary to the extent that only a service client can deal with -it, and often only by by requiring additional user supplied -metadata. For example, the <b>vdu_controls</b> client allows -the user to edit/override the service supplied +not fully DDC compliant. In some cases issues raised by +non-compliance can only be resolved at the client-level, +often by requiring the user to provide additional metadata. +For example, the <b>vdu_controls</b> client allows the user +to edit/override the service supplied capabilities-metadata.</p> -<p style="margin-left:9%; margin-top: 1em">In some cases -VDUs may not comply with the specified data-type for -single-byte <b>Simple Non Continuous</b> values, this -includes values such as the VDU input-source or -OSD-language. SNC values are supposed to be 8 bits only and -are passed in the low-byte of the the 16 bit values returned -by the VDU. The 16-bit values are masked to remove the -high-byte because some VDUs don’t zero the unused -high-byte, which means unmasked 16 bit SNC values will -sometimes fail to match 8-bit value declared in VDU -capabilities-metadata. However, there are other VDUs that -disregard the SNC 8 bit restriction and set the high-byte to -a significant value, which means masking is inappropriate in -some cases. The service defaults to standard-compliance and -masks off the high-byte. To allow for the less common second -case, the <b>GetVcp</b> and <b>GetMultipleVcp</b> methods -support the <b>RETURN_RAW_VALUES</b> flag which forces the -return of the original 16 bit values. This provides the -client with an opportunity to take responsibility for -disambiguating each case by applying heuristics or by -consulting additional user supplied metadata. Note that the -<b>SetVcp</b> counterpart always accepts full 16 bit values -and passes them unaltered to the VDU.</p> - -<p style="margin-left:9%; margin-top: 1em">The service may -fail to determine working options for the -<b>ConnectedDisplaysChanged</b> signal for some mixes of -VPUs and GPUs (some hardware/drivers misreport their -capabilities). If signals are not being raised, try manually -adding <b>--prefer-polling</b> option, this option is not -the most responsive, but it is the one most likely to always -work.</p> +<p style="margin-left:9%; margin-top: 1em">Some VDUs differ +in how they treat the data-type for +<b>Simple-Non-Continuous</b> values. SNC values are used for +features such as the <i>Input-Source</i> or +<i>OSD-language</i>. According to the DDC specification, SNC +values should be 8-bit values passed in the low-byte of a +16-bit value.</p> + +<p style="margin-left:9%; margin-top: 1em">Some VDUs +don’t zero the SNC high-byte. This may cause a +mismatch with the values specified in the VDU metadata. The +service handles this by defaulting to masking off the +high-byte of SNC values.</p> + +<p style="margin-left:9%; margin-top: 1em">Some VDUs return +SNC values where both the low and high byte are significant. +The <b>GetVcp</b> and <b>GetMultipleVcp</b> methods support +the <b>RETURN_RAW_VALUES</b> flag to force the return of +unmasked 16-bit values. This allows clients to apply +heuristics or use additional metadata to handle such cases. +The <b>SetVcp</b> counterpart always accepts full 16-bit +values and passes them unaltered to the VDU.</p> + +<p style="margin-left:9%; margin-top: 1em">Some mixes of +VPUs and GPUs don’t consistently update DRM metadata +for hot-plug events. If <b>ConnectedDisplaysChanged</b> +signals are not being raised, try manually adding +<b>--prefer-polling</b> option, to force the service to poll +for changes. Polling is less responsive, but it +doesn’t require DRM, and is likely to always work.</p> <p style="margin-left:9%; margin-top: 1em">Some GPU drivers and VDUs have buggy implementations of DDC. If you have the choice, a <b>DisplayPort to DisplayPort</b> connection may work more reliably than <b>DVI, HDMI</b> or mixed -connectors. Different GPU driver editions, such as +connectors. In some cases GPU driver editions, such as production, beta, and development, may vary in the state of their DDC support.</p> @@ -869,12 +867,12 @@ $HOME/.config/ddcutil/ddcutilrc and documented at <i>https://www.ddcutil.com/config_file/</i>.</p> -<p style="margin-left:9%; margin-top: 1em">The service -wraps <b>libddcutil</b>. In some cases <b>libddcutil</b> has -been found to perform differently from the <b>ddcutil</b> -command. If the service has problems with a VDU, it’s -worth trying the ddcutil command to see if it differs in -result and to include those details in any issue raised.</p> +<p style="margin-left:9%; margin-top: 1em">In some cases +<b>libddcutil</b> has been found to perform differently from +the <b>ddcutil</b> command. If the service has problems with +a VDU, it’s worth trying the ddcutil command to see if +it differs in result and to include those details in any +issue raised.</p> <h2>SEE ALSO <a name="SEE ALSO"></a> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ddcutil-service-1.0.9/docs/html/ddcutil-service.7.html new/ddcutil-service-1.0.11/docs/html/ddcutil-service.7.html --- old/ddcutil-service-1.0.9/docs/html/ddcutil-service.7.html 2024-06-14 03:32:23.000000000 +0200 +++ new/ddcutil-service-1.0.11/docs/html/ddcutil-service.7.html 2024-08-22 03:59:06.000000000 +0200 @@ -1,5 +1,5 @@ <!-- Creator : groff version 1.23.0 --> -<!-- CreationDate: Tue Jun 11 16:36:56 2024 --> +<!-- CreationDate: Tue Jul 2 16:41:23 2024 --> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> @@ -331,8 +331,8 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If set to 1, any invalid VDUs -will be included in the results.</p> +<p style="margin-left:14%;">If set to 8 (DETECT_ALL), any +invalid VDUs will be included in the results.</p> <p style="margin-left:9%; margin-top: 1em">OUT i <i>number_of_displays</i>:</p> @@ -414,8 +414,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT q <i>vcp_current_value</i>:</p> @@ -473,7 +474,7 @@ those returned by GetVcp).</p> <p style="margin-left:9%; margin-top: 1em">The method's -<i>flags</i> parameter can be set to 2 (RETURN_RAW_VALUE), +<i>flags</i> parameter can be set to 2 (RETURN_RAW_VALUES), see ddcutil−service.1 LIMITATIONS for an explanation.</p> @@ -498,8 +499,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT a(yqqs) <i>vcp_current_value</i>:</p> @@ -573,8 +575,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT i <i>error_status</i>:</p> @@ -650,8 +653,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT i <i>error_status</i>:</p> @@ -709,8 +713,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT s <i>feature_name</i>:</p> @@ -801,8 +806,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT s <i>capabilities_text</i>:</p> @@ -871,8 +877,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT s <i>model_name</i>:</p> @@ -954,8 +961,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT i <i>status</i>:</p> @@ -1005,8 +1013,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT d <i>current_multiplier</i>:</p> @@ -1078,8 +1087,9 @@ <p style="margin-left:9%; margin-top: 1em">IN u <i>flags</i>:</p> -<p style="margin-left:14%;">If 1, the <i>edid_txt</i> is -matched as a unique prefix of the EDID.</p> +<p style="margin-left:14%;">If 1 (EDID_PREFIX), the +<i>edid_txt</i> is matched as a unique prefix of the +EDID.</p> <p style="margin-left:9%; margin-top: 1em">OUT i <i>error_status</i>:</p>