Notes for Upcoming ddcutil Release 2.2.0 (Draft)
Note: Reflecting the extensive changes, the next ddcutil release will be numbered 2.2.0, not 2.1.5.
For ddcui changes, see ddcui Release Notes
Changes since 2.2.0-rc1
Branch 2.2.0-rc2 contains extensive changes, particularly for handling corner cases in display detection, such as displays that disconnect immediately after connection.
It's possible that there is a delay between the time a monitor is turned on (and X11/Wayland generate a display change event) and the time that DDC becomes enabled. To address this situation, there's a newly added flags field in the unused section of DDCA_Display_Status_Event, with bit DDCA_DISPLAY_EVENT_DDC_WORKING. If a monitor is detected but DDC is not working, a display connection event is reported to the client with flag DDCA_DISPLAY_EVENT_DDC_NOT_WORKING set, and the display reference goes onto a recheck queue processed by a separate thread. There will be a subsequent event of type DDCA_EVENT_DDC_ENABLED if and when the recheck thread determines that DDC is working.
There's a tension in display change detection between minimizing the time between when X11/Wayland detects a monitor having been turned on and libddcutil issuing an event of type DDCA_DISPLAY_EVENT_CONNECTED versus checking and rechecking failed states (e.g. DDC not working). In many cases, the frequency and wait intervals are controlled by settings in file src/base/parms.h. If you do experiment with these settings, please report the results.
Miscellaneous changes:
- The opaque value of DDCA_Display_Ref is now an integer display reference id number instead of an actual pointer to the internal display reference, making it slightly more opaque. The published type remains (void*), so no client changes should be needed.
- libddcutil maintains a table of DDCA_Display_Refs that have been passed to the client by the API. This table is used to further validate display references the client passes as arguments.
- Newly added option --disable-api causes API calls to fail. This can be useful for excluding libddcutil as a source of system errors, particularly when a client such as KDE PowerDevil, cannot be built without libddcutil.
- API calls ddca_get_display_refs() and ddca_get_display_info_list2() do not include displays that have been marked removed. Addresses ddcutil issue #417.
- The default for option --watch-mode is now DYNAMIC. This resolves to XEVENT if possible, otherwise to POLL. Watch mode UDEV continues to exist, but will likely be removed in the future.
- Option --ignore-mmid replaces the ambiguously named --ignore-ddc.
- Disable the check, in the prolog to API functions, that a monitor is not asleep. It is possible that a display is still responsive to DDC requests in this case. If it is not, the error will be detected when actually performing the requested operation.
- Ensure that all syslog messages are prefixed similarly with thread and timestamp.
- ddca_get_display_info() succeeds even if DDC communication is not working. Addresses issue ddcui issue #55.
- Option --skip-ddc-checks sets the detected VCP version to "Unknown". Addresses a possible segfault when this option is used with display change detection.
- Write syslog messages for sleeps incurred by display change detection.
- Maintain thread-specific traced function stacks for debugging.
- Additional compiler warnings to tighten code, specified in automake variable AM_CFLAGS.
-
Plug memory leaks.
-
Utility options:
- Option --f8 directs all report output to syslog
- Option --f19 optionally check buses with edid stable on add as well as remove
- Option --i6 has been eliminated. This option adjusted the display watch sleep time by a multiplier.
- Option --f24 causes "detect" be written to sysfs drm attribute status before reading connector attributes. Applies only for the proprietary nvidia driver. Note that this requires write access to the status attribute.
2.2.0-rc1
05 Dec 2024
Release 2.2.0 contains some major enhancements, particularly for display change detection, numerous small changes, and a large number of bug fixes.
DisplayLink
DisplayLink devices, using the evince driver, are supported.
Raspberry Pi
- Fix display not found and DDC communication failure on Raspberry Pi. Do not rely on sysfs attributes that do not exist for ARM devices. Resolves github issues 403, 413.
- Miscellaneous changes to allow for building on raspbian.
User Defined Features
- Add feature type XNC (Extended Non-Continous). This is like simple NC, but the SH byte is also reported. Provides a solution to the primary problem raised in github issue 403. Note that this feature type was created for use in user defined feature definitions; there are no features of this type defined in the Monitor Control Command Set specification.
- Allow SNC (Simple Non-Continuous) as alternative name for NC.
- Report user defined features as part of parsed capabilities.
- Commands recognizing user defined features now fail if there's an error loading a user defined feature file. These are capabilities, setvcp, dumpvcp, and probe.
- Fix error msg when nothing follows VALUE in user defined feature file.
- When processing a user defined feature file, recognize any whitespace character (e.g. tab), not just space.
Command detect
- Only show details about DDC communication errors if option --verbose is in effect.
- Provide a clearer message if slave address x37 is inactive:
- "Monitor does not support DDC" instead of generic "DDC_commnication failed"
- If option --verbose is in effect, emit an additional message to check the monitor's OSD.
- Report the Monitor Model Id in the --verbose output.
Command setvcp
- Do not report "Interpretation may not be accurate." when the VCP version cannot be determined. This message is irrelevant for setvcp, which does not interpret feature values. Partially addresses github issue 454.
Commands interrogate and environment --verbose
- Force settings --disable-cross-instance-locking, --disable-dynamic-sleep.
- Forced settings apply to environment --verbose as well as interrogate
- When probing DRM, recognize bus types DRM_BUS_PLATFORM, DRM_BUS_HOST1X, report as "platform", "host1x".
- Simple getvcp test was not reporting the bytes of the response packet.
- If no device with class x03 was found, the user's home directory was dumped. Addresses github issue 413.
- Remove "-i" option on get-edid command. Does not exist on some versions.
Udev rules
- /usr/lib/udev/rules.d/60-ddcutil-i2c-rules:
- Also give logged on user r/w access to /dev/dri/cardN, needed to allow logged on user to probe connectors using DRM.
- Do not install /usr/lib/udev/rules.d/60-ddcutil-usb.rules, delete it if previously installed. Addresses github issues 405, 428, 437.
Parser changes
- Add alternative option names for symmetry with other options:
- --discard-capabilities-cache is an alias for --discard-cache capabilities
- --discard-sleep-cache is an alias for --discard cache dsa
- --discard-dsa-cache is an alias for --discard cache dsa
- Eliminate --enable-dsa-cache as alias for --enable-dynamic-sleep-cache.
- Improve handling of --verify/--noverify, error if both specified
- Add --enable-flock and --disable-flock as aliases for --enable-cross-instance-locks and --disable-cross-instance-locks.
Minor Bug Fixes and Changes
- Configuration file ddcutilrc: If there is a pound sign "#" on a line, the remainder of the line is treated as a comment.
- If option --bus is specified, only check accessability for that bus, avoiding irrelevant warning messages regarding other buses. Addresses github issue 461:ddcutil tries to access other i2c devices even if --bus is used to specify the bus number.
- Add command noop, which allows for executing options such as --settings without having to execute a real command.
- Change the system log message level from WARNING to VERBOSE when sleep time is adjusted. Addresses github issue 427: Adjusting multiplier message fills system log when libddcutil used by clightd.
- When processing environment variable user $XDG_DATA_DIRS, or $XDG_CONFIG_DIRS, the final directory in the list was ignored. See github issue 438:ddcutil ignores the final entry in XDG_DATA_DIRS when looking for an mccs file.
- Fix core dump on ddcutil getvcp. Fixes github issue 407:Core dump on ddcutil getvcp.
- Convert CRLF line endings in source to LF.
- Rework laptop detection. A non-laptop display can have an eDP connector. This is an i915 video driver bug that will not be fixed. See freedesktop.org issue [DRM connector for external monitor has name card1-eDP-1] (https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/10389).
Building ddcutil
- As an aid to development, the build date and time are normally embedded in the ddcutil and libddcutil executables. This is reported using command ddcutil --version --verbose. libddcutil reports this to the system log. If reproducible builds are required, use configure option --disable-build-timestamp.
- configure options --enable-x11/--disable-x11 are restored. The default is --enable-x11. The X11 RandR API works on Wayland as well as X11, and is used for display change detection. In addition, the X11 API continues to be used to test for DPMS sleep mode.
- Changes for portability:
- Use printf() formats %jd and %zd to portably print variables of type ssize_t, and time_t, so as to build unchanged on architectures such as armel, armhf.
- Avoid compiler warning possible depending on compiler configuration when a switch() construct is used. Replaced with if/else if/else. Resolves github issue 458:Fix build with -Werror=format-security and GCC 14.2.1
- Compile using option -Wformat-security. Addresses github issue 458:https://github.com/rockowitz/ddcutil/pull/458.
Shared Library
Shared library libddcutil is backwardly compatible with the one in ddcutil 2.1.0. The SONAME is unchanged as libddcutil.so.5. The released library file is libddcutil.so.5.2.0.
Display Change Reporting
Detection of display connection and disconnection has been extensively reworked.
- Detecting and reporting sleep mode has proven very problematic. libddcutil no longer watches for and reports changes to DPMS state. However, if an API function is called to perform an operation that requires communiation with a display that is asleep, status DDCRC_DPMS_ASLEEP is returned.
- ddca_start_watch_displays() has been modifed accordingly in a backwards compatible way.
- The only event class that can be enabled is DDCA_EVENT_CLASS_DISPLAY_DETECTION. . - DDCA_EVENT_CLASS_ALL is effectively the same as DDCA_EVENT_CLASS_DISPLAY_CONNECTION.
- It is an error if either DDCA_EVENT_CLASS_DPMS or DDCA_EVENT_CLASS_NONE are specified.
- Performance is improved using UDEV and /sys to watch for changes and to get the EDID if possible.
-
Connection of Multi-Stream Transport (MST) hub devices is detected if the driver/device combination supports it. Not all drivers do.
-
Display change detection is unreliable with the nvidia proprietary driver.
- The nvidia driver does not use /sys in the same way as amdgpu, i915, nouveau and other drm enabled drivers that are part of the Linux kernel.
- Depending on driver version the phase of the moon, the /sys file system does not reflect display changes and UDEV events are not generated. In that case no display changes are reported.
- There is an alternate, much less efficient algorithm that does not
rely on UDEV and /sys that can be used for nvidia.
It instead attempts to read an EDID from every (plausible)
/dev/i2c device in a polling loop. Users with all but the most powerful machines will likely find it much too resource consumptive.
It is enabled by option --watch-mode poll.
- The following named options affect display change detection.
- ---watch-mode udev|poll. the default is UDEV.
- --enable/disable-try-get-edid-from-sysfs (default --enable-try-get-edid-from-sysfs) This may or may not improve performance at the expense of reliability.
- Some monitors behave in ways that make KDE PowerDevil unstable.
See, for example, ddcutil github issue 466:Samsung Odyssey G5 S27DG50: Setting brightness causes monitor to crash, github issue 470:DDCA_EVENT_DPMS_AWAKE sent shortly after DDCA_EVENT_DPMS_ASLEEP and KDE bug 495746:https://bugs.kde.org/show_bug.cgi?id=495746.
Specific monitor models can be excluded from display change detection using
option --disable-ddc, which takes a Monitor Model Id,
e.g. SAM-U32H75x-3587, as an argument. The monitor model id can be found in the output of
command ddcutil detect --verbose, and is the same monitor model id that is used in the name of a user defined features file.
-- Typically, this option will be added to the [libddcutil] section of configuration file ddcutilrc. It can also be included in the options string passed in the opts argument to ddca_init2(). - Display change detection can be completely disabled using libddcutil only
option --disable-watch-displays. This blocks ddca_start_watch_displays() from starting the thread that watches
for display changes. Workaround for github issue 470.
Unlike the use of KDE Plasma environment variable POWERDEVIL_NO_DDCUTIL=1, this disables display change detection
while leaving other libddcutil services available.
-
In addition to the named option, several utility options currently affect display change detection. Some of these will become named options when ddcutil version 2.2.0 is released, others will be removed once testing is finished.
- --f17 do not use sysfs connector_id (default is to use it)
- --f18 always report UDEV events
- --f20 do not try to avoid rechecking DDC responsiveness when a display is reconnected (default is to remember prior checks)
- --f21 always treat sysfs as unreliable for reporting display changes
- --f22 never treat sysfs as unreliable for reporting display changes
- --i6 watch loop sleep multiplier (multiply default watch loop settings)
- --i7 extra stabilization milliseconds after apparent disconnection
- --i8 explicit udev poll loop milliseconds (takes precedence over --i6)
- --i9 explicit non-udev poll loop milllisec (takes precedence over --i6)
- As the requirements become clearer, it is expected that the API will add functionality currently specified only as libddcutil options.
Other Shared Library Changes
Quiesce operation:
- Quiesce the API during ddca_redetect_displays(). Operations that access
display state are not permitted, and return DDCRC_QUIESCED.
Status codes:
- Most functions that specify a DDCA_Display_Ref now return status code
DDCRC_DISCONNECTED if the display reference is no longer valid.
- Status code DDCRC_INVALID_CONFIG_FILE has been renamed to more general DDCRC_CONFIG_ERROR,
and is used instead of DDCRC_BAD_DATA for User Defined Feature File errors.
DDCRC_INVALID_CONFIG_FILE is a valid alias.
System log:
- Write build date and time to system log when starting libddcutil.
- Rework libdccutil output to avoid duplicate msgs in the system log when all terminal
output is directed to the log, as with KDE Plasma.
- Include thread id in messages written to syslog.
Miscellaneous:
- Use mutexes to control access to corruptable data structures, such as the table of open monitors.
- Recover instead of abort when more than one non-removed display refs exist
for the same display.
- Enum value DDCA_STATS_API is added to enum DDCA_Stats_Type, for reporting API specific stats.
- ddca_start_watch_displays():
Fixed segfault that occured with driver nvidia when checking if all video
adapters implement drm. Addresses github issue 390:libddcutil -3021 "DDCRC_INTERNAL_ERROR".
- During initial display reference validation, an otherwise valid display reference may be
for a removed display. Avoid a segfault in this case.
Addresses github issue 418:libddcutil behaves differently/fails after a hotplug compared to ddcutil.
- Ignore phantom displays when searching for a display reference.
Addresses github issue 412:"Display not found" when using model / sn / mfg flags on ddcutil 2.1.4.
- ddca_get_display_refs() and ddca_get_display_info_list2() always
return 0, even if an error occured when examining a particular monitor.
Addresses github issue 417:libddcutil ddca_get_display_info_list2 returns DDCRC_OTHER (-3022)
- Errors that occur opening individual displays or reading their EDIDs are
are still reported using ddca_get_error_detail(). In addition, error
messages are written to the terminal and, depending on the current
syslog level, to the system log.
- It is useful to create a string representation of a display reference even
if it is no longer valid. Addresses github ddcui issue 55:
ddcui-0.5.x: IOT instruction (core dumped.