Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package ddcutil-service for
openSUSE:Leap:16.0 checked in at 2025-05-26 10:07:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:16.0/ddcutil-service (Old)
and /work/SRC/openSUSE:Leap:16.0/.ddcutil-service.new.2732 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ddcutil-service"
Mon May 26 10:07:03 2025 rev:2 rq:1279314 version:1.0.14
Changes:
--------
--- /work/SRC/openSUSE:Leap:16.0/ddcutil-service/ddcutil-service.changes
2025-03-19 11:41:38.356909152 +0100
+++
/work/SRC/openSUSE:Leap:16.0/.ddcutil-service.new.2732/ddcutil-service.changes
2025-05-26 10:07:04.583856706 +0200
@@ -1,0 +2,23 @@
+Sat Mar 8 21:34:11 UTC 2025 - Michael Hamilton <[email protected]>
+
+- 1.0.14
+ - A hotplug and DPMS tidy up to accommodate quirks exhibited by drivers,
GPUs and monitors.
+ - Default to libddcutil event detection for libddcutil >= 2.2 (for faster
response to changes).
+ - Add option --prefer-libddcutil-events as a better name for deprecated
option --prefer-drm.
+ - Deprecate option --prefer-drm as it's name is misleading.
+ - Add option --disable-connectivity-signals to allow connectivity signals to
be turned off.
+ - Add options --disable-hotplug-polling and --disable-dpms-polling to
accommodate quirky monitors.
+ - Always internally poll for DPMS changes (DPMS is not covered by libddcutil
events).
+ - Add method ListDetected to take advantage of hotplug detection in
libddcutil >= 2.2.
+ - Add the list command to ddcutil-client to provide access to the new
ListDetected method.
+ - Add wait, wait-connection-change, and wait-vcp-change commands to
ddcutil-client.
+ - Log more information when get_vcp fails.
+
+
+-------------------------------------------------------------------
+Wed Nov 27 19:36:37 UTC 2024 - Michael Hamilton <[email protected]>
+
+- 1.0.12
+ - Return the error status-code if enable_ddca_watch_displays fails - was
returning OK even on failure.
+
+-------------------------------------------------------------------
Old:
----
ddcutil-service-1.0.11.tar.gz
New:
----
ddcutil-service-1.0.14.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ddcutil-service.spec ++++++
--- /var/tmp/diff_new_pack.HArIPG/_old 2025-05-26 10:07:05.935913282 +0200
+++ /var/tmp/diff_new_pack.HArIPG/_new 2025-05-26 10:07:05.947913784 +0200
@@ -18,7 +18,7 @@
Name: ddcutil-service
-Version: 1.0.11
+Version: 1.0.14
Release: 0
Summary: D-Bus service for libddcutil VESA DDC Monitor Virtual Control
Panel
License: GPL-2.0-or-later
++++++ ddcutil-service-1.0.11.tar.gz -> ddcutil-service-1.0.14.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ddcutil-service-1.0.11/Makefile
new/ddcutil-service-1.0.14/Makefile
--- old/ddcutil-service-1.0.11/Makefile 2024-08-22 03:59:06.000000000 +0200
+++ new/ddcutil-service-1.0.14/Makefile 2025-03-08 21:14:51.000000000 +0100
@@ -8,6 +8,7 @@
#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
+#CFLAGS_DDCUTIL = -isystem $(HOME)/Downloads/ddcutil-2.2.0/src/public -L
$(HOME)/Downloads/ddcutil-2.2.0/src/.libs -lddcutil
CFLAGS += -g -std=gnu11 -Werror -Wall -Wformat-security -Og
SOURCE = ddcutil-service.c
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ddcutil-service-1.0.11/README.md
new/ddcutil-service-1.0.14/README.md
--- old/ddcutil-service-1.0.11/README.md 2024-08-22 03:59:06.000000000
+0200
+++ new/ddcutil-service-1.0.14/README.md 2025-03-08 21:14:51.000000000
+0100
@@ -139,6 +139,23 @@
granting the [Open Source development license](
https://jb.gg/OpenSourceSupport).
### Version History
+- 1.0.14
+ - Default to libddcutil event detection for libddcutil >= 2.2 (for faster
response to changes).
+ - Add option --prefer-libddcutil-events as a better name for deprecated
option --prefer-drm.
+ - Deprecate option --prefer-drm as it's name is misleading.
+ - Add option --disable-connectivity-signals to allow connectivity signals to
be turned off.
+ - Add options --disable-hotplug-polling and --disable-dpms-polling to
accommodate quirky monitors.
+ - Always internally poll for DPMS changes (DPMS is not covered by libddcutil
events).
+ - Add method ListDetected to take advantage of hotplug detection in
libddcutil >= 2.2.
+ - Add the list command to ddcutil-client to provide access to the new
ListDetected method.
+ - Add wait, wait-connection-change, and wait-vcp-change commands to
ddcutil-client.
+ - Log more information when get_vcp fails.
+- 1.0.13
+ - Version 1.0.13 existed in development for some months, but was not
released.
+ - Connectivity DBUS signalling was going to be on by default, but drivers,
GPUs, and
+ monitors proved too inconsistent.
+- 1.0.12
+ - Return the error status-code if enable_ddca_watch_displays fails - was
returning OK even on failure.
- 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.
@@ -147,8 +164,8 @@
- 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.
- - Fixed potential hot-plug/DPMS polling memory leaks and simplified event
locking.
- - Recoded hot-plug/DPMS polling to avoid a potential libddcutil assertion
failure.
+ - Fixed potential hotplug/DPMS polling memory leaks and simplified event
locking.
+ - Recoded hotplug/DPMS polling to avoid a potential libddcutil assertion
failure.
- Fixed code/doc typos, improved code readability/structure, reduced IDE
warnings.
- Updated documentation to caution against excessive updates when coding
loops, as this may impact VDU NVRAM lifespan.
- Updated documentation to caution against experimenting with non-standard
features, as it may risk damage to the VDU.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ddcutil-service-1.0.11/ddcutil-client.1
new/ddcutil-service-1.0.14/ddcutil-client.1
--- old/ddcutil-service-1.0.11/ddcutil-client.1 2024-08-22 03:59:06.000000000
+0200
+++ new/ddcutil-service-1.0.14/ddcutil-client.1 2025-03-08 21:14:51.000000000
+0100
@@ -25,6 +25,9 @@
.B detect
Detect connected displays.
.TP
+.B list
+List the currently detected VDUs without performing using a new detect.
+.TP
.B capabilities
Display detailed capabilities of the specified display in a indented format
and include value option names.
.TP
@@ -37,8 +40,17 @@
.B setvcp \fI0xNN n\fR
Set the value of the VCP code specified by \fI0xNN\fR to \fIn\fR.
.TP
-.B getvcp-metadata \fI0xNN
+.B getvcp-metadata \fI0xNN\fR
Get the metadata for the VCP code specified by \fI0xNN\fR.
+.TP
+.B wait-for-connection-change
+Wait for a \fBConnectedDisplaysChanged\fR signal, then exit.
+.TP
+.B wait-for-vcp-change
+Wait for a \fBVcpValueChanged\fR signal, then exit.
+.TP
+.B wait
+Wait for a \fBConnectedDisplaysChanged\fR or \fBVcpValueChanged\fR signal,
then exit.
.SH OPTIONS
.TP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ddcutil-service-1.0.11/ddcutil-client.c
new/ddcutil-service-1.0.14/ddcutil-client.c
--- old/ddcutil-service-1.0.11/ddcutil-client.c 2024-08-22 03:59:06.000000000
+0200
+++ new/ddcutil-service-1.0.14/ddcutil-client.c 2025-03-08 21:14:51.000000000
+0100
@@ -357,8 +357,8 @@
* @param connection dbus connection to ddcutil-service
* @return COMPLETED_WITHOUT_ERROR, SERVICE_ERROR or DBUS_ERROR
*/
-static cmd_status_t call_detect(GDBusConnection *connection) {
- const char *operation_name = "Detect";
+static cmd_status_t call_detect(GDBusConnection *connection, gboolean
list_only) {
+ const char *operation_name = list_only ? "ListDetected" : "Detect" ;
GError *error = NULL;
GVariant *result;
@@ -484,6 +484,42 @@
return handle_dbus_error("set_property", error);
}
+void waiter(GDBusConnection* connection,
+ const gchar* sender_name,
+ const gchar* object_path,
+ const gchar* interface_name,
+ const gchar* signal_name,
+ GVariant* parameters,
+ gpointer user_data) {
+ g_print("Recieved signal %s %s\n", signal_name,
g_variant_print(parameters, FALSE));
+ exit(0);
+}
+
+cmd_status_t wait_for_signal(gchar* signals[]) {
+ for (gchar **ptr = signals; *ptr; ptr++) {
+ const gchar *signal_name = *ptr;
+ guint id = g_dbus_connection_signal_subscribe(connection,
+ DBUS_BUS_NAME,
+ DBUS_INTERFACE_NAME,
+ signal_name,
+ NULL,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ waiter,
+ NULL,
+ NULL);
+ if (id != 0) {
+ g_print("waiting for %s signal...\n", signal_name);
+ }
+ else {
+ g_print("failed to wait for %s signal\n", signal_name);
+ return -1;
+ }
+ }
+ g_main_loop_run(g_main_loop_new(NULL, 0));
+ return 0;
+}
+
/**
* Parse a command line int argument using strtol
* @param input_str the command line argument
@@ -616,7 +652,7 @@
};
context = g_option_context_new(
- "[detect | capabilities | capabilities-terse | getvcp 0xNN |
setvcp 0xNN n]");
+ "[detect | list | capabilities | capabilities-terse | getvcp 0xNN
| setvcp 0xNN n | wait-for-connection-change | wait-for-vcp-change | wait]");
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);
@@ -678,7 +714,9 @@
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);
+ exit_status = call_detect(connection, FALSE);
+ } else if (g_strcmp0(method, "list") == 0) {
+ exit_status = call_detect(connection, TRUE);
} else if (g_strcmp0(method, "setvcp") == 0) {
exit_status = parse_display_and_edid(&display_number, edid_txt);
if (exit_status == COMPLETED_WITHOUT_ERROR) {
@@ -743,7 +781,16 @@
if (exit_status == COMPLETED_WITHOUT_ERROR) {
exit_status = call_capabilities(connection, display_number,
edid_txt);
}
- } else {
+ } else if (g_strcmp0(method, "wait-for-connection-change") == 0) {
+ gchar* signals[] = {"ConnectedDisplaysChanged", NULL};
+ exit_status = wait_for_signal(signals);
+ } else if (g_strcmp0(method, "wait-for-vcp-change") == 0) {
+ gchar* signals[] = {"VcpValueChanged", NULL};
+ exit_status = wait_for_signal(signals);
+ } else if (g_strcmp0(method, "wait") == 0) {
+ gchar* signals[] = {"ConnectedDisplaysChanged", "VcpValueChanged",
NULL};
+ exit_status = wait_for_signal(signals);
+ } else {
g_printerr("ERROR: Unknown command: %s\n", method);
exit_status = SYNTAX_ERROR;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ddcutil-service-1.0.11/ddcutil-service.1
new/ddcutil-service-1.0.14/ddcutil-service.1
--- old/ddcutil-service-1.0.11/ddcutil-service.1 2024-08-22
03:59:06.000000000 +0200
+++ new/ddcutil-service-1.0.14/ddcutil-service.1 2025-03-08
21:14:51.000000000 +0100
@@ -4,15 +4,23 @@
.SH SYNOPSIS
.B ddcutil-service
-.I --help
+.B --help
|
-.I --version
+.B --version
|
-.I --introspect
+.B --introspect
.br
.B ddcutil-service
[
-.B --emit-connectivity-signals
+.B --enable-connectivity-signals
+]
+|
+[
+.B --disable-hotplug-polling
+]
+|
+[
+.B --disable-dpms-polling
]
|
[
@@ -20,7 +28,7 @@
]
|
[
-.B --prefer-drm
+.B --prefer-libddcutil-events
]
|
[
@@ -100,41 +108,63 @@
Outputs the XML introspection text for the service and exits.
.TP
-.B "--emit-connectivity-signals"
+.B "--enable-connectivity-signals"
-Enable the
-.B ConnectedDisplaysChanged signal
-sent to clients and also enable any monitoring for changes.
-Once the service is running, this setting can be toggled by altering the
-.B ServiceEmitConnectivitySignals
-property.
-See \fBSERVICE SIGNALS\fP.
+Enable monitor hotplug detection and DPMS-state detection. These connectivity
+events generate the \fBConnectedDisplaysChanged signal\fP.
Connectivity-detection
+defaults to off because it may not work consistently for all monitors
+and all GPU drivers.
+One enabled, further connectivity related options may be employed to try and
+obtain a workable configuration.
+
+.TP
+.B "--disable-hotplug-polling"
+
+Disable internal polling for hotplug events.
+Polling may wake some monitor models from DPMS sleep (seems rare).
+(Disables polling \fBlibddcutil detect\fP.)
+
+.TP
+.B "--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 polling \fBlibddcutil getvcp 0xd6\fP.)
.TP
.B "--prefer-polling"
-Set polling to be the preferred method for detecting display connectivity
changes
-for the \fBConnectedDisplaysChanged signal\fP. This is the default.
+Set service internal polling to be the preferred method for detecting display
connectivity changes
+for the \fBConnectedDisplaysChanged signal\fP. This is the default prior to
\fBlibddcutil 2.2\fP
+and may still be a better choice for monitors connected via DVI if they behave
inconsistently
+when using libddcutil event detection.
.TP
-.B "--prefer-drm"
+.B "--prefer-libddcutil-events"
Use
-.B libddcutil DRM-lookups
+.B libddcutil event detection
as the preferred method for detecting display connectivity changes
-for the \fBConnectedDisplaysChanged signal\fP. This option should detect
changes sooner
-with less overheads, but may fail to detect changes for some combinations or
drivers and hardware.
+for the \fBConnectedDisplaysChanged signal\fP.
+This is the default when using \fBlibddcutil 2.2\fP 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 by libddcutil. Libddcutil event detection
+may fail to work reliably for some combinations of drivers, hardware,
+and connectors, in which case, try \fB--prefer-polling\fP instead.
+In particular, eventing from monitors hotplugged via DVI connectors seems
+to be more inconsistent.
.TP
.B "--poll-interval" \fIseconds\fP
-If polling is enabled, this option defines how often to check for display
+This option defines how often to internally poll for display
connectivity changes. Default 30 seconds, minimum 10 seconds, zero to
disable polling.
.TP
.B "--poll-cascade-interval" \fIseconds\fP
-If polling is enabled, this option defines the minimum interval between
+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.
Default 0.5 seconds, minimum 0.1 seconds.
@@ -214,6 +244,12 @@
Return a list of monitors detected along with their properties.
.TP
+.B ListDetected
+Return the list of previously detected monitors along with their properties.
+This method is particularly useful for \fBlibddcutil 2.2+\fP where detection
+may occur in the background automatically.
+
+.TP
.B GetVcp
Query a display settings by VCP code, for example, brightness is VCP code 0x10.
@@ -312,47 +348,32 @@
.TP
.B ConnectedDisplaysChanged
-The service may optionally emit a
+The service may emit a
.B ConnectedDisplaysChanged
D-Bus signal when a display undergoes a connectivity status change
-due to hot-plug and DPMS events.
-This feature is optional because the manual
-experimentation required to configure it is unnecessary for display
-configurations that remain static.
-
-Change-detection can be enabled by passing
-.B --emit-connectivity-signals
-on the command line, or by setting the
-.B ServiceEmitConnectivitySignals
-property.
+due to hotplug and DPMS events. This feature must be enabled
+by using the \fB--enable-connectivity-signals\fP option.
-To permanently enable change-detection, the
-.B --emit-connectivity-signals
-option can be appended to the
-.B Exec
-line of the
-system or user D-Bus
-.B com.ddcutil.DdcutilService.service
-file (see \fBFILES\fP).
-
-Changes are detected in one of two ways.
-The service defaults to periodic polling by
-issuing \fBlibddcutil DDCA detects\fP. Polling is
-likely to work for a wide variety of drivers and hardware.
-Polling for changes will be subject to delays because
-the polling interval defaults to 30 seconds (with a minimum of 10 seconds).
-Alternatively the service can use \fBlibddcutil DRM access \fP to provide
-a more efficient method for change detection,
-this requires \fBddcutil/libddcutil version 2.1.0+\fP, a GPU configured for
\fBDRM\fP, and
-the \fB--enable-watch-displays\fP to be added to \fI[libddcutil] options\fP
-in \fB$HOME/.config/ddcutil/ddcutilrc\fP.
+When utilizing libddcutil 2.2, or above, the service defaults to
+using libddcutil's inbuilt change detection. This is a portable change
+detection mechanism which should detect changes without delay for
+most desktop environments.
+
+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 \fB--prefer-polling\fP and
+\fB--prefer-libddcutil-events\fP can be used to override the default
+for change detection.
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.
-DisplayPort behaves differently to DVI and HDMI when
-a display is turned off but remains connected. Some drivers that
-support DRM don't properly support the necessary change detection features.
+See \fBLIMITATIONS\fP below for further details.
.TP
.B VcpValueChanged
@@ -385,7 +406,7 @@
List the event-types sent by the
.B ConnectedDisplaysChanged
signal along with their text names.
-Events are included for display connection/disconnection (hot-plug),
DPMS-sleep, and DPMS-wake.
+Events are included for display connection/disconnection (hotplug),
DPMS-sleep, and DPMS-wake.
If the list is empty, the GPU, GPU-driver, or
.B libddcutil
version doesn't support display event detection.
@@ -503,7 +524,7 @@
Exec=/usr/bin/ddcutil-service
.fi
-Service options, such as \fB--emit-connectivity-signals\fP or
\fB--prefer-drm\fP,
+Service options, such as \fB--prefer-polling\fP or
\fB--prefer-libddcutil-events\fP,
should be appended to the end of \fBExec=\fP line.
.TP
@@ -663,10 +684,27 @@
full 16-bit values and passes them unaltered to the VDU.
Some mixes of VPUs and GPUs don't consistently update
-DRM metadata for hot-plug events. If \fBConnectedDisplaysChanged\fP
-signals are not being raised, try manually adding \fB--prefer-polling\fP
-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.
+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.
+hotplugging DVI connections appear to behave more inconsistently
+than DisplayPort with some drivers (for multple OEMs).
+
+If \fBConnectedDisplaysChanged\fP signals are not being raised, you can
+try manually adding \fB--prefer-polling\fP option, to force the service to
+poll internally for changes. Polling is less responsive,
+but it is more likely to work.
+
+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 disabled
+by adding the \fB--disable-dpms-polling\fP option.
+
+The two internal polling options have been reported to wake at least
+one model of monitor from sleep. If this occurs, each can be independently
+disabled by the options \fB--disable-hotplug-polling\fP
+and \fB--disable-dpms-polling\fP.
Some GPU drivers and VDUs have buggy implementations of DDC.
If you have the choice, a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ddcutil-service-1.0.11/ddcutil-service.7
new/ddcutil-service-1.0.14/ddcutil-service.7
--- old/ddcutil-service-1.0.11/ddcutil-service.7 2024-08-22
03:59:06.000000000 +0200
+++ new/ddcutil-service-1.0.14/ddcutil-service.7 2025-03-08
21:14:51.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: com.ddcutil.DdcutilInterface
.\" Author: Michael Hamilton
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 07/02/2024
+.\" Date: 12/19/2024
.\" Manual: Miscellaneous
.\" Source: ddcutil-service
.\" Language: English
.\"
-.TH "COM\&.DDCUTIL\&.DDCU" "7" "07/02/2024" "ddcutil\-service" "Miscellaneous"
+.TH "COM\&.DDCUTIL\&.DDCU" "7" "12/19/2024" "ddcutil\-service" "Miscellaneous"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -42,6 +42,11 @@
OUT a(iiisssqsu) detected_displays,
OUT i error_status,
OUT s error_message);
+ListDetected (IN u flags,
+ OUT i number_of_displays,
+ OUT a(iiisssqsu) detected_displays,
+ OUT i error_status,
+ OUT s error_message);
GetVcp (IN i display_number,
IN s edid_txt,
IN y vcp_code,
@@ -260,6 +265,57 @@
.RE
.PP
OUT a(iiisssqsu) \fIdetected_displays\fR:
+.RS 4
+An array of structures describing the VDUs\&.
+.RE
+.PP
+OUT i \fIerror_status\fR:
+.RS 4
+A libddcutil DDCRC error status\&. DDCRC_OK (zero) if no errors have
occurred\&.
+.RE
+.PP
+OUT s \fIerror_message\fR:
+.RS 4
+Text message for error_status\&.
+.RE
+.SS "The ListDetected() method"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ListDetected (IN u flags,
+ OUT i number_of_displays,
+ OUT a(iiisssqsu) detected_displays,
+ OUT i error_status,
+ OUT s error_message);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Returns the currently detected VDUs without performing using a new detect\&.
This method is particularly useful for libddcutil 2\&.2+ where detection may
occur in the background automatically\&.
+.PP
+The array
+\fIdetected_displays\fR
+will be of length
+\fInumber_of_displays\fR\&.
+.PP
+Each element of
+\fIdetected_displays\fR
+array will contain the fields specified by the AttributesReturnedByDetect
property\&. The fields will include the libddcutil display\-number and a
base64\-encoded EDID\&.
+.PP
+IN u \fIflags\fR:
+.RS 4
+For future use
+.RE
+.PP
+OUT i \fInumber_of_displays\fR:
+.RS 4
+.sp
+.RE
+.PP
+OUT a(iiisssqsu) \fIdetected_displays\fR:
.RS 4
An array of structures describing the VDUs\&.
.RE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ddcutil-service-1.0.11/ddcutil-service.c
new/ddcutil-service-1.0.14/ddcutil-service.c
--- old/ddcutil-service-1.0.11/ddcutil-service.c 2024-08-22
03:59:06.000000000 +0200
+++ new/ddcutil-service-1.0.14/ddcutil-service.c 2025-03-08
21:14:51.000000000 +0100
@@ -58,7 +58,7 @@
#include <ddcutil_status_codes.h>
#include <ddcutil_macros.h>
-#define DDCUTIL_DBUS_INTERFACE_VERSION_STRING "1.0.11"
+#define DDCUTIL_DBUS_INTERFACE_VERSION_STRING "1.0.14"
#define DDCUTIL_DBUS_DOMAIN "com.ddcutil.DdcutilService"
#if DDCUTIL_VMAJOR == 2 && DDCUTIL_VMINOR == 0 && DDCUTIL_VMICRO < 2
@@ -176,6 +176,31 @@
</method>
<!--
+ ListDetected:
+ @flags: For future use
+ @detected_displays: An array of structures describing the VDUs.
+ @error_status: A libddcutil DDCRC error status. DDCRC_OK (zero) if no
errors have occurred.
+ @error_message: Text message for error_status.
+
+ Returns the currently detected VDUs without performing using a new
detect.
+ This method is particularly useful for libddcutil 2.2+ where detection
+ may occur in the background automatically.
+
+ The array @detected_displays will be of length @number_of_displays.
+
+ Each element of @detected_displays array will contain the fields
+ specified by the AttributesReturnedByDetect property. The fields
+ will include the libddcutil display-number and a base64-encoded EDID.
+ -->
+ <method name='ListDetected'>
+ <arg name='flags' type='u' direction='in'/>
+ <arg name='number_of_displays' type='i' direction='out'/>
+ <arg name='detected_displays' type='a(iiisssqsu)' direction='out'/>
+ <arg name='error_status' type='i' direction='out'/>
+ <arg name='error_message' type='s' direction='out'/>
+ </method>
+
+ <!--
GetVcp:
@display_number: The libddcutil/ddcutil display number to query
@edid_txt: The base-64 encoded EDID of the display
@@ -707,7 +732,7 @@
G_STATIC_ASSERT(G_N_ELEMENTS(flag_options) ==
G_N_ELEMENTS(flag_options_names)); // Boilerplate
/*
----------------------------------------------------------------------------------------------------
- * Define the service's connectivity monitoring options for VDU hot-plug/DPMS
events
+ * Define the service's connectivity monitoring options for VDU hotplug/DPMS
events
*
* Detecting events is optional. Events can be detected byinternal event
polling or by setting
* up libddcutil callbacks. However, libddcutil needs fully functioning DRM to
trap events, which
@@ -718,9 +743,13 @@
MONITOR_BY_LIBDDCUTIL_EVENTS,
} Monitoring_Preference_Type;
-static gboolean display_status_detection_enabled = FALSE;
+static gboolean display_status_detection_enabled = FALSE; // TODO this seems
to always be TRUE - get rid of it?
static gboolean enable_connectivity_signals = FALSE;
+// User overrides for polling:
+static gboolean disable_hotplug_polling = FALSE;
+static gboolean disable_dpms_polling = FALSE;
+
static Monitoring_Preference_Type monitoring_preference =
MONITOR_BY_INTERNAL_POLLING;
#define MIN_POLL_SECONDS 10
@@ -961,7 +990,8 @@
DDCA_Status detect_status = ddca_get_display_info_list2(include_invalid,
dlist_loc);
// 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.
+ // 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) {
@@ -1100,7 +1130,7 @@
* @param parameters inbound parameters
* @param invocation originating D-Bus method call
*/
-static void detect(GVariant* parameters, GDBusMethodInvocation* invocation) {
+static void detect(GVariant* parameters, GDBusMethodInvocation* invocation,
gboolean list_only) {
u_int32_t flags;
g_variant_get(parameters, "(u)", &flags);
@@ -1113,9 +1143,13 @@
g_info("Detect flags=%x", flags);
- DDCA_Status detect_status = ddca_redetect_displays();
+ DDCA_Status detect_status = DDCRC_OK;
char* detect_message_text = NULL;
+ if (!list_only) {
+ detect_status = ddca_redetect_displays();
+ }
+
if (detect_status != DDCRC_OK) {
detect_message_text = get_status_message(detect_status);
g_warning("Detect: ddca_redetect_displays failed status=%d
message=%s", detect_status, detect_message_text);
@@ -1226,6 +1260,14 @@
}
ddca_close_display(disp_handle);
}
+ else {
+ g_warning("GetVcp open failed for vcp_code=%d display_num=%d
edid=%.30s... status=%d",
+ vcp_code, display_number, edid_encoded, status);
+ }
+ }
+ else {
+ g_warning("GetVcp get_display_info failed for vcp_code=%d
display_num=%d edid=%.30s...",
+ vcp_code, display_number, edid_encoded);
}
char* message_text = get_status_message(status);
GVariant* result = g_variant_new(
@@ -1311,7 +1353,17 @@
}
ddca_close_display(disp_handle);
}
+ else {
+ g_info("GetMultipleVcp open failed for display_num=%d
edid=%.30s...",
+ display_number, edid_encoded);
+ }
+ }
+ else {
+ g_info("GetMultipleVcp get_display_info failed for display_num=%d
edid=%.30s...",
+ display_number, edid_encoded);
}
+ g_info("GetMultipleVcp open looks ok for display_num=%d edid=%.30s...",
+ display_number, edid_encoded);
char* message_text = get_status_message(status);
GVariant* result = g_variant_new("(a(yqqs)is)", value_array_builder,
status, message_text);
g_dbus_method_invocation_return_value(invocation, result); // Think this
frees the result
@@ -1896,7 +1948,6 @@
*/
static DDCA_Status enable_ddca_watch_displays(void) {
#if defined(LIBDDCUTIL_HAS_CHANGES_CALLBACK)
- g_message("ServiceEmitConnectivitySignals using libddcutil change
detection");
int status = DDCRC_OK;
DDCA_Display_Event_Class classes_loc;
const bool running = ddca_get_active_watch_classes(&classes_loc) ==
DDCRC_OK;
@@ -1909,10 +1960,9 @@
status = ddca_start_watch_displays(DDCA_EVENT_CLASS_ALL);
if (status == DDCRC_OK) {
g_message("registering libddcutil display status callback");
- poll_interval_micros = 0; // Disable internal polling
- const int reg_status =
ddca_register_display_status_callback(display_status_event_callback);
- if (reg_status == DDCRC_OK) {
- return reg_status;
+ status =
ddca_register_display_status_callback(display_status_event_callback);
+ if (status == DDCRC_OK) {
+ return status;
}
}
}
@@ -1974,7 +2024,10 @@
}
if (g_strcmp0(method_name, "Detect") == 0) {
- detect(parameters, invocation);
+ detect(parameters, invocation, FALSE);
+ }
+ else if (g_strcmp0(method_name, "ListDetected") == 0) {
+ detect(parameters, invocation, TRUE);
}
else if (g_strcmp0(method_name, "GetVcp") == 0) {
get_vcp(parameters, invocation);
@@ -2109,6 +2162,44 @@
return ret;
}
+static void configure_display_connectivity_detection(void) {
+ if (enable_connectivity_signals) {
+ if (monitoring_preference == MONITOR_BY_LIBDDCUTIL_EVENTS) {
+ g_message("ConnectedDisplaysChanged: ddcutil-service will use
libddcutil events for hotplug");
+ if (enable_ddca_watch_displays() != DDCRC_OK) {
+ g_warning("ConnectedDisplaysChanged: ddcutil-service falling
back to internal polling.");
+ monitoring_preference = MONITOR_BY_INTERNAL_POLLING;
+ // Note - DPMS events aren't supported by libddcutil, so we
will still do it by polling
+ }
+ }
+ else {
+ disable_ddca_watch_displays(); // just in case we are switching
preferences.
+ }
+ // Need to poll for at least DPMS, but not hotplug if using libddcutil
+ if (!disable_hotplug_polling && monitoring_preference ==
MONITOR_BY_INTERNAL_POLLING) {
+ g_message("ConnectedDisplaysChanged: ddcutil-service will
internally poll for hotplug");
+ } else {
+ g_message("ConnectedDisplaysChanged: ddcutil-service internal
hotplug polling disabled");
+ }
+ if (!disable_dpms_polling) {
+ g_message("ConnectedDisplaysChanged: ddcutil-service will
internally poll for DPMS");
+ } else {
+ g_message("ConnectedDisplaysChanged: ddcutil-service internal
polling for DPMS disabled");
+ }
+ if (!disable_dpms_polling || !disable_hotplug_polling) {
+ g_message("ConnectedDisplaysChanged: ddcutil-service internal "
+ "poll-interval=%ld secs poll-cascade-interval=%5.3f
secs",
+ poll_interval_micros / 1000000,
poll_cascade_interval_micros / 100000.0);
+ }
+ }
+ else {
+ if (monitoring_preference == MONITOR_BY_LIBDDCUTIL_EVENTS) {
+ disable_ddca_watch_displays();
+ }
+ g_message("ConnectedDisplaysChanged: disabled.");
+ }
+}
+
/**
* @brief Handles calls to DdcutilService D-Bus
org.freedesktop.DBus.Properties.Set.
*
@@ -2164,34 +2255,9 @@
g_warning("Property ServiceEmitSignals is deprecated, please use
ServiceEmitConnectivitySignals");
}
enable_connectivity_signals = g_variant_get_boolean(value);
- g_message("ServiceEmitConnectivitySignals set property to %s",
- enable_connectivity_signals ? "enabled" : "disabled");
- switch (monitoring_preference) {
- case MONITOR_BY_LIBDDCUTIL_EVENTS:
- g_message("Detect changes using libddcutil callbacks.");
- poll_interval_micros = 0;
- if (enable_connectivity_signals) {
- if (enable_ddca_watch_displays() == DDCRC_OK) {
- break; // Success, exit the switch
- }
- // Failed, fall through to polling
- } else {
- disable_ddca_watch_displays();
- break;
- }
- case MONITOR_BY_INTERNAL_POLLING:
- default:
- if (enable_connectivity_signals) {
- if (poll_interval_micros == 0) { // If not already set
- poll_interval_micros = DEFAULT_POLL_SECONDS * 1000000;
- }
- g_message("ServiceEmitConnectivitySignals ddcutil-service
polling every %ld seconds",
- poll_interval_micros / 1000000);
- } else {
- poll_interval_micros = 0;
- }
- break;
- }
+ g_message("ServiceEmitConnectivitySignals: setting property to %s",
+ enable_connectivity_signals ? "enabled" : "disabled");
+ configure_display_connectivity_detection();
}
else if (g_strcmp0(property_name, "ServicePollInterval") == 0) {
const uint secs = g_variant_get_uint32(value);
@@ -2262,6 +2328,9 @@
}
static bool is_dpms_capable(const DDCA_Display_Info *vdu_info) {
+ if (disable_dpms_polling) {
+ return FALSE;
+ }
DDCA_Status status;
DDCA_Feature_Metadata *meta_0xd6 = NULL;
#if defined(USE_DREF_CHECK_FOR_DPMS)
@@ -2282,7 +2351,7 @@
return status == DDCRC_OK;
}
-static bool poll_dpms_awake(const DDCA_Display_Info* vdu_info) {
+static bool is_dpms_awake(const DDCA_Display_Info* vdu_info) {
DDCA_Display_Handle disp_handle;
DDCA_Status status = ddca_open_display2(vdu_info->dref, 1, &disp_handle);
if (status == DDCRC_OK) {
@@ -2303,17 +2372,27 @@
const long now_in_micros = g_get_monotonic_time();
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
+ // When monitoring_preference == MONITOR_BY_INTERNAL_POLLING, this
function handles
+ // both hotplug and DPMS detection.
+ // When monitoring_preference == MONITOR_BY_LIBDDCUTIL_EVENTS
libddcutil
+ // handles hotplug detection, but this function still handles DPMS
detection.
+ const bool handle_hotplug_detection =
+ monitoring_preference == MONITOR_BY_INTERNAL_POLLING &&
!disable_hotplug_polling;
+ g_debug("Internal Poll check: %s", handle_hotplug_detection ? "hotplug
and DPMS check" : "DPMS only check");
+
+ DDCA_Status detect_status = DDCRC_OK;
+ if (handle_hotplug_detection) { // Need to do expensive
ddca_redected_displays() for hotplug detection
+ // 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 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
+ }
+ 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;
@@ -2327,23 +2406,23 @@
// Check all displays, mark existing ones as connected, add
new ones.
for (int ndx = 0; ndx < dlist->ct && !event_is_ready; ndx++) {
- const DDCA_Display_Info* vdu_info = &dlist->info[ndx];
- gchar* edid_encoded = edid_encode(vdu_info->edid_bytes);
- const GList* ptr = g_list_find_custom(poll_list,
edid_encoded, pollcmp);
- if (ptr != NULL) { // Found it, mark it as connected
- Poll_List_Item* vdu_poll_data = (Poll_List_Item
*)(ptr->data);
+ const DDCA_Display_Info* ddca_dinfo_ptr =
&dlist->info[ndx];
+ gchar* edid_encoded =
edid_encode(ddca_dinfo_ptr->edid_bytes);
+ const GList* list_ptr = g_list_find_custom(poll_list,
edid_encoded, pollcmp);
+ if (list_ptr != NULL) { // Found it, mark it as connected
+ Poll_List_Item* vdu_poll_data = (Poll_List_Item
*)(list_ptr->data);
const gboolean previous_dpms_awake =
vdu_poll_data->dpms_awake;
vdu_poll_data->connected = TRUE;
- g_debug("Poll check: existing-connection disp=%d
%.30s...", ndx + 1, edid_encoded);
+ g_debug("Internal Poll check: existing-connection
disp=%d %.30s...", ndx + 1, edid_encoded);
if (vdu_poll_data->has_dpms) {
- vdu_poll_data->dpms_awake =
poll_dpms_awake(vdu_info);
+ vdu_poll_data->dpms_awake =
is_dpms_awake(ddca_dinfo_ptr);
if (previous_dpms_awake !=
vdu_poll_data->dpms_awake) {
g_message("Poll signal event - dpms changed to
%s %d %.30s...",
vdu_poll_data->dpms_awake ? "awake" :
"asleep", ndx + 1, edid_encoded);
Event_Data_Type* event =
g_malloc(sizeof(Event_Data_Type));
event->event_type =
vdu_poll_data->dpms_awake ?
DDCA_EVENT_DPMS_AWAKE : DDCA_EVENT_DPMS_ASLEEP;
- event->dref = vdu_info->dref;
+ event->dref = ddca_dinfo_ptr->dref;
g_free(atomic_event_exchange(&signal_event_data, event)); // keep latest only
event_is_ready = TRUE; // Only one event on
each poll - terminate loop
}
@@ -2354,35 +2433,42 @@
Poll_List_Item* vdu_poll_data =
g_malloc(sizeof(Poll_List_Item));
vdu_poll_data->edid_encoded = edid_encoded;
vdu_poll_data->connected = TRUE;
- vdu_poll_data->has_dpms = is_dpms_capable(vdu_info);
- vdu_poll_data->dpms_awake = vdu_poll_data->has_dpms ?
poll_dpms_awake(vdu_info) : TRUE;
+ vdu_poll_data->has_dpms =
is_dpms_capable(ddca_dinfo_ptr);
+ vdu_poll_data->dpms_awake = vdu_poll_data->has_dpms ?
is_dpms_awake(ddca_dinfo_ptr) : TRUE;
poll_list = g_list_append(poll_list, vdu_poll_data);
g_debug("Poll check: new-connection disp=%d %.30s...
has_dpms=%d awake=%d ",
ndx + 1, edid_encoded, vdu_poll_data->has_dpms,
vdu_poll_data->dpms_awake);
- if (next_poll_time) { // Not on first time through
- g_message("Poll signal event - connected %d
%.30s...", ndx + 1, edid_encoded);
- Event_Data_Type* event =
g_malloc(sizeof(Event_Data_Type));
- event->event_type = DDCA_EVENT_DISPLAY_CONNECTED;
- g_free(atomic_event_exchange(&signal_event_data,
event)); // keep latest only
- event_is_ready = TRUE; // Only one event on each
poll - terminate loop
+ if (handle_hotplug_detection) {
+ if (next_poll_time) { // Not on first time through
+ g_message("Poll signal event - connected %d
%.30s...", ndx + 1, edid_encoded);
+ Event_Data_Type *event =
g_malloc(sizeof(Event_Data_Type));
+ event->event_type =
DDCA_EVENT_DISPLAY_CONNECTED;
+
g_free(atomic_event_exchange(&signal_event_data, event)); // keep latest only
+ event_is_ready = TRUE; // Only one event on
each poll - terminate loop
+ }
}
}
}
// Check if any displays are still marked as disconnected
- for (GList* ptr = poll_list; ptr != NULL && !event_is_ready;) {
- GList* next = ptr->next;
- Poll_List_Item* vdu_poll_data = ptr->data;
+ for (GList* list_ptr = poll_list; list_ptr != NULL &&
!event_is_ready;) {
+ GList* list_next_ptr = list_ptr->next; // Save this now
because we may delete list_ptr
+ Poll_List_Item* vdu_poll_data = list_ptr->data;
if (!vdu_poll_data->connected) {
- g_message("Poll signal event - disconnected
%.30s...\n", vdu_poll_data->edid_encoded);
- Event_Data_Type* event =
g_malloc(sizeof(Event_Data_Type));
- event->event_type = DDCA_EVENT_DISPLAY_DISCONNECTED;
- g_free(atomic_event_exchange(&signal_event_data,
event)); // keep latest only
+ if (handle_hotplug_detection) {
+ g_message("Poll signal event - disconnected
%.30s...", vdu_poll_data->edid_encoded);
+ Event_Data_Type *event =
g_malloc(sizeof(Event_Data_Type));
+ event->event_type =
DDCA_EVENT_DISPLAY_DISCONNECTED;
+ g_free(atomic_event_exchange(&signal_event_data,
event)); // keep latest only
+ event_is_ready = TRUE; // Only one event on each
poll - terminate loop
+ }
+ else {
+ g_debug("Poll check: remove-connection %.30s... ",
vdu_poll_data->edid_encoded);
+ }
g_free(vdu_poll_data->edid_encoded);
g_free(vdu_poll_data);
- poll_list = g_list_delete_link(poll_list, ptr);
- event_is_ready = TRUE; // Only one event on each poll
- terminate loop
+ poll_list = g_list_delete_link(poll_list, list_ptr);
}
- ptr = next;
+ list_ptr = list_next_ptr;
}
ddca_free_display_info_list(dlist);
}
@@ -2430,7 +2516,7 @@
return FALSE;
}
- if (poll_interval_micros > 0) {
+ if (!disable_hotplug_polling || !disable_dpms_polling) {
poll_for_changes();
}
@@ -2644,8 +2730,8 @@
gboolean introspect_request = FALSE; // g_option_context_parse will
overrun
gboolean log_info = FALSE; // TODO should all bool be changed
to gboolean for safety?
- gboolean prefer_polling = TRUE;
- gboolean prefer_drm = FALSE;
+ gboolean prefer_polling = FALSE;
+ gboolean prefer_libddcutil_events = FALSE;
int poll_seconds = -1; // -1 flags no argument supplied
double poll_cascade_interval_seconds = 0.0;
@@ -2656,7 +2742,6 @@
gint ddca_syslog_level = DDCA_SYSLOG_NOTICE;
gint ddca_init_options = 0; // DDCA_INIT_OPTIONS_CLIENT_OPENED_SYSLOG
-
// Use the glib command line parser...
const GOptionEntry entries[] = {
{
@@ -2668,12 +2753,24 @@
"print introspection xml and exit", NULL
},
{
+ "enable-connectivity-signals", 'q', 0, G_OPTION_ARG_NONE,
&enable_connectivity_signals,
+ "enable DBUS signalling of display connection events", NULL
+ },
+ {
+ "disable-hotplug-polling", 'u', 0, G_OPTION_ARG_NONE,
&disable_hotplug_polling,
+ "disable internal polling for hotplug events (disable polling
libddcutil detect)", NULL
+ },
+ {
+ "disable-dpms-polling", 'm', 0, G_OPTION_ARG_NONE,
&disable_dpms_polling,
+ "disable internal polling for DPMS events (disable polling getvcp
0xd6)", NULL
+ },
+ {
"prefer-polling", 'p', 0, G_OPTION_ARG_NONE, &prefer_polling,
- "prefer polling for detecting display connection events", NULL
+ "prefer internal polling for detecting display connection events",
NULL
},
{
- "prefer-drm", 'd', 0, G_OPTION_ARG_NONE, &prefer_drm,
- "prefer libddcutil DRM-lookups for detecting display connection
events", NULL
+ "prefer-libddcutil-events", 'd', 0, G_OPTION_ARG_NONE,
&prefer_libddcutil_events,
+ "prefer libddcutil for detecting display connection events", NULL
},
{
"poll-interval", 't', 0, G_OPTION_ARG_INT, &poll_seconds,
@@ -2684,14 +2781,6 @@
"polling minimum interval between cascading events in seconds, 0.1
minimum", NULL
},
{
- "emit-connectivity-signals", 'e', 0, G_OPTION_ARG_NONE,
&enable_connectivity_signals,
- "enable the D-Bus ConnectedDisplaysChanged signal and associated
change monitoring", NULL
- },
- {
- "emit-signals", 'e', 0, G_OPTION_ARG_NONE,
&enable_connectivity_signals,
- "deprecated, replaced by --emit-connectivity-signals", NULL
- },
- {
"return-raw-values", 'r', 0, G_OPTION_ARG_NONE, &return_raw_values,
"return high-byte and low-byte for all values, including Simple
Non-Continuous values", NULL
},
@@ -2700,7 +2789,7 @@
"lock configuration, make properties and sleep-multipliers read
only, disable the restart method", NULL
},
{
- "log-info", 'i', 0, G_OPTION_ARG_NONE, &log_info,
+ "log-info", 'I', 0, G_OPTION_ARG_NONE, &log_info,
"log service info and debug messages", NULL
},
{
@@ -2711,6 +2800,10 @@
"ddca-init-options", 'i', 0, G_OPTION_ARG_INT, &ddca_init_options,
"1=Disable-Config-File", NULL
},
+ {
+ "prefer-drm", 'd', 0, G_OPTION_ARG_NONE, &prefer_libddcutil_events,
+ "deprecated nondescript name, same as --prefer-libddcutil-events",
NULL
+ },
{NULL}
};
@@ -2762,7 +2855,6 @@
exit(1);
}
-
// Handle ddcutil ddc_init() arguments
char* argv_null_terminated[argc];
for (int i = 0; i < argc; i++) {
@@ -2804,43 +2896,34 @@
GMainLoop* main_loop = g_main_loop_new(NULL, FALSE);
- prefer_polling = !prefer_drm;
- monitoring_preference = prefer_polling ? MONITOR_BY_INTERNAL_POLLING :
MONITOR_BY_LIBDDCUTIL_EVENTS;
-
- if (enable_connectivity_signals) {
- switch (monitoring_preference) {
- case MONITOR_BY_LIBDDCUTIL_EVENTS: {
- const int enable_watch_status = enable_ddca_watch_displays();
- if (enable_watch_status == DDCRC_OK) {
- poll_interval_micros = 0;
- break;
- }
- g_warning("Falling back to service internal polling for change
detection");
- }
- case MONITOR_BY_INTERNAL_POLLING:
- default:
- g_message("ConnectedDisplaysChanged signal - using service
internal polling for change detection");
- if (poll_seconds >= 0 && !update_poll_interval(poll_seconds)) {
- g_print("Polling interval parameter must be at least %d
seconds.", MIN_POLL_SECONDS);
- exit(1);
- }
- if (poll_cascade_interval_seconds > 0.0
- &&
!update_poll_cascade_interval(poll_cascade_interval_seconds)) {
- g_print("Polling cascade interval parameter must be at
least %5.3f seconds.",
- MIN_POLL_CASCADE_INTERVAL_SECONDS);
- exit(1);
- }
- g_message("ConnectedDisplaysChanged signal - poll-interval=%ld
poll-cascade-interval=%5.3f",
- poll_interval_micros / 1000000,
poll_cascade_interval_micros / 100000.0);
- break;
- }
+ if (prefer_polling) {
+ monitoring_preference = MONITOR_BY_INTERNAL_POLLING;
+ }
+ else if (prefer_libddcutil_events) {
+ monitoring_preference = MONITOR_BY_LIBDDCUTIL_EVENTS;
}
else {
- g_message("ConnectedDisplaysChanged signals disabled"
- "(add --emit_connectivity_signals to enable them).");
- poll_interval_micros = 0; // Disable internal polling
+ const gboolean has_reliable_events = ddca_ddcutil_version().major > 2
||
+ (ddca_ddcutil_version().major ==
2 && ddca_ddcutil_version().minor >= 2);
+ if (has_reliable_events) {
+ g_message("libddcutil version >= 2.2 - service will default to
libddcutil-events for change detection.");
+ }
+ monitoring_preference = has_reliable_events ?
MONITOR_BY_LIBDDCUTIL_EVENTS : MONITOR_BY_INTERNAL_POLLING;
}
+ if (poll_seconds >= 0 && !update_poll_interval(poll_seconds)) {
+ g_print("Polling interval parameter must be at least %d seconds.",
MIN_POLL_SECONDS);
+ exit(1);
+ }
+ if (poll_cascade_interval_seconds > 0.0
+ && !update_poll_cascade_interval(poll_cascade_interval_seconds)) {
+ g_print("Polling cascade interval parameter must be at least %5.3f
seconds.",
+ MIN_POLL_CASCADE_INTERVAL_SECONDS);
+ exit(1);
+ }
+
+ configure_display_connectivity_detection();
+
enable_custom_source(main_loop); // May do nothing - but a client may
enable events or polling later
g_main_loop_run(main_loop);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ddcutil-service-1.0.11/ddcutil-service.spec
new/ddcutil-service-1.0.14/ddcutil-service.spec
--- old/ddcutil-service-1.0.11/ddcutil-service.spec 2024-08-22
03:59:06.000000000 +0200
+++ new/ddcutil-service-1.0.14/ddcutil-service.spec 2025-03-08
21:14:51.000000000 +0100
@@ -18,7 +18,7 @@
Name: ddcutil-service
-Version: 1.0.11
+Version: 1.0.14
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.11/docs/html/ddcutil-service.1.html
new/ddcutil-service-1.0.14/docs/html/ddcutil-service.1.html
--- old/ddcutil-service-1.0.11/docs/html/ddcutil-service.1.html 2024-08-22
03:59:06.000000000 +0200
+++ new/ddcutil-service-1.0.14/docs/html/ddcutil-service.1.html 2025-03-08
21:14:51.000000000 +0100
@@ -1,5 +1,5 @@
<!-- Creator : groff version 1.23.0 -->
-<!-- CreationDate: Tue Jul 2 16:41:23 2024 -->
+<!-- CreationDate: Sun Mar 9 09:14:36 2025 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
@@ -60,11 +60,12 @@
-<p style="margin-left:9%; margin-top: 1em"><b>ddcutil-service</b>
-<i>--help</i> | <i>--version</i> | <i>--introspect</i>
-<b><br>
-ddcutil-service</b> [ <b>--emit-connectivity-signals</b> ] |
-[ <b>--prefer-polling</b> ] | [ <b>--prefer-drm</b> ] | [
+<p style="margin-left:9%; margin-top: 1em"><b>ddcutil-service
+--help</b> | <b>--version</b> | <b>--introspect <br>
+ddcutil-service</b> [ <b>--enable-connectivity-signals</b> ]
+| [ <b>--disable-hotplug-polling</b> ] | [
+<b>--disable-dpms-polling</b> ] | [ <b>--prefer-polling</b>
+] | [ <b>--prefer-libddcutil-events</b> ] | [
<b>--polling-interval</b> <i>seconds</i> ] | [
<b>--return-raw-values</b> ] | [ <b>--lock</b> ] | [
<b>--log-info</b> ] [ <b>--ddca-syslog-level</b> <i>N</i> ]
@@ -141,48 +142,76 @@
introspection text for the service and exits.</p>
-<p style="margin-left:9%;"><b>--emit-connectivity-signals</b></p>
+<p style="margin-left:9%;"><b>--enable-connectivity-signals</b></p>
+
+<p style="margin-left:18%; margin-top: 1em">Enable monitor
+hotplug detection and DPMS-state detection. These
+connectivity events generate the <b>ConnectedDisplaysChanged
+signal</b>. Connectivity-detection defaults to off because
+it may not work consistently for all monitors and all GPU
+drivers. One enabled, further connectivity related options
+may be employed to try and obtain a workable
+configuration.</p>
+
+
+<p style="margin-left:9%;"><b>--disable-hotplug-polling</b></p>
-<p style="margin-left:18%; margin-top: 1em">Enable the
-<b>ConnectedDisplaysChanged signal</b> sent to clients and
-also enable any monitoring for changes. Once the service is
-running, this setting can be toggled by altering the
-<b>ServiceEmitConnectivitySignals</b> property. See
-<b>SERVICE SIGNALS</b>.</p>
+<p style="margin-left:18%; margin-top: 1em">Disable
+internal polling for hotplug events. Polling may wake some
+monitor models from DPMS sleep (seems rare). (Disables
+polling <b>libddcutil detect</b>.)</p>
+
+
+<p style="margin-left:9%;"><b>--disable-dpms-polling</b></p>
+
+<p style="margin-left:18%; margin-top: 1em">Disable the
+internal polling for DPMS events. Polling for DPMS state may
+wake some monitor models from DPMS sleep (seems rare).
+(Disables polling <b>libddcutil getvcp 0xd6</b>.)</p>
<p style="margin-left:9%;"><b>--prefer-polling</b></p>
-<p style="margin-left:18%; margin-top: 1em">Set polling to
-be the preferred method for detecting display connectivity
-changes for the <b>ConnectedDisplaysChanged signal</b>. This
-is the default.</p>
+<p style="margin-left:18%; margin-top: 1em">Set service
+internal polling to be the preferred method for detecting
+display connectivity changes for the
+<b>ConnectedDisplaysChanged signal</b>. This is the default
+prior to <b>libddcutil 2.2</b> and may still be a better
+choice for monitors connected via DVI if they behave
+inconsistently when using libddcutil event detection.</p>
+
-<p style="margin-left:9%;"><b>--prefer-drm</b></p>
+<p style="margin-left:9%;"><b>--prefer-libddcutil-events</b></p>
<p style="margin-left:18%; margin-top: 1em">Use
-<b>libddcutil DRM-lookups</b> as the preferred method for
-detecting display connectivity changes for the
-<b>ConnectedDisplaysChanged signal</b>. This option should
-detect changes sooner with less overheads, but may fail to
-detect changes for some combinations or drivers and
-hardware.</p>
+<b>libddcutil event detection</b> as the preferred method
+for detecting display connectivity changes for the
+<b>ConnectedDisplaysChanged signal</b>. This is the default
+when using <b>libddcutil 2.2</b> 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 by libddcutil. Libddcutil event
+detection may fail to work reliably for some combinations of
+drivers, hardware, and connectors, in which case, try
+<b>--prefer-polling</b> instead. In particular, eventing
+from monitors hotplugged via DVI connectors seems to be more
+inconsistent.</p>
<p style="margin-left:9%;"><b>--poll-interval</b>
<i>seconds</i></p>
-<p style="margin-left:18%; margin-top: 1em">If polling is
-enabled, this option defines how often to check for display
+<p style="margin-left:18%; margin-top: 1em">This option
+defines how often to internally poll for display
connectivity changes. Default 30 seconds, minimum 10
seconds, zero to disable polling.</p>
<p style="margin-left:9%;"><b>--poll-cascade-interval</b>
<i>seconds</i></p>
-<p style="margin-left:18%; margin-top: 1em">If polling is
-enabled, this option defines the 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. Default 0.5 seconds, minimum 0.1
+<p style="margin-left:18%; margin-top: 1em">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. Default 0.5 seconds, minimum 0.1
seconds.</p>
<p style="margin-left:9%;"><b>--return-raw-values</b></p>
@@ -272,11 +301,24 @@
<p><b>Detect</b></p></td>
<td width="1%"></td>
-<td width="82%">
+<td width="81%">
<p>Return a list of monitors detected along with their
-properties.</p> </td></tr>
+properties.</p> </td>
+<td width="1%">
+</td></tr>
+</table>
+
+<p style="margin-left:9%;"><b>ListDetected</b></p>
+
+<p style="margin-left:18%;">Return the list of previously
+detected monitors along with their properties. This method
+is particularly useful for <b>libddcutil 2.2+</b> where
+detection may occur in the background automatically.</p>
+
+<table width="100%" border="0" rules="none" frame="void"
+ cellspacing="0" cellpadding="0">
<tr valign="top" align="left">
<td width="9%"></td>
<td width="8%">
@@ -403,50 +445,38 @@
<p style="margin-left:9%;"><b>ConnectedDisplaysChanged</b></p>
-<p style="margin-left:18%;">The service may optionally emit
-a <b>ConnectedDisplaysChanged</b> D-Bus signal when a
-display undergoes a connectivity status change due to
-hot-plug and DPMS events. This feature is optional because
-the manual experimentation required to configure it is
-unnecessary for display configurations that remain
-static.</p>
-
-
-<p style="margin-left:18%; margin-top: 1em">Change-detection
-can be enabled by passing <b>--emit-connectivity-signals</b>
-on the command line, or by setting the
-<b>ServiceEmitConnectivitySignals</b> property.</p>
-
-<p style="margin-left:18%; margin-top: 1em">To permanently
-enable change-detection, the
-<b>--emit-connectivity-signals</b> option can be appended to
-the <b>Exec</b> line of the system or user D-Bus
-<b>com.ddcutil.DdcutilService.service</b> file (see
-<b>FILES</b>).</p>
-
-<p style="margin-left:18%; margin-top: 1em">Changes are
-detected in one of two ways. The service defaults to
-periodic polling by issuing <b>libddcutil DDCA detects</b>.
-Polling is likely to work for a wide variety of drivers and
-hardware. Polling for changes will be subject to delays
-because the polling interval defaults to 30 seconds (with a
-minimum of 10 seconds). Alternatively the service can use
-<b>libddcutil DRM access</b> to provide a more efficient
-method for change detection, this requires
-<b>ddcutil/libddcutil version 2.1.0+</b>, a GPU configured
-for <b>DRM</b>, and the <b>--enable-watch-displays</b> to be
-added to <i>[libddcutil] options</i> in
-<b>$HOME/.config/ddcutil/ddcutilrc</b>.</p>
+<p style="margin-left:18%;">The service may emit a
+<b>ConnectedDisplaysChanged</b> D-Bus signal when a display
+undergoes a connectivity status change due to hotplug and
+DPMS events. This feature must be enabled by using the
+<b>--enable-connectivity-signals</b> option.</p>
+
+<p style="margin-left:18%; margin-top: 1em">When utilizing
+libddcutil 2.2, or above, the service defaults to using
+libddcutil’s inbuilt change detection. This is a
+portable change detection mechanism which should detect
+changes without delay for most desktop environments.</p>
+
+<p style="margin-left:18%; margin-top: 1em">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).</p>
+
+<p style="margin-left:18%; margin-top: 1em">In either case,
+the options <b>--prefer-polling</b> and
+<b>--prefer-libddcutil-events</b> can be used to override
+the default for change detection.</p>
<p style="margin-left:18%; margin-top: 1em">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. DisplayPort behaves
-differently to DVI and HDMI when a display is turned off but
-remains connected. Some drivers that support DRM don’t
-properly support the necessary change detection
-features.</p>
+such as KDE, Gnome, X11, and Wayland. See <b>LIMITATIONS</b>
+below for further details.</p>
<p style="margin-left:9%;"><b>VcpValueChanged</b></p>
@@ -481,7 +511,7 @@
<p style="margin-left:18%;">List the event-types sent by
the <b>ConnectedDisplaysChanged</b> signal along with their
text names. Events are included for display
-connection/disconnection (hot-plug), DPMS-sleep, and
+connection/disconnection (hotplug), DPMS-sleep, and
DPMS-wake. If the list is empty, the GPU, GPU-driver, or
<b>libddcutil</b> version doesn’t support display
event detection.</p>
@@ -640,9 +670,9 @@
Exec=/usr/bin/ddcutil-service</p>
<p style="margin-left:18%; margin-top: 1em">Service
-options, such as <b>--emit-connectivity-signals</b> or
-<b>--prefer-drm</b>, should be appended to the end of
-<b>Exec=</b> line.</p>
+options, such as <b>--prefer-polling</b> or
+<b>--prefer-libddcutil-events</b>, should be appended to the
+end of <b>Exec=</b> line.</p>
<p
style="margin-left:9%;"><b>$HOME/.local/share/dbus-1/services/com.ddcutil.DdcutilService.service</b></p>
@@ -840,11 +870,33 @@
<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>
+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. hotplugging DVI
+connections appear to behave more inconsistently than
+DisplayPort with some drivers (for multple OEMs).</p>
+
+<p style="margin-left:9%; margin-top: 1em">If
+<b>ConnectedDisplaysChanged</b> signals are not being
+raised, you can try manually adding <b>--prefer-polling</b>
+option, to force the service to poll internally for changes.
+Polling is less responsive, but it is more likely to
+work.</p>
+
+<p style="margin-left:9%; margin-top: 1em">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 disabled by adding the
+<b>--disable-dpms-polling</b> option.</p>
+
+<p style="margin-left:9%; margin-top: 1em">The two internal
+polling options have been reported to wake at least one
+model of monitor from sleep. If this occurs, each can be
+independently disabled by the options
+<b>--disable-hotplug-polling</b> and
+<b>--disable-dpms-polling</b>.</p>
<p style="margin-left:9%; margin-top: 1em">Some GPU drivers
and VDUs have buggy implementations of DDC. If you have the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ddcutil-service-1.0.11/docs/html/ddcutil-service.7.html
new/ddcutil-service-1.0.14/docs/html/ddcutil-service.7.html
--- old/ddcutil-service-1.0.11/docs/html/ddcutil-service.7.html 2024-08-22
03:59:06.000000000 +0200
+++ new/ddcutil-service-1.0.14/docs/html/ddcutil-service.7.html 2025-03-08
21:14:51.000000000 +0100
@@ -1,5 +1,5 @@
<!-- Creator : groff version 1.23.0 -->
-<!-- CreationDate: Tue Jul 2 16:41:23 2024 -->
+<!-- CreationDate: Thu Feb 20 14:08:26 2025 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
@@ -28,6 +28,7 @@
<a href="#METHOD DETAILS">METHOD DETAILS</a><br>
<a href="#The Restart() method">The Restart() method</a><br>
<a href="#The Detect() method">The Detect() method</a><br>
+<a href="#The ListDetected() method">The ListDetected() method</a><br>
<a href="#The GetVcp() method">The GetVcp() method</a><br>
<a href="#The GetMultipleVcp() method">The GetMultipleVcp() method</a><br>
<a href="#The SetVcp() method">The SetVcp() method</a><br>
@@ -89,6 +90,11 @@
OUT a(iiisssqsu) detected_displays, <br>
OUT i error_status, <br>
OUT s error_message); <br>
+ListDetected (IN u flags, <br>
+OUT i number_of_displays, <br>
+OUT a(iiisssqsu) detected_displays, <br>
+OUT i error_status, <br>
+OUT s error_message); <br>
GetVcp (IN i display_number, <br>
IN s edid_txt, <br>
IN y vcp_code, <br>
@@ -342,6 +348,60 @@
<p style="margin-left:9%; margin-top: 1em">OUT a(iiisssqsu)
<i>detected_displays</i>:</p>
+
+<p style="margin-left:14%;">An array of structures
+describing the VDUs.</p>
+
+<p style="margin-left:9%; margin-top: 1em">OUT i
+<i>error_status</i>:</p>
+
+<p style="margin-left:14%;">A libddcutil DDCRC error
+status. DDCRC_OK (zero) if no errors have occurred.</p>
+
+<p style="margin-left:9%; margin-top: 1em">OUT s
+<i>error_message</i>:</p>
+
+<p style="margin-left:14%;">Text message for
+error_status.</p>
+
+<h3>The ListDetected() method
+<a name="The ListDetected() method"></a>
+</h3>
+
+
+<p style="margin-left:14%; margin-top: 1em">ListDetected
+(IN u flags, <br>
+OUT i number_of_displays, <br>
+OUT a(iiisssqsu) detected_displays, <br>
+OUT i error_status, <br>
+OUT s error_message);</p>
+
+<p style="margin-left:9%; margin-top: 1em">Returns the
+currently detected VDUs without performing using a new
+detect. This method is particularly useful for libddcutil
+2.2+ where detection may occur in the background
+automatically.</p>
+
+<p style="margin-left:9%; margin-top: 1em">The array
+<i>detected_displays</i> will be of length
+<i>number_of_displays</i>.</p>
+
+<p style="margin-left:9%; margin-top: 1em">Each element of
+<i>detected_displays</i> array will contain the fields
+specified by the AttributesReturnedByDetect property. The
+fields will include the libddcutil display−number and
+a base64−encoded EDID.</p>
+
+<p style="margin-left:9%; margin-top: 1em">IN u
+<i>flags</i>:</p>
+
+<p style="margin-left:14%;">For future use</p>
+
+<p style="margin-left:9%; margin-top: 1em">OUT i
+<i>number_of_displays</i>:</p>
+
+<p style="margin-left:9%; margin-top: 1em">OUT a(iiisssqsu)
+<i>detected_displays</i>:</p>
<p style="margin-left:14%;">An array of structures
describing the VDUs.</p>