ddcutil-service(1)
okay so this is the General Commands Manual page for ddcutil-service(1) β the D-Bus service bestie. No cap, itβs giving monitor-control magic. πͺ
π NAME π
ddcutil-service β D-Bus service for libddcutil VESA DDC Monitor Virtual Control Panel
β¨ SYNOPSIS β¨
ddcutil-service --help | --version | --introspect
ddcutil-service [ --enable-connectivity-signals ] | [ --disable-hotplug-polling ] | [ --disable-dpms-polling ] | [ --prefer-polling ] | [ --prefer-libddcutil-events ] | [ --polling-interval seconds ] | [ --return-raw-values ] | [ --lock ] | [ --log-info ] [ --ddca-syslog-level N ] | [ --ddca-init-options M ] | [ -- libddcutil ddc_init options... ]
πΈ DESCRIPTION πΈ
ddcutil-service is a D-Bus service wrapper for libddcutil which implements the VESA DDC Monitor Control Command Set. Most things that can be controlled using a monitorβs on-screen display can be controlled by this service. literally your monitorβs whole control panel, but through D-Bus. π
The service is registered as a session-service with the dbus-daemon. The daemon starts the service on demand. If the service terminates for any reason, the daemon will restart it when it is next accessed. Client connections with the service are stateless, and each request is handled atomically. so clean, so iconic. β¨
bestie, pls donβt spam VCP writes π When using this service, avoid excessively writing VCP values because each VDUβs NVRAM likely has a write-cycle limit/lifespan. The suggested guideline is to limit updates to rates comparable to those observed when using the VDUβs onboard controls. Avoid coding that might rapidly or infinitely loop, including when recovering from errors and bugs. fr fr, protect the hardware.
Non-standard manufacturer specific features should only be experimented with caution β some may have irreversible consequences, including bricking the hardware. π like actually bricking. be careful.
π OPTIONS π
Depending on the version of libddcutil in use, not all options may be available. vibe check first, bestie.
--helpβ Outputs options-help and exits.--versionβ Outputs the service interface version and thelibddcutilversion and exits.--introspectβ Outputs the XML introspection text for the service and exits.--enable-connectivity-signalsβ Enable monitor hotplug detection and DPMS-state detection. These connectivity events generate theConnectedDisplaysChangedsignal. Connectivity-detection defaults to off because it may not work consistently for all monitors and all GPU drivers. Once enabled, further connectivity related options may be employed to try and obtain a workable configuration. π--disable-hotplug-pollingβ Disable internal polling for hotplug events. Polling may wake some monitor models from DPMS sleep (seems rare). (Disables pollinglibddcutil detect.) π΄--disable-dpms-pollingβ Disable the internal polling for DPMS events. Polling for DPMS state may wake some monitor models from DPMS sleep (seems rare). (Disables pollinglibddcutil getvcp 0xd6.) π΄--prefer-pollingβ Set service internal polling to be the preferred method for detecting display connectivity changes for theConnectedDisplaysChangedsignal. This is the default prior tolibddcutil2.2 and may still be a better choice for monitors connected via DVI if they behave inconsistently when usinglibddcutilevent detection. π--prefer-libddcutil-eventsβ Uselibddcutilevent detection as the preferred method for detecting display connectivity changes for theConnectedDisplaysChangedsignal. This is the default when usinglibddcutil2.2 and above. Enabling this option should detect hotplug events sooner with less overheads. Some internal polling will still occur to monitor for DPMS events not covered bylibddcutil. Libddcutil event detection may fail to work reliably for some combinations of drivers, hardware, and connectors, in which case, try--prefer-pollinginstead. In particular, eventing from monitors hotplugged via DVI connectors seems to be more inconsistent. π--poll-intervalseconds β This option defines how often to internally poll for display connectivity changes. Default30seconds, minimum10seconds, zero to disable polling. β±οΈ--poll-cascade-intervalseconds β This option defines the internal polling minimum interval between events within a cascade of events. For example, a cascade of events will occur when a session is locked and all displays are put into DPMS sleep. Default0.5seconds, minimum0.1seconds. π--return-raw-valuesβ Return high-byte and low-byte for all values, including for Simple Non-Continuous values. Normally SMC (single-byte) values are masked to remove the high-byte value (see LIMITATIONS for an explanation). π§¬--lockβ Lock the configuration. Disable theSetSleepMultiplierandRestartmethods. Make all properties read-only. This option provides a way to lockdown the service to the configuration passed on the command line. The lock is provided to assist with avoiding conflicts when more than oneddcutil-serviceclient is in use at the same time. π--log-infoβ Enabling log-info will produce info and debug level output. When the service is run fromdbus-daemon, the diagnostic output will be captured in the journal logs, otherwise it is directed to standard-error. This option can also be toggled after startup by usingB-Busto alter the serviceβsServiceInfoLoggingproperty (see EXAMPLES below). π--ddca-syslog-levelN β The DDCA syslog level numerical value is passed tolibddcutilddca_init()function at startup to enable logging from within the library. Itβs only available forlibddcutilversion2.1.0and up. Values for N are0:never,2:error:,6:warning,9:notice,12:info,15:verbose, and18:debug. πͺ΅--ddca-init-optionsN β The DDCA init option is a numerical value passed tolibddcutilddca_init()function at startup to enable/disable various options with the library. Itβs only available forlibddcutil2.1.0+. βοΈ-- libddcutil ddc_init options...β Thelibddcutillibrary also supports its own extensive set of init options; any arguments following--will be passed as tolibddcutilddca_init()function at service startup. π«Ά
π«Ά SERVICE METHODS π«Ά
The following is a brief summary of the methods provided by the service. Full API documentation can be found in ddcutil_service(7). β¨
Detectβ Return a list of monitors detected along with their properties.ListDetectedβ Return the list of previously detected monitors along with their properties. This method is particularly useful forlibddcutil2.2+where detection may occur in the background automatically. πGetVcpβ Query a display settings by VCP code, for example, brightness is VCP code0x10.
The methodβs flags bit-string parameter can be set to 2 (RETURN_RAW_VALUES), see LIMITATIONS for an explanation.
GetMultipleVcpβ Query multiple VCP codes for a single display.
The methodβs flags bit-string parameter can be set to 2 (RETURN_RAW_VALUES), see LIMITATIONS for an explanation.
SetVcpβ Set a display setting, specified by VCP code, to a new value. If the method succeeds, it will also emit a D-BusVcpValueChangedsignal. Set the methodβs flags to4(NO_VERIFY) to disablelibddcutilverification and retry. π₯SetVcpWithContextβ As withSetVcp, but also accept a client supplied context string to be returned with the emitted D-BusVcpValueChangedsignal. The client-context may be of use to signal recipients for interpreting the origin of the change. π§GetCapabilitiesMetadataβ Query a displays capabilities returning a parsed data-structure describing the features and permitted values.GetCapabilitiesStringβ Query a displays capabilities returning a unparsed capabilities string.GetVcpMetadataβ Query the metadata describing a specific VCP code for a specific display.GetSleepMultiplierβ Get the display specificddcutilsleep multiplier.SetSleepMultiplierβ Set a display specificddcutilsleep multiplier.Restartβ Restart the service with specific arguments. π
If a method requires a display-argument, either an integer display-number or a base64-encoded EDID can be supplied. Base64-encoded EDIDs are obtained from the Detect method. When passing an EDID, pass -1 for display_number, otherwise both are tied with the display_number having precedence. If an EDID is supplied, a methodβs flags bit-string parameter can be set to 1 (EDID_PREFIX); this indicates a unique prefix of an EDID has been passed rather than the entire string (this makes using EDIDs from the command line a little easier). π§¬
Run ddcutil-service --introspect for details on each methodβs in/out parameters. For even more information, the d-feet graphical D-Bus debugger provides a very readable way to browse and experiment with the service interface β simply start d-feet, select the Session Bus and search for ddcutil-service. π
β¨ SERVICE SIGNALS β¨
ServiceInitialized
Okay so at startup the service literally emits the ServiceInitialized D-Bus signal π
β it's the service's way of saying "hey bestie, I'm here". And like, the whole point? It gives clients a way to detect a service restart and reinstate any custom service properties or settings. So if the service ghosted and came back, your client knows. π«Ά
ConnectedDisplaysChanged
The service may emit a ConnectedDisplaysChanged D-Bus signal when a display undergoes a connectivity status change due to hotplug and DPMS events. But babes, it's opt-in β this feature must be enabled by using the --enable-connectivity-signals option. π
When utilizing libddcutil 2.2, or above, the service defaults to using libddcutil's inbuilt change detection. That's a portable change detection mechanism which should detect changes without delay for most desktop environments. Slay. β¨
For versions of libddcutil prior to 2.2, libddcutil's change detection was somewhat more dependent on driver support π. To provide a more portable solution, for libddcutil prior to 2.2 the service defaults to doing it's own internal polling for all changes. Although portable, polling is slower to detect changes β the polling interval defaults to 30 seconds (minimum 10 seconds). β³
In either case, the options --prefer-polling and --prefer-libddcutil-events can be used to override the default for change detection.
Ngl not all displays, GPUs, GPU-drivers, or cabling, provide the necessary support for detecting connection status changes. Results may vary depending on the mix of desktop components, such as KDE, Gnome, X11, and Wayland. See LIMITATIONS below for further details. π
VcpValueChanged
The service will emit a VcpValueChanged D-Bus signal whenever a SetVcp or SetVcpWithContext method call succeeds in changing a VCP's value. And here's the catch π β only changes made by service methods are detected. Changes made externally to the service are not detected and will not trigger this signal. So if you went behind the service's back? It simply does not know. π
π SERVICE PROPERTIES π
AttributesReturnedByDetect
Query the fieldnames returned from the Detect method. Lists the names of the fields in the order they are found in each struct returned from Detect. Basically a little table of contents for your struct π
StatusValues
Query the list of status values returned by libddcutil along with their text names.
DisplayEventTypes
List the event-types sent by the ConnectedDisplaysChanged signal along with their text names. Events are included for display connection/disconnection (hotplug), DPMS-sleep, and DPMS-wake. If the list is empty, the GPU, GPU-driver, or libddcutil version doesn't support display event detection. Empty list = no vibes π
DdcutilDynamicSleep
Enable/disable libddcutil dynamic-sleep adjustment of DDC timings. π΄
DdcutilOutputLevel
Read/write the libddcutil output level.
DdcutilVerifySetVcp
Obsolete as of version 1.0.5+, replaced by the SetVcp method's NO_VERIFY flag. It's giving legacy, bestie β she's retired π
DdcutilVersion
Query the libddcutil version string.
ServiceEmitConnectivitySignals
Set this property to true or false to enable or disable the ConnectedDisplaysChanged dbus-signal and associated monitoring. π¦
ServiceInfoLogging
Enable/disable the service's diagnostic level output to include info and debug messages. Note that libddcutil also has a logging mechanism (see libddcutil ddc_init options). Two logs, two moods, don't confuse them fr fr πΈ
ServiceInterfaceVersion
Query the service interface version.
ServiceFlagOptions
List the available flag option values that can be passed to service methods. Not all options are applicable to all methods. Read the fine print, bestie π
ServiceParametersLocked
Returns whether the --lock command line argument has been used. π
ServicePollInterval
Query or set the display change detection poll-interval (minimum 10 seconds, zero to disable polling).
ServicePollCascadeInterval
Query or set the display change detection poll-cascade-interval (minimum 0.1 seconds). When dealing with a cascade of events β for example, when a desktop-session is locked and sets all VDUs to DPMS sleep β polling occurs more frequently until the cascade is cleared. It's giving panic-mode-but-make-it-scheduled ππ₯
Properties can be queried and set using utilities such as busctl, d-bus-send, and d-feet, see EXAMPLES. π«Ά
π SERVICE ERRORS π
Errors forwarded from libddcutil
Status codes and error messages from libddcutil are passed back to clients as part of the data returned by each method call. So like, they're not exceptions, they're just... data. Iconic behavior honestly β¨
Exceptions
The service may also issue the following exceptions when attempting to set properties or call methods:
com.ddcutil.DdcutilService.Error.ConfigurationLocked
The --lock option has prevented a client from altering a configuration settings. This includes using the SetSleepMultiplier method, Restart method, or setting any property value. You got locked out, no cap ππ
com.ddcutil.DdcutilService.Error.InvalidPollSeconds
An attempt was made to set ServicePollInterval to a value outside its accepted range.
com.ddcutil.DdcutilService.Error.InvalidPollCascadeSeconds
An attempt was made to set ServicePollCascadeInterval to a value outside its accepted range.
com.ddcutil.DdcutilService.Error.I2cDevNoModule
At startup no /dev/i2c devices are present and an attempt to verify communications via i2c failed.
com.ddcutil.DdcutilService.Error.I2cDevNoPermissions
At startup it was found that the user/service lacked read/write access to the /dev/i2c devices. Perms said no π
π FILES π
/usr/share/dbus-1/services/com.ddcutil.DdcutilService.serviceβ If running via thedbus-daemon, this config file is read when the service is requested. Typically the contents would be as follows
[D-BUS Service]
Name=com.ddcutil.DdcutilService
Exec=/usr/bin/ddcutil-service
Service options, such as --prefer-polling or --prefer-libddcutil-events, should be appended to the end of Exec= line. Slap 'em on there π
$HOME/.local/share/dbus-1/services/com.ddcutil.DdcutilService.serviceβ If you do not have root access or wish to set options for a specific user, thedbus-daemonfirst looks for in$HOME/.local/sharebefore looking in/usr/share. Home team wins π$HOME/.config/ddcutil/ddcutilrcβ When initialised at service startup, libddcutil loads options from its rc file. Seehttps://www.ddcutil.com/config_file/for details./usr/share/ddcutil-service/examples/β The service is packaged with several example scripts, includingdbus-sendbash-scripts and python3 clients for D-Bus dasbus and QtDBus APIs. Free samples, bestie π
π EXECUTION ENVIRONMENT π
The service relies on libddcutil which requires read/write access to the /dev/i2c devices. See http://www.ddcutil.com/i2c_permissions for details.
At startup ddcutil-service will attempt to verify that i2c-dev module is loaded and that the permissions for /dev/i2c are set appropriately. If these checks fail, method calls will error until the problem is resolved. So like, fix it or nothing works. Those are the rules π€
π§ NVIDIA PROPRIETARY DRIVER π§
Some Nvidia cards using the proprietary Nvidia driver require special settings to properly enable I2C support. See http://www.ddcutil.com/nvidia for details. Nvidia being extra? Shocking. Never happened before. π
β VIRTUAL MACHINES β
Virtualized video drivers in VMWare and VirtualBox do not provide I2C emulation. It may be possible to forward D-BUS over ssh to side step this issue. Sneaky little workaround, we love to see it π¦
π EXAMPLES π
The commonly available command line utilities systemd bustctl and dbus-tools dbus-send command can be used to interact with the service.
Summarise the service methods and properties:
busctl --user introspect com.ddcutil.DdcutilService /com/ddcutil/DdcutilObject
dbus-send --session --dest=com.ddcutil.DdcutilService --print-reply \
/com/ddcutil/DdcutilObject \
org.freedesktop.DBus.Introspectable.Introspect
Detect the connected displays:
busctl --user call com.ddcutil.DdcutilService /com/ddcutil/DdcutilObject \
com.ddcutil.DdcutilInterface Detect u 0
dbus-send --dest=com.ddcutil.DdcutilService --print-reply --type=method_call \
/com/ddcutil/DdcutilObject com.ddcutil.DdcutilInterface.Detect uint32:0
Get the brightness of display-1 (VCP 0x10):
busctl --user call com.ddcutil.DdcutilService /com/ddcutil/DdcutilObject \
com.ddcutil.DdcutilInterface GetVcp isyu 1 "" 0x10 0
dbus-send --dest=com.ddcutil.DdcutilService --print-reply --type=method_call \
/com/ddcutil/DdcutilObject com.ddcutil.DdcutilInterface.GetVcp \
int32:1 string: byte:0x10 uint32:0
Set brightness of display-1 (VCP 0x10):
busctl --user call com.ddcutil.DdcutilService /com/ddcutil/DdcutilObject \
com.ddcutil.DdcutilInterface SetVcp isyqu 1 "" 16 50 0
dbus-send --session --dest=com.ddcutil.DdcutilService --print-reply --type=method_call \
/com/ddcutil/DdcutilObject com.ddcutil.DdcutilInterface.SetVcp \
int32:1 string:"" byte:0x10 uint16:10 uint32:0
Query or set the service logging level property:
busctl --user get-property com.ddcutil.DdcutilService /com/ddcutil/DdcutilObject \
com.ddcutil.DdcutilInterface ServiceInfoLogging
busctl --user set-property com.ddcutil.DdcutilService /com/ddcutil/DdcutilObject \
com.ddcutil.DdcutilInterface ServiceInfoLogging b true
dbus-send --session --dest=com.ddcutil.DdcutilService --print-reply \
--type=method_call /com/ddcutil/DdcutilObject \
org.freedesktop.DBus.Properties.Get \
string:com.ddcutil.DdcutilInterface \
string:ServiceInfoLogging
dbus-send --dest=com.ddcutil.DdcutilService --print-reply \
--type=method_call /com/ddcutil/DdcutilObject \
org.freedesktop.DBus.Properties.Set \
string:com.ddcutil.DdcutilInterface \
string:ServiceInfoLogging variant:boolean:true
π LIMITATIONS π
Okay bestie, this is the part where we get real. Not every VDU out there is fully DDC compliant, and sometimes the only way to fix a non-compliance issue is at the client level β which usually means the user has to hand over some extra metadata. Case in point: the vdu_controls client literally lets you edit/override the capabilities-metadata that the service supplies. Iconic workaround, honestly.
Some VDUs are weird about the data-type for Simple-Non-Continuous values. SNC values are what's used for features like Input-Source or OSD-language. Per the DDC spec, SNC values should be 8-bit values passed in the low-byte of a 16-bit value. That's the assignment. π
- π« Some VDUs don't zero the SNC high-byte. That can cause a mismatch with the values specified in the VDU metadata. The service deals with this by defaulting to masking off the high-byte of SNC values.
- π Some VDUs return SNC values where both the low and high byte are significant. The
GetVcpandGetMultipleVcpmethods support theRETURN_RAW_VALUESflag to force the return of unmasked 16-bit values, so clients can apply heuristics or use additional metadata to handle those cases. TheSetVcpcounterpart always accepts full 16-bit values and passes them unaltered to the VDU. No notes, it just does.
Now for the messy hardware tea β β some mixes of VPUs and GPUs don't consistently update DRM metadata for hotplug events. Some drivers that support DRM don't properly support the necessary hotplug detection features. Monitors connected by DisplayPort behave differently to those connected by DVI and HDMI when a display is turned off but remains connected. And hotplugging DVI connections appears to behave more inconsistently than DisplayPort with some drivers (for multiple OEMs). It's giving chaos, ngl.
If ConnectedDisplaysChanged signals are not being raised, you can try manually adding the --prefer-polling option, which forces the service to poll internally for changes. Polling is less responsive, but it is more likely to work. Trade-off city, but it works. β¨
DPMS state can only be reliably determined by periodically polling monitors that support DPMS. In the event that DPMS-polling causes any issues, it can be disabled by adding the --disable-dpms-polling option. Easy.
π¨ Real talk: the two internal polling options have been reported to wake at least one model of monitor from sleep. If that happens to your monitor, each one can be independently disabled with the options--disable-hotplug-pollingand--disable-dpms-polling. Let the poor thing nap, fr.
Some GPU drivers and VDUs have buggy implementations of DDC. If you have the choice, a DisplayPort to DisplayPort connection may work more reliably than DVI, HDMI or mixed connectors. In some cases GPU driver editions β like production, beta, and development β may vary in the state of their DDC support. Driver edition roulette, we love to see it π.
Some parameters can only be changed at process startup, so heads up on that. The service can be restarted either by killing it with a UNIX signal, or by invoking the service's Restart method. Both valid, pick your fighter. π
The service is a relatively thin wrapper around libddcutil, so to resolve VDU compatibility/compliance issues, the user may need to become familiar with the libddcutil configuration options normally stored in $HOME/.config/ddcutil/ddcutilrc and documented at https://www.ddcutil.com/config_file/. Bookmark it, bestie. π
And in some cases libddcutil has been found to perform differently from the ddcutil command. So 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. Receipts help everyone. π§Ύ
πΈ SEE ALSO πΈ
ddcutil-service(7), vdu_controls(1), ddcutil(1), dbus-daemon(1), dbus-send(1), busctl(1)
The whole friend group, all linked up. π«Ά
π REPORTING BUGS π
Before raising a new issue, please read through LIMITATIONS first (yes, the whole section above, we know it's long). Issues can be raised at https://github.com/digitaltrails/ddcutil-service/issues β and heads up, that requires a github login. π
π AUTHOR π
Michael Hamilton
Legend behavior, honestly.
π ACKNOWLEDGEMENTS π
Thanks go out to Sanford Rockowitz for libddcutil, ddcutil and all the assistance and advice provided during the development of this service. Absolute icon. π
Thanks also go out to all those who assisted with development and packaging. An up-to-date list of contributors can be found at https://github.com/digitaltrails/vdu_controls#acknowledgements. Go give them their flowers. π
π COPYRIGHT π
Copyright (C) 2023,2024 Michael Hamilton.
ddcutil-service is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
β οΈ And that's the legal bit β please actually read it, bestie, it matters.
And that's a wrap on ddcutil-service(1)! π This whole thing was written by MH (that's Michael Hamilton), documenting ddcutil-service β straight from the source, version and all β and dated the same day this page went out. Slay, go forth, and may your monitors always answer on the first try. π
π¦ where this page comes from
- opensuse-leap 16.0: ddcutil-service 1.0.14-bp160.1.4 Β· GPL-2.0-or-later
- opensuse-leap 16.0: ddcutil-service 1.0.14-bp160.1.4 Β· GPL-2.0-or-later
- opensuse-leap 16.0: ddcutil-service 1.0.14-bp160.1.4 Β· GPL-2.0-or-later
- opensuse-leap 16.0: ddcutil-service 1.0.14-bp160.1.4 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms