├── .github └── workflows │ └── codeql.yml ├── .gitignore ├── AUTHORS ├── CHANGELOG.md ├── COPYING ├── Makefile.am ├── NEWS.md ├── PACKAGING ├── README.gitignore ├── README.md ├── autogen.sh ├── config └── .gitignore ├── configure.ac ├── data ├── Makefile.am ├── cmake │ └── ddcutil │ │ └── FindDDCUtil.cmake ├── ddcutil.pc.in ├── etc │ ├── X11 │ │ └── xorg.conf.d │ │ │ └── 90-nvidia-i2c.conf │ ├── modprobe.d │ │ └── nvidia-i2c.conf │ └── udev │ │ └── rules.d │ │ ├── 60-ddcutil-i2c.rules │ │ └── 60-ddcutil-usb.rules └── usr │ └── lib │ ├── modules-load.d │ └── ddcutil.conf │ └── udev │ └── rules.d │ └── 60-ddcutil-i2c.rules ├── ddcutil.appdata.xml ├── docs ├── Makefile.am ├── ddcutil-c-api.in └── doxygen │ ├── Makefile.am │ └── doxyfile.in ├── doxydoc ├── api.doxyfile ├── di ├── internals.doxyfile └── internals_mainpage.md ├── icons ├── COPYING └── hicolor │ ├── 128x128 │ └── apps │ │ └── ddcutil.png │ ├── 16x16 │ └── apps │ │ └── ddcutil.png │ ├── 256x256 │ └── apps │ │ └── ddcutil.png │ ├── 32x32 │ └── apps │ │ └── ddcutil.png │ ├── 48x48 │ └── apps │ │ └── ddcutil.png │ └── 64x64 │ └── apps │ └── ddcutil.png ├── m4 ├── .gitignore ├── ax_path_python3.m4 ├── ax_pkg_swig.m4 ├── ax_prog_doxygen.m4 ├── ax_python_devel.m4 ├── ax_python_env.m4 ├── ax_swig_enable_cxx.m4 ├── ax_swig_multi_module_support.m4 ├── ax_swig_python.m4 ├── ax_unprecious.m4 └── introspection.m4 ├── man ├── Makefile.am └── ddcutil.1 ├── pixmaps ├── COPYING └── ddcutil.png ├── sonar-project.properties └── src ├── Makefile.am ├── app_ddcutil ├── Makefile.am ├── app_capabilities.c ├── app_capabilities.h ├── app_ddcutil_services.c ├── app_ddcutil_services.h ├── app_dumpload.c ├── app_dumpload.h ├── app_dynamic_features.c ├── app_dynamic_features.h ├── app_experimental.c ├── app_experimental.h ├── app_getvcp.c ├── app_getvcp.h ├── app_interrogate.c ├── app_interrogate.h ├── app_probe.c ├── app_probe.h ├── app_setvcp.c ├── app_setvcp.h ├── app_testcases.c ├── app_testcases.h ├── app_vcpinfo.c ├── app_vcpinfo.h ├── app_watch.c ├── app_watch.h └── main.c ├── app_sysenv ├── Makefile.am ├── app_sysenv_services.c ├── app_sysenv_services.h ├── query_sysenv.c ├── query_sysenv.h ├── query_sysenv_access.c ├── query_sysenv_access.h ├── query_sysenv_base.c ├── query_sysenv_base.h ├── query_sysenv_detailed_bus_pci_devices.c ├── query_sysenv_detailed_bus_pci_devices.h ├── query_sysenv_dmidecode.c ├── query_sysenv_dmidecode.h ├── query_sysenv_drm.c ├── query_sysenv_drm.h ├── query_sysenv_i2c.c ├── query_sysenv_i2c.h ├── query_sysenv_logs.c ├── query_sysenv_logs.h ├── query_sysenv_modules.c ├── query_sysenv_modules.h ├── query_sysenv_original_sys_scans.c ├── query_sysenv_original_sys_scans.h ├── query_sysenv_procfs.c ├── query_sysenv_procfs.h ├── query_sysenv_simplified_sys_bus_pci_devices.c ├── query_sysenv_simplified_sys_bus_pci_devices.h ├── query_sysenv_sysfs.c ├── query_sysenv_sysfs.h ├── query_sysenv_sysfs_common.c ├── query_sysenv_sysfs_common.h ├── query_sysenv_usb.c ├── query_sysenv_usb.h ├── query_sysenv_xref.c └── query_sysenv_xref.h ├── base ├── Makefile.am ├── base.md ├── base_services.c ├── base_services.h ├── build_info.c ├── build_info.h ├── build_timestamp.c ├── build_timestamp.h ├── core.c ├── core.h ├── core_per_thread_settings.c ├── core_per_thread_settings.h ├── ddc_command_codes.c ├── ddc_command_codes.h ├── ddc_errno.c ├── ddc_errno.h ├── ddc_packets.c ├── ddc_packets.h ├── ddcutil_types_internal.h ├── display_lock.c ├── display_lock.h ├── display_retry_data.c ├── display_retry_data.h ├── displays.c ├── displays.h ├── drm_connector_state.c ├── drm_connector_state.h ├── dsa2.c ├── dsa2.h ├── dynamic_features.c ├── dynamic_features.h ├── execution_stats.c ├── execution_stats.h ├── feature_lists.c ├── feature_lists.h ├── feature_metadata.c ├── feature_metadata.h ├── feature_set_ref.c ├── feature_set_ref.h ├── flock.c ├── flock.h ├── i2c_bus_base.c ├── i2c_bus_base.h ├── linux_errno.c ├── linux_errno.h ├── monitor_model_key.c ├── monitor_model_key.h ├── monitor_quirks.c ├── monitor_quirks.h ├── parms.h ├── per_display_data.c ├── per_display_data.h ├── per_thread_data.c ├── per_thread_data.h ├── rtti.c ├── rtti.h ├── sleep.c ├── sleep.h ├── stats.c ├── stats.h ├── status_code_mgt.c ├── status_code_mgt.h ├── trace_control.c ├── trace_control.h ├── tuned_sleep.c ├── tuned_sleep.h ├── vcp_version.c └── vcp_version.h ├── bsd ├── i2c-dev.h ├── i2c.h └── linux_types.h ├── cmdline ├── Makefile.am ├── cmd_parser.h ├── cmd_parser_aux.c ├── cmd_parser_aux.h ├── cmd_parser_goption.c ├── parsed_cmd.c └── parsed_cmd.h ├── ddc ├── Makefile.am ├── ddc_common_init.c ├── ddc_common_init.h ├── ddc_display_ref_reports.c ├── ddc_display_ref_reports.h ├── ddc_display_selection.c ├── ddc_display_selection.h ├── ddc_displays.c ├── ddc_displays.h ├── ddc_dumpload.c ├── ddc_dumpload.h ├── ddc_initial_checks.c ├── ddc_initial_checks.h ├── ddc_multi_part_io.c ├── ddc_multi_part_io.h ├── ddc_output.c ├── ddc_output.h ├── ddc_packet_io.c ├── ddc_packet_io.h ├── ddc_phantom_displays.c ├── ddc_phantom_displays.h ├── ddc_read_capabilities.c ├── ddc_read_capabilities.h ├── ddc_save_current_settings.c ├── ddc_save_current_settings.h ├── ddc_serialize.c ├── ddc_serialize.h ├── ddc_services.c ├── ddc_services.h ├── ddc_strategy.c ├── ddc_strategy.h ├── ddc_try_data.c ├── ddc_try_data.h ├── ddc_vcp.c ├── ddc_vcp.h ├── ddc_vcp_version.c └── ddc_vcp_version.h ├── dw ├── Makefile.am ├── dw_archived.c ├── dw_common.c ├── dw_common.h ├── dw_dref.c ├── dw_dref.h ├── dw_main.c ├── dw_main.h ├── dw_poll.c ├── dw_poll.h ├── dw_recheck.c ├── dw_recheck.h ├── dw_services.c ├── dw_services.h ├── dw_status_events.c ├── dw_status_events.h ├── dw_udev.c ├── dw_udev.h ├── dw_xevent.c └── dw_xevent.h ├── dynvcp ├── Makefile.am ├── dyn_feature_codes.c ├── dyn_feature_codes.h ├── dyn_feature_files.c ├── dyn_feature_files.h ├── dyn_feature_set.c ├── dyn_feature_set.h ├── dyn_parsed_capabilities.c ├── dyn_parsed_capabilities.h ├── vcp_feature_set.c └── vcp_feature_set.h ├── i2c ├── Makefile.am ├── i2c_bus_core.c ├── i2c_bus_core.h ├── i2c_bus_selector.c ├── i2c_bus_selector.h ├── i2c_edid.c ├── i2c_edid.h ├── i2c_execute.c ├── i2c_execute.h ├── i2c_services.c ├── i2c_services.h ├── i2c_strategy_dispatcher.c ├── i2c_strategy_dispatcher.h └── wrap_i2c-dev.h ├── libmain ├── Makefile.am ├── api_base.c ├── api_base_internal.h ├── api_capabilities.c ├── api_capabilities_internal.h ├── api_displays.c ├── api_displays_internal.h ├── api_error_info_internal.c ├── api_error_info_internal.h ├── api_feature_access.c ├── api_feature_access_internal.h ├── api_metadata.c ├── api_metadata_internal.h ├── api_services_internal.c └── api_services_internal.h ├── public ├── ddcutil_c_api.h ├── ddcutil_macros.h.in ├── ddcutil_status_codes.h └── ddcutil_types.h ├── sample_clients ├── Makefile.am ├── clmain.c ├── demo_capabilities.c ├── demo_display_selection.c ├── demo_feature_list.c ├── demo_get_set_vcp.c ├── demo_global_settings.c ├── demo_profile_features.c ├── demo_redirection.c └── demo_vcpinfo.c ├── sysfs ├── Makefile.am ├── sysfs_base.c ├── sysfs_base.h ├── sysfs_conflicting_drivers.c ├── sysfs_conflicting_drivers.h ├── sysfs_dpms.c ├── sysfs_dpms.h ├── sysfs_i2c_info.c ├── sysfs_i2c_info.h ├── sysfs_i2c_sys_info.c ├── sysfs_i2c_sys_info.h ├── sysfs_services.c ├── sysfs_services.h ├── sysfs_sys_drm_connector.c ├── sysfs_sys_drm_connector.h ├── sysfs_top.c └── sysfs_top.h ├── test ├── Makefile.am ├── i2c │ ├── i2c_testutil.c │ └── i2c_testutil.h ├── testcase_mock_table.c ├── testcase_table.c ├── testcase_table.h ├── testcases.c └── testcases.h ├── usb ├── Makefile.am ├── usb_base.c ├── usb_base.h ├── usb_displays.c ├── usb_displays.h ├── usb_edid.c ├── usb_edid.h ├── usb_services.c ├── usb_services.h ├── usb_vcp.c └── usb_vcp.h ├── usb_util ├── Makefile.am ├── base_hid_report_descriptor.c ├── base_hid_report_descriptor.h ├── hid_report_descriptor.c ├── hid_report_descriptor.h ├── hiddev_reports.c ├── hiddev_reports.h ├── hiddev_util.c ├── hiddev_util.h ├── hidraw_util.c ├── hidraw_util.h ├── libusb_reports.c ├── libusb_reports.h ├── libusb_util.c ├── libusb_util.h ├── usb_hid_common.c └── usb_hid_common.h ├── util ├── Makefile.am ├── backtrace.c ├── backtrace.h ├── common_inlines.h ├── common_printf_formats.h ├── coredefs.h ├── coredefs_base.h ├── data_structures.c ├── data_structures.h ├── ddcutil_config_file.c ├── ddcutil_config_file.h ├── debug_util.c ├── debug_util.h ├── device_id_util.c ├── device_id_util.h ├── drm_card_connector_util.c ├── drm_card_connector_util.h ├── edid.c ├── edid.h ├── error_info.c ├── error_info.h ├── failsim.c ├── failsim.h ├── file_util.c ├── file_util.h ├── file_util_base.c ├── file_util_base.h ├── glib_string_util.c ├── glib_string_util.h ├── glib_util.c ├── glib_util.h ├── i2c_util.c ├── i2c_util.h ├── libdrm_aux_util.c ├── libdrm_aux_util.h ├── libdrm_util.c ├── libdrm_util.h ├── linux_util.c ├── linux_util.h ├── msg_util.c ├── msg_util.h ├── multi_level_map.c ├── multi_level_map.h ├── pnp_ids.c ├── pnp_ids.h ├── regex_util.c ├── regex_util.h ├── report_util.c ├── report_util.h ├── simple_ini_file.c ├── simple_ini_file.h ├── string_util.c ├── string_util.h ├── subprocess_util.c ├── subprocess_util.h ├── sysfs_filter_functions.c ├── sysfs_filter_functions.h ├── sysfs_i2c_util.c ├── sysfs_i2c_util.h ├── sysfs_util.c ├── sysfs_util.h ├── systemd_util.c ├── systemd_util.h ├── timestamp.c ├── timestamp.h ├── traced_function_stack.c ├── traced_function_stack.h ├── udev_i2c_util.c ├── udev_i2c_util.h ├── udev_usb_util.c ├── udev_usb_util.h ├── udev_util.c ├── udev_util.h ├── util.md ├── utilrpt.c ├── utilrpt.h ├── x11_util.c ├── x11_util.h ├── xdg_util.c └── xdg_util.h └── vcp ├── Makefile.am ├── parse_capabilities.c ├── parse_capabilities.h ├── parsed_capabilities_feature.c ├── parsed_capabilities_feature.h ├── persistent_capabilities.c ├── persistent_capabilities.h ├── vcp_feature_codes.c ├── vcp_feature_codes.h ├── vcp_feature_values.c └── vcp_feature_values.h /.gitignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | 3 | # Editor temporary files 4 | *~ 5 | *.swp 6 | 7 | # Other temporary files 8 | *.tmp 9 | 10 | # Extensions 11 | *.o 12 | *.lo 13 | *.la 14 | *.expand 15 | *.pyc 16 | 17 | # Hidden directories 18 | .deps 19 | .dirstamp 20 | .libs 21 | 22 | # Autotools 23 | aclocal.m4 24 | autom4te.cache 25 | config.cache 26 | /config.h 27 | /config.h.in 28 | /stamp-h1 29 | /config.log 30 | /config.site 31 | /config.status 32 | /configure 33 | /libtool 34 | Makefile 35 | Makefile.in 36 | /autoscan.log 37 | /configure.scan 38 | src/**/am--include-marker 39 | src/base/build_details.h 40 | 41 | # Generated files 42 | ddcutil.pc 43 | src/public/ddcutil_macros.h 44 | docs/ddcutil-c-api 45 | 46 | # Executable 47 | /src/ddcutil 48 | 49 | # Experimental API implementations 50 | *.typelib 51 | *.gir 52 | 53 | # Eclipse 54 | .settings/ 55 | .autotools 56 | .cproject 57 | .project 58 | 59 | # Doxygen output 60 | doxydoc/html 61 | doxydoc/latex 62 | doxydoc/apidoc 63 | 64 | # Miscellaneous tools 65 | /heaptrack* 66 | *.tar.gz 67 | 68 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Sanford Rockowitz 2 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | ddcutil 2 | ======= 3 | 4 | The [ddcutil website](http://www.ddcutil.com) is the primary location of information for ddcutil users. 5 | 6 | Recent announcements can be found on the [home page](http://www.ddcutil.com). 7 | 8 | Earlier announcements are located at [prior announcements](http://www.ddcutil.prior_announcements). 9 | 10 | Detailed information about user-visible changes for each release are located at [release notes](http://www.ddcutil.com/release_notes). 11 | -------------------------------------------------------------------------------- /PACKAGING: -------------------------------------------------------------------------------- 1 | When packaging ddcutil for distributions, take note of the following: 2 | 3 | - Use of group i2c for permissions is in general no longer necessary. 4 | The rules in file /usr/lib/60-ddcutil-i2c.rules give the logged on user RW 5 | permission to /dev/i2c devices associated with monitors. However, use of 6 | tag uaccess does not address the case where the user has logged on using ssh. 7 | - File 60-ddcutil-usb.rules is not installed. Monitors that use USB for 8 | communication with their Virtual Control Panels are rare, and error messages 9 | caused by the rules, while benigh, can be confusing. 10 | - File /usr/lib/modules-load.d/ddcutil.conf ensures that driver i2c-dev is 11 | loaded if it is not built into the kernel. 12 | - By default, the build date and time are embedded in the ddcutil and 13 | libddcutil executables. If reproducable builds are required, use configure 14 | option --disable-build-timestamp. -------------------------------------------------------------------------------- /README.gitignore: -------------------------------------------------------------------------------- 1 | Starting with release 1.0.0, .gitignore specifies only files that should be 2 | ignored by any ddcutil git repository, e.g. build artifacts. File of local 3 | interest only should instead be specified in file .git/info/exclude, which 4 | which unlike .gitignore is not tracked in the respository. -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # assumes running from top level ddcutil directory 3 | autoreconf --force -I config -I m4 --install --verbose 4 | test -n "$NOCONFIGURE" || ./configure "$@" 5 | 6 | -------------------------------------------------------------------------------- /config/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /data/ddcutil.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: @PACKAGE@ 7 | Description: Control display settings 8 | URL: http://www.ddcutil.com 9 | Version: @VERSION@ 10 | # No. These are packages required by the library, not the caller 11 | # Requires: @REQUIRED_PACKAGES@ 12 | # Libs and Cflags not needed since using default locations 13 | Libs: -L${libdir} -lddcutil 14 | Cflags: -I${includedir} 15 | -------------------------------------------------------------------------------- /data/etc/X11/xorg.conf.d/90-nvidia-i2c.conf: -------------------------------------------------------------------------------- 1 | # xorg.conf.d file specifying proprietary Nvidia driver options often needed for DDC/CI 2 | Section "Device" 3 | Driver "nvidia" 4 | Identifier "Dev0" 5 | Option "RegistryDwords" "RMUseSwI2c=0x01; RMI2cSpeed=100" 6 | # solves problem of i2c errors with nvidia driver 7 | # per https://devtalk.nvidia.com/default/topic/572292/-solved-does-gddccontrol-work-for-anyone-here-nvidia-i2c-monitor-display-ddc/#4309293 8 | EndSection 9 | -------------------------------------------------------------------------------- /data/etc/modprobe.d/nvidia-i2c.conf: -------------------------------------------------------------------------------- 1 | # modprobe.d file to set proprietary Nvidia driver options often needed for DDC/CI 2 | options nvidia NVreg_RegistryDwords=RMUseSwI2c=0x01;RMI2cSpeed=100 3 | 4 | -------------------------------------------------------------------------------- /data/etc/udev/rules.d/60-ddcutil-i2c.rules: -------------------------------------------------------------------------------- 1 | # Sample rules to grant RW access to /dev/i2c devices. 2 | 3 | # This sample file can be modified and copied to /etc/udev/rules.d. If file 4 | # /etc/udev/rules.d/60-ddcutil-i2c.rules exists, it overrides a file with the 5 | # same name in /usr/lib/udev/rules.d, which is created by ddcutil installation. 6 | # This can be useful in cases where the usual rules do not work as needed, or 7 | # during development. 8 | 9 | # The usual case, using TAG+="uaccess": If a /dev/i2c device is associated 10 | # with a video adapter, grant the current user access to it. 11 | # SUBSYSTEM=="i2c-dev", KERNEL=="i2c-[0-9]*", ATTRS{class}=="0x030000", TAG+="uaccess" 12 | 13 | # Assigns i2c devices to group i2c, and gives that group RW access. 14 | # Individual users must then be assigned to group i2c. 15 | # On some distributions, installing package i2c-tools creates this rule. 16 | # (For example, on Ubuntu, see 40-i2c-tools.rules.) 17 | # KERNEL=="i2c-[0-9]*", GROUP="i2c", MODE="0660" 18 | 19 | # Gives everyone RW access to the /dev/i2c devices: 20 | # KERNEL=="i2c-[0-9]*", MODE="0666" 21 | -------------------------------------------------------------------------------- /data/etc/udev/rules.d/60-ddcutil-usb.rules: -------------------------------------------------------------------------------- 1 | # Rules for monitors implementing USB communication with their Virtual Control Panel. 2 | 3 | # This sample file can be modified and copied to /etc/udev/rules.d. 4 | 5 | # If file /etc/udev/rules.d/60-ddcutil-usb.rules exists, it overrides a file with 6 | # the same name in /usr/lib/udev/rules.d. (This file used to be created by ddcutil 7 | # installation.) 8 | 9 | # The simplest solution is to specify a particular monitor device by its vid/pid, 10 | # and then use TAG+="uaccess" to grant the current user read/write access to it. 11 | # The values in this example are for an Apple Cinema Display, model A1082: 12 | # SUBSYSTEM=="usbmisc", ATTRS{idVendor}=="05ac", ATTRS{idProduct}=="9223", TAG+="uaccess" 13 | 14 | # A more general solution is to use ddcutil chkusbmon to check if a USB Human 15 | # Interface device implements the USB Device Class Definition for Human Interface 16 | # Devices. Unfortunately, this has been seen to cause system instability in 17 | # certain ill-defined cases. 18 | 19 | # Note this rule may have to be adjusted to reflect the actual path where 20 | # ddcutil is installed. The -v option produces informational messages. 21 | # These are lost when the rule is normally executed by udev, but can be 22 | # helpful when rules are tested using the "udevadm test" command. 23 | # SUBSYSTEM=="usbmisc", KERNEL=="hiddev*", PROGRAM="/usr/bin/ddcutil chkusbmon $env{DEVNAME} -v", TAG+="uaccess" 24 | 25 | -------------------------------------------------------------------------------- /data/usr/lib/modules-load.d/ddcutil.conf: -------------------------------------------------------------------------------- 1 | i2c-dev 2 | -------------------------------------------------------------------------------- /data/usr/lib/udev/rules.d/60-ddcutil-i2c.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM=="i2c-dev", KERNEL=="i2c-[0-9]*", ATTRS{class}=="0x030000", TAG+="uaccess" 2 | SUBSYSTEM=="dri", KERNEL=="card[0-9]*", TAG+="uaccess" 3 | -------------------------------------------------------------------------------- /docs/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | SUBDIRS = 3 | # SUBDIRS += ddcutil 4 | 5 | if USE_DOXYGEN 6 | SUBDIRS += doxygen 7 | endif 8 | 9 | if USE_DOXYGEN 10 | if HAVE_DOCBASE 11 | 12 | docbasedir = $(datadir)/doc-base 13 | 14 | docbase_DATA = ddcutil-c-api 15 | 16 | EXTRA_DIST = ddcutil-c-api 17 | 18 | install-data-local: 19 | @echo "(docs/Makefile) Executing rule install-data-local" 20 | 21 | install-data-hook: 22 | @echo "(docs/Makefile) Executing rule install-data-hook" 23 | @echo "docbasedir $(docbasedir)" 24 | @echo "datadir $(datadir)" 25 | install-docs --install-changed 26 | 27 | # uninstall-data-hook doesn't exist, use uninstall-hook: 28 | 29 | uninstall-hook: 30 | @echo "(docs/Makefile) Executing rule uninstall-data-hook" 31 | install-docs --install-changed 32 | 33 | endif 34 | endif 35 | -------------------------------------------------------------------------------- /docs/ddcutil-c-api.in: -------------------------------------------------------------------------------- 1 | Document: ddcutil-c-api 2 | Title: ddcutil C API 3 | Author: Sanford Rockowitz 4 | Abstract: This doxgygen generated manual documents the ddcutil C API. 5 | You're probably better off just looking at the header files and sample code. 6 | Section: System/Hardware 7 | 8 | Format: HTML 9 | Index: @prefix@/share/doc/ddcutil/html/index.html 10 | Files: @prefix@/share/doc/ddcutil/html/* 11 | 12 | -------------------------------------------------------------------------------- /docs/doxygen/Makefile.am: -------------------------------------------------------------------------------- 1 | docpkg = $(PACKAGE_TARNAME)-doxy-$(PACKAGE_VERSION).tar.gz 2 | 3 | doc_DATA = $(docpkg) 4 | 5 | $(docpkg): doxygen.stamp 6 | tar chof - html | gzip -9 -c >$@ 7 | 8 | doxygen.stamp: doxyfile 9 | $(DOXYGEN) $(DOXYFLAGS) $< 10 | echo Timestamp > $@ 11 | 12 | install-data-hook: 13 | cd $(DESTDIR)$(docdir) && tar xf $(docpkg) 14 | 15 | uninstall-hook: 16 | cd $(DESTDIR)$(docdir) && rm -rf html 17 | 18 | CLEANFILES = doxywarn.txt doxygen.stamp $(docpkg) 19 | 20 | clean-local: 21 | rm -rf html 22 | 23 | 24 | -------------------------------------------------------------------------------- /doxydoc/di: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Problem: if run from other than doxydocs directory, 4 | # doxygen picks up files from subdirectories of that directory, 5 | # despite the explicit INPUT statement in the control file. 6 | # So change to the doxydocs directory and execute the command there 7 | 8 | curdir=$PWD 9 | 10 | doxyfile=`dirname $0`/internals.doxyfile 11 | 12 | cd `dirname $0` 13 | 14 | # cmd="doxygen ${doxyfile}" 15 | cmd="doxygen internals.doxyfile" 16 | echo "Executing command: ${cmd}" 17 | $cmd 18 | 19 | cd $curdir 20 | -------------------------------------------------------------------------------- /doxydoc/internals_mainpage.md: -------------------------------------------------------------------------------- 1 | **ddcutil** Internal Documentation 2 | 3 | -------------------------------------------------------------------------------- /icons/hicolor/128x128/apps/ddcutil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockowitz/ddcutil/ef4b79da505c7ed5a80de00b62fb9d0e485e9331/icons/hicolor/128x128/apps/ddcutil.png -------------------------------------------------------------------------------- /icons/hicolor/16x16/apps/ddcutil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockowitz/ddcutil/ef4b79da505c7ed5a80de00b62fb9d0e485e9331/icons/hicolor/16x16/apps/ddcutil.png -------------------------------------------------------------------------------- /icons/hicolor/256x256/apps/ddcutil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockowitz/ddcutil/ef4b79da505c7ed5a80de00b62fb9d0e485e9331/icons/hicolor/256x256/apps/ddcutil.png -------------------------------------------------------------------------------- /icons/hicolor/32x32/apps/ddcutil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockowitz/ddcutil/ef4b79da505c7ed5a80de00b62fb9d0e485e9331/icons/hicolor/32x32/apps/ddcutil.png -------------------------------------------------------------------------------- /icons/hicolor/48x48/apps/ddcutil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockowitz/ddcutil/ef4b79da505c7ed5a80de00b62fb9d0e485e9331/icons/hicolor/48x48/apps/ddcutil.png -------------------------------------------------------------------------------- /icons/hicolor/64x64/apps/ddcutil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockowitz/ddcutil/ef4b79da505c7ed5a80de00b62fb9d0e485e9331/icons/hicolor/64x64/apps/ddcutil.png -------------------------------------------------------------------------------- /m4/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !ax_* 4 | ax_python_devel_alt.m4 5 | *~ 6 | !introspection.m4 7 | 8 | -------------------------------------------------------------------------------- /m4/ax_swig_enable_cxx.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.gnu.org/software/autoconf-archive/ax_swig_enable_cxx.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_SWIG_ENABLE_CXX 8 | # 9 | # DESCRIPTION 10 | # 11 | # Enable SWIG C++ support. This affects all invocations of $(SWIG). 12 | # 13 | # LICENSE 14 | # 15 | # Copyright (c) 2008 Sebastian Huber 16 | # Copyright (c) 2008 Alan W. Irwin 17 | # Copyright (c) 2008 Rafael Laboissiere 18 | # Copyright (c) 2008 Andrew Collier 19 | # 20 | # This program is free software; you can redistribute it and/or modify it 21 | # under the terms of the GNU General Public License as published by the 22 | # Free Software Foundation; either version 2 of the License, or (at your 23 | # option) any later version. 24 | # 25 | # This program is distributed in the hope that it will be useful, but 26 | # WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 28 | # Public License for more details. 29 | # 30 | # You should have received a copy of the GNU General Public License along 31 | # with this program. If not, see . 32 | # 33 | # As a special exception, the respective Autoconf Macro's copyright owner 34 | # gives unlimited permission to copy, distribute and modify the configure 35 | # scripts that are the output of Autoconf when processing the Macro. You 36 | # need not follow the terms of the GNU General Public License when using 37 | # or distributing such scripts, even though portions of the text of the 38 | # Macro appear in them. The GNU General Public License (GPL) does govern 39 | # all other use of the material that constitutes the Autoconf Macro. 40 | # 41 | # This special exception to the GPL applies to versions of the Autoconf 42 | # Macro released by the Autoconf Archive. When you make and distribute a 43 | # modified version of the Autoconf Macro, you may extend this special 44 | # exception to the GPL to apply to your modified version as well. 45 | 46 | #serial 9 47 | 48 | AU_ALIAS([SWIG_ENABLE_CXX], [AX_SWIG_ENABLE_CXX]) 49 | AC_DEFUN([AX_SWIG_ENABLE_CXX],[ 50 | AC_REQUIRE([AX_PKG_SWIG]) 51 | AC_REQUIRE([AC_PROG_CXX]) 52 | SWIG="$SWIG -c++" 53 | ]) 54 | -------------------------------------------------------------------------------- /m4/ax_unprecious.m4: -------------------------------------------------------------------------------- 1 | AC_DEFUN([AX_UNPRECIOUS], [ 2 | m4_define([_AC_PRECIOUS_VARS], 3 | m4_bpatsubst(_AC_PRECIOUS_VARS, [$1], [])) 4 | ]) 5 | 6 | -------------------------------------------------------------------------------- /man/Makefile.am: -------------------------------------------------------------------------------- 1 | if !INSTALL_LIB_ONLY_COND 2 | man_MANS = ddcutil.1 3 | else 4 | man_MANS = 5 | endif 6 | EXTRA_DIST = $(man_MANS) 7 | 8 | # dist_man1_MANS = \ 9 | # ddcutil.1 10 | 11 | -------------------------------------------------------------------------------- /pixmaps/ddcutil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rockowitz/ddcutil/ef4b79da505c7ed5a80de00b62fb9d0e485e9331/pixmaps/ddcutil.png -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=rockowitz_ddcutil 2 | sonar.organization=rockowitz 3 | 4 | # This is the name and version displayed in the SonarCloud UI. 5 | #sonar.projectName=ddcutil 6 | #sonar.projectVersion=1.0 7 | 8 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 9 | #sonar.sources=. 10 | 11 | # Encoding of the source code. Default is default system encoding 12 | #sonar.sourceEncoding=UTF-8 13 | -------------------------------------------------------------------------------- /src/app_ddcutil/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | -I$(top_srcdir)/src \ 4 | -I$(top_srcdir)/src/public 5 | 6 | if USE_LIBDRM_COND 7 | AM_CPPFLAGS += \ 8 | $(LIBDRM_CFLAGS) 9 | endif 10 | 11 | 12 | AM_CFLAGS = -Wall 13 | if WARNINGS_ARE_ERRORS_COND 14 | AM_CFLAGS += -Werror 15 | endif 16 | # AM_CFLAGS += -Wpedantic 17 | 18 | if ENABLE_CALLGRAPH_COND 19 | AM_CFLAGS += -fdump-rtl-expand 20 | endif 21 | 22 | CLEANFILES = \ 23 | *expand 24 | 25 | # Intermediate Library 26 | noinst_LTLIBRARIES = libappddcutil.la 27 | 28 | libappddcutil_la_SOURCES = \ 29 | main.c \ 30 | app_capabilities.c \ 31 | app_dumpload.c \ 32 | app_dynamic_features.c \ 33 | app_experimental.c \ 34 | app_getvcp.c \ 35 | app_probe.c \ 36 | app_ddcutil_services.c \ 37 | app_setvcp.c \ 38 | app_vcpinfo.c \ 39 | app_watch.c 40 | 41 | if INCLUDE_TESTCASES_COND 42 | libappddcutil_la_SOURCES += app_testcases.c 43 | endif 44 | 45 | if ENABLE_ENVCMDS_COND 46 | libappddcutil_la_SOURCES += \ 47 | app_interrogate.c 48 | endif 49 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_capabilities.h: -------------------------------------------------------------------------------- 1 | /** \file app_capabilities.h 2 | * 3 | * Implement the CAPABILITIES command 4 | */ 5 | 6 | // Copyright (C) 2020-2021 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef APP_CAPABILITIES_H_ 10 | #define APP_CAPABILITIES_H_ 11 | 12 | /** \cond */ 13 | #include "base/displays.h" 14 | /** \endcond */ 15 | #include "vcp/parse_capabilities.h" 16 | 17 | DDCA_Status 18 | app_get_capabilities_string( 19 | Display_Handle * dh, 20 | char ** capabilities_string_loc); 21 | 22 | void 23 | app_show_parsed_capabilities( 24 | Display_Handle * dh, 25 | Parsed_Capabilities * pcap); 26 | 27 | DDCA_Status 28 | app_capabilities( // implements the CAPABILITIES command 29 | Display_Handle * dh); 30 | 31 | void init_app_capabilities(); 32 | 33 | #endif /* APP_CAPABILITIES_H_ */ 34 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_ddcutil_services.c: -------------------------------------------------------------------------------- 1 | /** @file app_ddcutil_services.c 2 | * Initialize files in directory app_ddcutil 3 | */ 4 | 5 | // Copyright (C) 2023 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #include "config.h" 9 | 10 | #include "app_capabilities.h" 11 | #include "app_dumpload.h" 12 | #include "app_dynamic_features.h" 13 | #include "app_getvcp.h" 14 | #ifdef ENABLE_ENVCMDS 15 | #include "app_interrogate.h" 16 | #endif 17 | #include "app_probe.h" 18 | #include "app_setvcp.h" 19 | #include "app_vcpinfo.h" 20 | #include "app_watch.h" 21 | #include "app_vcpinfo.h" 22 | 23 | void init_app_ddcutil_services() { 24 | init_app_capabilities(); 25 | init_app_dumpload(); 26 | init_app_dynamic_features(); 27 | init_app_getvcp(); 28 | #ifdef ENABLE_ENVCMDS 29 | init_app_interrogate(); 30 | #endif 31 | init_app_probe(); 32 | init_app_setvcp(); 33 | init_app_vcpinfo(); 34 | init_app_watch(); 35 | // main initialized by local init call 36 | } 37 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_ddcutil_services.h: -------------------------------------------------------------------------------- 1 | /** @file app_services.h 2 | * Master initializer for app_ddcutil directory 3 | */ 4 | 5 | // Copyright (C) 2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef APP_SERVICES_H_ 9 | #define APP_SERVICES_H_ 10 | 11 | void init_app_ddcutil_services(); 12 | 13 | #endif /* APP_DDCUTIL_SERVICES_H_ */ 14 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_dumpload.h: -------------------------------------------------------------------------------- 1 | /** @file app_dumpload.h 2 | * 3 | * Implement the DUMPVCP and LOADVCP commands 4 | */ 5 | 6 | // Copyright (C) 2014-2022 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef APP_DUMPLOAD_H_ 10 | #define APP_DUMPLOAD_H_ 11 | 12 | #include 13 | #include 14 | 15 | Status_Errno_DDC 16 | app_loadvcp_by_file(const char * fn, Display_Handle * dh); 17 | 18 | Status_Errno_DDC 19 | app_dumpvcp_as_file(Display_Handle * dh, const char * optional_filename); 20 | 21 | void 22 | init_app_dumpload(); 23 | 24 | #endif /* APP_DUMPLOAD_H_ */ 25 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_dynamic_features.c: -------------------------------------------------------------------------------- 1 | /** @file app_dynamic_features.c */ 2 | 3 | // Copyright (C) 2018-2024 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | /** \cond */ 7 | #include 8 | #include 9 | #include 10 | 11 | #include "ddcutil_types.h" 12 | #include "ddcutil_status_codes.h" 13 | 14 | #include "util/error_info.h" 15 | #include "util/string_util.h" 16 | /** \endcond */ 17 | 18 | #include "base/core.h" 19 | #include "base/dynamic_features.h" 20 | #include "base/monitor_model_key.h" 21 | #include "base/rtti.h" 22 | 23 | #include "dynvcp/dyn_feature_files.h" 24 | 25 | #include "app_dynamic_features.h" 26 | 27 | 28 | /** Wraps call to #dfr_check_by_dref(), writing error messages 29 | * for errors reported. 30 | * 31 | * \param dref display reference 32 | * \return false if errors occurred, true otherwise 33 | */ 34 | bool app_check_dynamic_features(Display_Ref * dref) { 35 | bool debug = false; 36 | DBGTRC_STARTING(debug, DDCA_TRC_TOP|DDCA_TRC_UDF, "dref=%s, enable_dynamic_features=%s", 37 | dref_repr_t(dref), sbool(enable_dynamic_features)); 38 | 39 | bool result = true; 40 | if (!enable_dynamic_features) // global variable 41 | goto bye; 42 | 43 | Error_Info * errs = dfr_check_by_dref(dref); 44 | DDCA_Output_Level ol = get_output_level(); 45 | if (errs) { 46 | if (errs->status_code == DDCRC_NOT_FOUND) { 47 | if (ol >= DDCA_OL_VERBOSE) { 48 | f0printf(fout(), "%s\n", errs->detail); 49 | } 50 | } 51 | else { 52 | // errinfo_report(errs, 1); 53 | f0printf(fout(), "%s\n", errs->detail); 54 | for (int ndx = 0; ndx < errs->cause_ct; ndx++) { 55 | f0printf(fout(), " %s\n", errs->causes[ndx]->detail); 56 | } 57 | result = false; 58 | } 59 | errinfo_free(errs); 60 | } 61 | else { 62 | // dbgrpt_dynamic_features_rec(dfr, 1); 63 | if (ol >= DDCA_OL_VERBOSE) { 64 | f0printf(fout(), "Processed feature definition file: %s\n", 65 | dref->dfr->filename); 66 | } 67 | } 68 | 69 | bye: 70 | DBGTRC_RET_BOOL(debug, DDCA_TRC_UDF, result, ""); 71 | return result; 72 | } 73 | 74 | 75 | void init_app_dynamic_features() { 76 | RTTI_ADD_FUNC(app_check_dynamic_features); 77 | } 78 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_dynamic_features.h: -------------------------------------------------------------------------------- 1 | //* @file app_dynamic_features.h */ 2 | 3 | // Copyright (C) 2018-2024 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef APP_DYNAMIC_FEATURES_H_ 7 | #define APP_DYNAMIC_FEATURES_H_ 8 | 9 | #include "base/displays.h" 10 | 11 | bool app_check_dynamic_features(Display_Ref * dref); 12 | void init_app_dynamic_features(); 13 | 14 | #endif /* APP_DYNAMIC_FEATURES_H_ */ 15 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_experimental.h: -------------------------------------------------------------------------------- 1 | /** \file app_experimental.h */ 2 | 3 | // Copyright (C) 2021-2024 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef APP_EXPERIMENTAL_H_ 7 | #define APP_EXPERIMENTAL_H_ 8 | 9 | #include "cmdline/parsed_cmd.h" 10 | 11 | void report_experimental_options(Parsed_Cmd * parsed_cmd, int depth); 12 | 13 | void test_display_detection_variants(); 14 | 15 | #endif /* APP_EXPERIMENTAL_H_ */ 16 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_getvcp.h: -------------------------------------------------------------------------------- 1 | /** @file app_getvcp.h 2 | * Implement the GETVCP command 3 | */ 4 | 5 | //Copyright (C) 2014-2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef APP_GETVCP_H_ 9 | #define APP_GETVCP_H_ 10 | 11 | #include "public/ddcutil_types.h" 12 | 13 | /** \cond */ 14 | #include 15 | /** \endcond */ 16 | 17 | #include "base/displays.h" 18 | #include "base/feature_set_ref.h" 19 | #include "base/status_code_mgt.h" 20 | 21 | #include "cmdline/parsed_cmd.h" 22 | 23 | Status_Errno_DDC 24 | app_show_single_vcp_value_by_feature_id( 25 | Display_Handle * dh, 26 | DDCA_Vcp_Feature_Code feature_id, 27 | bool force); 28 | 29 | Status_Errno_DDC 30 | app_show_vcp_subset_values_by_dh( 31 | Display_Handle * dh, 32 | VCP_Feature_Subset subset, 33 | Feature_Set_Flags flags, 34 | Bit_Set_256 * features_seen); 35 | 36 | Status_Errno_DDC 37 | app_show_feature_set_values_by_dh( 38 | Display_Handle * dh, 39 | Parsed_Cmd * parsed_cmd); 40 | 41 | void 42 | init_app_getvcp(); 43 | 44 | #endif /* APP_GETVCP_H_ */ 45 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_interrogate.h: -------------------------------------------------------------------------------- 1 | /** \file app_interrogate.h */ 2 | 3 | // Copyright (C) 2021-2022 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef APP_INTERROGATE_H_ 7 | #define APP_INTERROGATE_H_ 8 | 9 | #include "cmdline/parsed_cmd.h" 10 | 11 | void app_interrogate(Parsed_Cmd * parsed_cmd); 12 | void init_app_interrogate(); 13 | 14 | #endif /* APP_INTERROGATE_H_ */ 15 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_probe.h: -------------------------------------------------------------------------------- 1 | /** @file app_probe.h 2 | * Implement PROBE command 3 | */ 4 | 5 | // Copyright (C) 2020-2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef APP_PROBE_H_ 9 | #define APP_PROBE_H_ 10 | 11 | #include "base/displays.h" 12 | 13 | void app_probe_display_by_dref(Display_Ref * dref); 14 | void app_probe_display_by_dh(Display_Handle * dh); 15 | void init_app_probe(); 16 | 17 | #endif /* APP_PROBE_H_ */ 18 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_setvcp.h: -------------------------------------------------------------------------------- 1 | /** @file app_setvcp.h 2 | * 3 | * Implement the SETVCP command 4 | */ 5 | 6 | // Copyright (C) 2014-2022 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef APP_SETVCP_H_ 10 | #define APP_SETVCP_H_ 11 | 12 | #include "cmdline/parsed_cmd.h" 13 | #include "base/displays.h" 14 | #include "base/status_code_mgt.h" 15 | 16 | Status_Errno_DDC 17 | app_setvcp( 18 | Parsed_Cmd * parsed_cmd, 19 | Display_Handle * dh); 20 | 21 | void init_app_setvcp(); 22 | 23 | #endif /* APP_SETVCP_H_ */ 24 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_testcases.c: -------------------------------------------------------------------------------- 1 | // app_testcases.c 2 | 3 | // Copyright (C) 2014-2021 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include 7 | #include 8 | 9 | #include "ddcutil_status_codes.h" 10 | 11 | #include "util/error_info.h" 12 | #include "base/core.h" 13 | #include "cmdline/parsed_cmd.h" 14 | #include "ddc/ddc_displays.h" 15 | #include "ddc/ddc_vcp.h" 16 | #include "test/testcases.h" 17 | #include "app_ddcutil/app_testcases.h" 18 | 19 | bool 20 | app_testcases(Parsed_Cmd* parsed_cmd) 21 | { 22 | int testnum; 23 | bool ok = true; 24 | int ct = sscanf(parsed_cmd->args[0], "%d", &testnum); 25 | if (ct != 1) { 26 | f0printf(fout(), "Invalid test number: %s\n", parsed_cmd->args[0]); 27 | ok = false; 28 | } 29 | else { 30 | ddc_ensure_displays_detected(); 31 | ok = true; 32 | // Why is ddc_save_current_settings() call here? 33 | #ifdef OUT 34 | Error_Info * ddc_excp = ddc_save_current_settings(dh); 35 | if (ddc_excp) { 36 | f0printf(fout(), "Save current settings failed. rc=%s\n", psc_desc(ddc_excp->status_code)); 37 | if (ddc_excp->status_code == DDCRC_RETRIES) 38 | f0printf(fout(), " Try errors: %s", errinfo_causes_string(ddc_excp) ); 39 | errinfo_report(ddc_excp, 0); // ** ALTERNATIVE **/ 40 | errinfo_free(ddc_excp); 41 | // ERRINFO_FREE_WITH_REPORT(ddc_excp, report_exceptions); 42 | ok = false; 43 | } 44 | if (ok) { 45 | #endif 46 | if (!parsed_cmd->pdid) 47 | parsed_cmd->pdid = create_dispno_display_identifier(1); // default monitor 48 | ok = execute_testcase(testnum, parsed_cmd->pdid); 49 | #ifdef OUT 50 | } 51 | #endif 52 | } 53 | 54 | return ok; 55 | } 56 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_testcases.h: -------------------------------------------------------------------------------- 1 | // app_testcases.h 2 | 3 | // Copyright (C) 2021 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef APP_TESTCASES_H_ 7 | #define APP_TESTCASES_H_ 8 | 9 | #include 10 | #include "cmdline/parsed_cmd.h" 11 | 12 | bool 13 | app_testcases(Parsed_Cmd* parsed_cmd); 14 | 15 | #endif /* APP_TESTCASES_H_ */ 16 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_vcpinfo.h: -------------------------------------------------------------------------------- 1 | /** @file app_vcpinfo.h 2 | * 3 | * Implement VCPINFO and (deprecated) LISTVCP commands 4 | */ 5 | 6 | // Copyright (C) 2020-2023 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef APP_VCPINFO_H_ 10 | #define APP_VCPINFO_H_ 11 | 12 | #include 13 | #include 14 | 15 | #include "cmdline/parsed_cmd.h" 16 | 17 | void 18 | app_listvcp(FILE * fh); 19 | 20 | bool 21 | app_vcpinfo(Parsed_Cmd * parsed_cmd); 22 | 23 | void 24 | init_app_vcpinfo(); 25 | 26 | #endif /* APP_VCPINFO_H_ */ 27 | -------------------------------------------------------------------------------- /src/app_ddcutil/app_watch.h: -------------------------------------------------------------------------------- 1 | /** @file app_watch.h 2 | * Implement the WATCH command 3 | */ 4 | 5 | //Copyright (C) 2014-2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef APP_WATCH_H_ 9 | #define APP_WATCH_H_ 10 | 11 | #include "base/displays.h" 12 | 13 | void 14 | app_read_changes_forever( 15 | Display_Handle * dh, 16 | bool force_no_fifo); 17 | 18 | void 19 | init_app_watch(); 20 | #endif /* APP_WATCH_H_ */ 21 | -------------------------------------------------------------------------------- /src/app_sysenv/Makefile.am: -------------------------------------------------------------------------------- 1 | if ENABLE_ENVCMDS_COND 2 | 3 | AM_CPPFLAGS = \ 4 | $(GLIB_CFLAGS) \ 5 | -I$(top_srcdir)/src \ 6 | -I$(top_srcdir)/src/public 7 | 8 | if USE_LIBDRM_COND 9 | AM_CPPFLAGS += \ 10 | $(LIBDRM_CFLAGS) 11 | endif 12 | 13 | 14 | AM_CFLAGS = -Wall 15 | if WARNINGS_ARE_ERRORS_COND 16 | AM_CFLAGS += -Werror 17 | endif 18 | # AM_CFLAGS += -Wpedantic 19 | 20 | if ENABLE_CALLGRAPH_COND 21 | AM_CFLAGS += -fdump-rtl-expand 22 | endif 23 | 24 | CLEANFILES = \ 25 | *expand 26 | 27 | # Intermediate Library 28 | noinst_LTLIBRARIES = libappsysenv.la 29 | 30 | libappsysenv_la_SOURCES = \ 31 | app_sysenv_services.c \ 32 | query_sysenv.c \ 33 | query_sysenv_access.c \ 34 | query_sysenv_base.c \ 35 | query_sysenv_dmidecode.c \ 36 | query_sysenv_i2c.c \ 37 | query_sysenv_logs.c \ 38 | query_sysenv_modules.c \ 39 | query_sysenv_procfs.c \ 40 | query_sysenv_sysfs_common.c \ 41 | query_sysenv_original_sys_scans.c \ 42 | query_sysenv_detailed_bus_pci_devices.c \ 43 | query_sysenv_simplified_sys_bus_pci_devices.c \ 44 | query_sysenv_sysfs.c \ 45 | query_sysenv_xref.c 46 | 47 | if ENABLE_USB_COND 48 | libappsysenv_la_SOURCES += \ 49 | query_sysenv_usb.c 50 | endif 51 | 52 | if USE_LIBDRM_COND 53 | libappsysenv_la_SOURCES += \ 54 | query_sysenv_drm.c 55 | endif 56 | 57 | endif 58 | -------------------------------------------------------------------------------- /src/app_sysenv/app_sysenv_services.c: -------------------------------------------------------------------------------- 1 | // app_sysenv_services.c 2 | 3 | // Copyright (C) 2018 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include "app_sysenv_services.h" 7 | #include "query_sysenv_detailed_bus_pci_devices.h" 8 | #include "query_sysenv_sysfs.h" 9 | 10 | void init_app_sysenv_services() { 11 | init_query_detailed_bus_pci_devices(); 12 | init_query_sysenv_sysfs(); 13 | init_query_sysenv(); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/app_sysenv/app_sysenv_services.h: -------------------------------------------------------------------------------- 1 | // app_sysenv_services.h 2 | 3 | // Copyright (C) 2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include "query_sysenv_detailed_bus_pci_devices.h" 7 | #include "query_sysenv_sysfs.h" 8 | #include "query_sysenv.h" 9 | 10 | #ifndef APP_SYSENV_SERVICES_H_ 11 | #define APP_SYSENV_SERVICES_H_ 12 | 13 | void init_app_sysenv_services(); 14 | 15 | #endif /* APP_SYSENV_SERVICES_H_ */ 16 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv.h: -------------------------------------------------------------------------------- 1 | /** @file query_sysenv.h 2 | * 3 | * Primary file for the ENVIRONMENT command 4 | */ 5 | 6 | // Copyright (C) 2014-2024 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef QUERY_SYSENV_H_ 10 | #define QUERY_SYSENV_H_ 11 | 12 | #include 13 | 14 | #include "cmdline/parsed_cmd.h" 15 | 16 | void force_envcmd_settings(Parsed_Cmd * parsed_cmd); 17 | void query_sysenv(bool quickenv); 18 | 19 | void init_query_sysenv(); 20 | 21 | #endif /* QUERY_SYSENV_H_ */ 22 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_access.h: -------------------------------------------------------------------------------- 1 | /* @file query_sysenv_access.h 2 | * 3 | * Checks on the the existence of and access to /dev/i2c devices 4 | */ 5 | 6 | // Copyright (C) 2014-2021 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | 10 | #ifndef QUERY_SYSENV_ACCESS_H_ 11 | #define QUERY_SYSENV_ACCESS_H_ 12 | 13 | #include "util/data_structures.h" 14 | 15 | #include "app_sysenv/query_sysenv_base.h" 16 | 17 | Byte_Value_Array identify_i2c_devices(); 18 | 19 | void check_i2c_devices(Env_Accumulator * accum); 20 | 21 | #endif /* QUERY_SYSENV_ACCESS_H_ */ 22 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_detailed_bus_pci_devices.h: -------------------------------------------------------------------------------- 1 | // query_sysenv_detailed_bus_pci_devices.h 2 | 3 | // Copyright (C) 2021 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef QUERY_SYSENV_DETAILED_BUS_PCI_DEVICES_H_ 7 | #define QUERY_SYSENV_DETAILED_BUS_PCI_DEVICES_H_ 8 | 9 | void dump_detailed_sys_bus_pci(int depth); 10 | 11 | void init_query_detailed_bus_pci_devices(); 12 | 13 | #endif // QUERY_SYSENV_DETAILED_BUS_PCI_DEVICES_H_ 14 | 15 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_dmidecode.h: -------------------------------------------------------------------------------- 1 | /** @file query_sysenv_dmidecode.h 2 | * 3 | * dmidecode report for the environment command 4 | */ 5 | 6 | // Copyright (C) 2016-2019 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef QUERY_SYSENV_DMIDECODE_H_ 10 | #define QUERY_SYSENV_DMIDECODE_H_ 11 | 12 | void query_dmidecode(); 13 | 14 | #endif /* QUERY_SYSENV_DMIDECODE_H_ */ 15 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_drm.h: -------------------------------------------------------------------------------- 1 | /** @file query_drm_sysenv.h 2 | * 3 | * drm reporting for the environment command 4 | */ 5 | 6 | // Copyright (C) 2017-2019 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef QUERY_DRM_SYSENV_H_ 10 | #define QUERY_DRM_SYSENV_H_ 11 | 12 | void probe_using_libdrm(); 13 | 14 | #endif /* QUERY_DRM_SYSENV_H_ */ 15 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_i2c.h: -------------------------------------------------------------------------------- 1 | /** @file query_sysenv_i2c.h 2 | * 3 | * Check I2C devices using directly coded I2C calls 4 | */ 5 | 6 | // Copyright (C) 2014-2018 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef QUERY_SYSENV_I2C_H_ 10 | #define QUERY_SYSENV_I2C_H_ 11 | 12 | #include "query_sysenv_base.h" 13 | 14 | 15 | void raw_scan_i2c_devices(Env_Accumulator * accum); 16 | void test_edid_read_variants(Env_Accumulator * accum); 17 | void query_i2c_buses(); 18 | 19 | #endif /* QUERY_SYSENV_I2C_H_ */ 20 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_logs.h: -------------------------------------------------------------------------------- 1 | /** @file query_sysenv_logs.h 2 | * 3 | * Query configuration files, logs, and output of logging commands. 4 | */ 5 | 6 | // Copyright (C) 2017-2023 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef QUERY_SYSENV_LOGS_H_ 10 | #define QUERY_SYSENV_LOGS_H_ 11 | 12 | #include "query_sysenv_base.h" 13 | 14 | void probe_logs(Env_Accumulator * accum); 15 | void probe_config_files(Env_Accumulator * accum); 16 | void probe_cache_files(int depth); 17 | 18 | #endif /* QUERY_SYSENV_LOGS_H_ */ 19 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_modules.h: -------------------------------------------------------------------------------- 1 | /** \f query_sysenv_modules.h 2 | * 3 | * Module checks 4 | */ 5 | 6 | // Copyright (C) 2014-2021 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | 10 | #ifndef QUERY_SYSENV_MODULES_H_ 11 | #define QUERY_SYSENV_MODULES_H_ 12 | 13 | #include 14 | 15 | #include "query_sysenv_base.h" 16 | 17 | void check_i2c_dev_module(Env_Accumulator * accum, int depth); 18 | void probe_modules_d(int depth); 19 | 20 | #endif /* QUERY_SYSENV_MODULES_H_ */ 21 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_original_sys_scans.h: -------------------------------------------------------------------------------- 1 | // query_sysenv_original_sys_scans.h 2 | 3 | // Copyright (C) 2021 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef QUERY_SYSENV_ORIGINAL_SYS_SCANS_H_ 7 | #define QUERY_SYSENV_ORIGINAL_SYS_SCANS_H_ 8 | 9 | void dump_original_sys_scans(); 10 | 11 | #endif /* QUERY_SYSENV_ORIGINAL_SYS_SCANS_H_ */ 12 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_procfs.h: -------------------------------------------------------------------------------- 1 | /** @file query_sysenv_procfs.h 2 | * 3 | * Query environment using /proc file system 4 | */ 5 | 6 | // Copyright (C) 2014-2019 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef QUERY_SYSENV_PROCFS_H_ 10 | #define QUERY_SYSENV_PROCFS_H_ 11 | 12 | /** \cond */ 13 | #include 14 | /** \endcond */ 15 | 16 | int query_proc_modules_for_video(); 17 | bool query_proc_driver_nvidia(); 18 | 19 | #endif /* QUERY_SYSENV_PROCFS_H_ */ 20 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_simplified_sys_bus_pci_devices.h: -------------------------------------------------------------------------------- 1 | // query_sysenv_sys_bus_pci_devices.h 2 | 3 | // Copyright (C) 2021 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef QUERY_SYSENV_SIMPLIFIED_SYS_BUS_PCI_DEVICES_H_ 7 | #define QUERY_SYSENV_SIMPLIFIED_SYS_BUS_PCI_DEVICES_H_ 8 | 9 | void dump_simplified_sys_bus_pci(int depth); 10 | 11 | #endif /* QUERY_SYSENV_SIMPLIFIED_SYS_BUS_PCI_DEVICES_H_ */ 12 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_sysfs.h: -------------------------------------------------------------------------------- 1 | /** @file query_sysenv_sysfs.h 2 | * 3 | * Query environment using /sys file system 4 | */ 5 | 6 | // Copyright (C) 2014-2024 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef QUERY_SYSENV_SYSFS_H_ 10 | #define QUERY_SYSENV_SYSFS_H_ 11 | 12 | #include "query_sysenv_base.h" 13 | 14 | typedef struct { 15 | unsigned short int vendor_id; 16 | unsigned short int device_id; 17 | unsigned short int subdevice_id; // subsystem device id 18 | unsigned short int subvendor_id; // subsystem vendor id 19 | } Device_Ids; 20 | Device_Ids read_device_ids1(char * cur_dir_name); 21 | Device_Ids read_device_ids2(char * cur_dir_name); 22 | 23 | void query_card_and_driver_using_sysfs(Env_Accumulator * accum); 24 | void query_loaded_modules_using_sysfs(); 25 | void query_sys_bus_i2c(Env_Accumulator * accum); 26 | void query_sys_amdgpu_parameters(int depth); 27 | void query_drm_using_sysfs(); 28 | void dump_sysfs_i2c(Env_Accumulator * accum); 29 | void init_query_sysenv_sysfs(); 30 | 31 | #endif /* QUERY_SYSENV_SYSFS_H_ */ 32 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_sysfs_common.c: -------------------------------------------------------------------------------- 1 | // query_sysenv_sysfs_common.c 2 | 3 | // Copyright (C) 2021 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "util/string_util.h" 12 | #include "util/sysfs_util.h" 13 | 14 | #include "base/core.h" 15 | 16 | #include "query_sysenv_sysfs_common.h" 17 | 18 | // Local conversion functions for data coming from sysfs, 19 | // which should always be valid. 20 | 21 | ushort h2ushort(char * hval) { 22 | bool debug = false; 23 | 24 | ushort ival; 25 | #ifdef NDEBUG 26 | sscanf(hval, "%hx", &ival); 27 | #else 28 | assert( sscanf(hval, "%hx", &ival) == 1); 29 | #endif 30 | 31 | DBGMSF(debug, "hhhh = |%s|, returning 0x%04x", hval, ival); 32 | return ival; 33 | } 34 | 35 | unsigned h2uint(char * hval) { 36 | bool debug = false; 37 | 38 | unsigned ival; 39 | #ifdef NDEBUG 40 | sscanf(hval, "%x", &ival); 41 | #else 42 | assert( sscanf(hval, "%x", &ival) == 1); 43 | #endif 44 | 45 | DBGMSF(debug, "hhhh = |%s|, returning 0x%08x", hval, ival); 46 | return ival; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_sysfs_common.h: -------------------------------------------------------------------------------- 1 | // query_sysenv_sysfs_common.h 2 | 3 | // Copyright (C) 2018-2021 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef QUERY_SYSENV_SYSFS_COMMON_H_ 7 | #define QUERY_SYSENV_SYSFS_COMMON_H_ 8 | 9 | #include 10 | #include 11 | 12 | ushort h2ushort(char * hval); 13 | 14 | unsigned h2uint(char * hval); 15 | 16 | #endif /* QUERY_SYSENV_SYSFS_COMMON_H_ */ 17 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_usb.h: -------------------------------------------------------------------------------- 1 | /** @file query_usb_sysenv.h 2 | * 3 | * Probe the USB environment 4 | */ 5 | 6 | // Copyright (C) 2014-2019 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef QUERY_USB_SYSENV_H_ 10 | #define QUERY_USB_SYSENV_H_ 11 | 12 | void query_usbenv(); 13 | 14 | #endif /* QUERY_USB_SYSENV_H_ */ 15 | -------------------------------------------------------------------------------- /src/app_sysenv/query_sysenv_xref.h: -------------------------------------------------------------------------------- 1 | /** @file query_sysenv.xref.h 2 | * 3 | * Table cross-referencing the multiple ways that a display is referenced 4 | * in various Linux subsystems. 5 | */ 6 | 7 | // Copyright (C) 2017-2022 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | 11 | #ifndef QUERY_SYSENV_XREF_H_ 12 | #define QUERY_SYSENV_XREF_H_ 13 | 14 | #include "util/edid.h" 15 | 16 | #define DEVICE_ID_XREF_MARKER "DXRF" 17 | /** Device identifier cross-reference entry */ 18 | typedef struct { 19 | char marker[4]; 20 | 21 | // Subsystem ids: 22 | // I2C scan by I2C bus number 23 | // DRM 24 | // SYSFS query /sys 25 | // X11 query X11 26 | // UDEV query udev 27 | 28 | 29 | Byte raw_edid[128]; // All DRM I2C SYSFS X11 30 | char * edid_tag; 31 | Parsed_Edid * parsed_edid; // All DRM I2C SUSFS 32 | int i2c_busno; // I2C 33 | char * xrandr_name; // X11 34 | char * udev_name; // UDEV 35 | char * udev_syspath; // UDEV 36 | int udev_busno; // UDEV 37 | char * drm_connector_name; // DRM 38 | int drm_connector_type; // DRM 39 | char * drm_device_path; // DRM 40 | char * sysfs_drm_name; // SYSFS 41 | char * sysfs_drm_i2c; // SYSFS // or save I2C bus number found? 42 | // #ifdef ALTERNATIVE 43 | int sysfs_drm_busno; 44 | // #endif 45 | bool ambiguous_edid; 46 | } Device_Id_Xref; 47 | 48 | void device_xref_init(); 49 | void device_xref_set_i2c_bus_scan_complete(); 50 | // bool device_xref_i2c_bus_scan_complete(); 51 | 52 | char * device_xref_edid_tag(const Byte * raw_edid); 53 | 54 | Device_Id_Xref * device_xref_find_by_edid(const Byte * raw_edid); 55 | Device_Id_Xref * device_xref_find_by_busno(int busno); 56 | Device_Id_Xref * device_xref_new_with_busno(int busno, Byte * raw_edid); 57 | void device_xref_report(int depth); 58 | 59 | #endif /* QUERY_SYSENV_XREF_H_ */ 60 | -------------------------------------------------------------------------------- /src/base/base.md: -------------------------------------------------------------------------------- 1 | /** \dir 2 | Base services and definitions for the **ddcutil** application. 3 | 4 | Subdirectory base depends only on: 5 | - File src/public/ddcutil_types.h, for publicly visible type definitions 6 | - Subdirectory src/util, for application agnostic services 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /src/base/base_services.c: -------------------------------------------------------------------------------- 1 | /** @file base_services.c 2 | * 3 | * Initialize and release base services. 4 | */ 5 | 6 | // Copyright (C) 2014-2025 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #include "config.h" 10 | 11 | #include "util/debug_util.h" 12 | #include "util/error_info.h" 13 | 14 | #include "core.h" 15 | #include "ddc_packets.h" 16 | #include "displays.h" 17 | #ifdef USE_LIBDRM 18 | #include "drm_connector_state.h" 19 | #endif 20 | #include "dynamic_features.h" 21 | #include "dsa2.h" 22 | #include "execution_stats.h" 23 | #include "flock.h" 24 | #include "feature_metadata.h" 25 | #include "i2c_bus_base.h" 26 | #include "linux_errno.h" 27 | #include "monitor_model_key.h" 28 | #include "per_display_data.h" 29 | #include "per_thread_data.h" 30 | #include "rtti.h" 31 | #include "sleep.h" 32 | #include "tuned_sleep.h" 33 | 34 | #include "base_services.h" 35 | 36 | /** Master initialization function for files in subdirectory base 37 | */ 38 | void init_base_services() { 39 | bool debug = false; 40 | DBGF(debug, "Starting."); 41 | 42 | errinfo_init(psc_name, psc_desc); 43 | init_core(); 44 | init_monitor_model_key(); 45 | init_base_dynamic_features(); 46 | init_ddc_packets(); 47 | init_dsa2(); 48 | init_execution_stats(); 49 | // init_linux_errno(); 50 | init_per_display_data(); 51 | init_per_thread_data(); 52 | init_sleep_stats(); 53 | init_status_code_mgt(); 54 | init_tuned_sleep(); 55 | init_displays(); 56 | init_i2c_bus_base(); 57 | init_feature_metadata(); 58 | #ifdef USE_LIBDRM 59 | init_drm_connector_state(); 60 | #endif 61 | init_flock(); 62 | 63 | DBGF(debug, "Done"); 64 | } 65 | 66 | 67 | /** Cleanup at termination helps to reveal where the real leaks are */ 68 | void terminate_base_services() { 69 | bool debug = false; 70 | DBGF(debug, "Starting"); 71 | 72 | terminate_per_thread_data(); 73 | terminate_per_display_data(); 74 | terminate_execution_stats(); 75 | terminate_dsa2(); 76 | terminate_displays(); 77 | terminate_rtti(); 78 | 79 | DBGF(debug, "Done"); 80 | } 81 | -------------------------------------------------------------------------------- /src/base/base_services.h: -------------------------------------------------------------------------------- 1 | /** \file base_services.h" 2 | * Initialize and release base services. 3 | */ 4 | 5 | // Copyright (C) 2014-2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef BASE_SERVICES_H_ 9 | #define BASE_SERVICES_H_ 10 | 11 | void init_base_services(); 12 | void terminate_base_services(); 13 | 14 | #endif /* BASE_SERVICES_H_ */ 15 | -------------------------------------------------------------------------------- /src/base/build_info.h: -------------------------------------------------------------------------------- 1 | /** \file build_info.h 2 | * 3 | * Build Information: version, compilation options, etc. 4 | */ 5 | 6 | // Copyright (C) 2014-2022 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef BUILD_INFO_H_ 10 | #define BUILD_INFO_H_ 11 | 12 | const char * get_base_ddcutil_version(); 13 | const char * get_ddcutil_version_suffix(); 14 | const char * get_full_ddcutil_version(); 15 | 16 | void report_build_options(int depth); 17 | 18 | #endif /* BUILD_INFO_H_ */ 19 | -------------------------------------------------------------------------------- /src/base/build_timestamp.c: -------------------------------------------------------------------------------- 1 | /** \file build_timestamp.c 2 | * 3 | * Timestamp generated at each build. 4 | */ 5 | 6 | // Copyright (C) 2024 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #include "config.h" 10 | 11 | #include "base/build_details.h" // created by Makefile 12 | #include "base/build_timestamp.h" 13 | 14 | #ifdef BUILD_TIMESTAMP 15 | const char * BUILD_DATE = __DATE__; 16 | const char * BUILD_TIME = __TIME__; 17 | #else 18 | const char * BUILD_DATE = "Not set"; 19 | const char * BUILD_TIME = "Not set"; 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /src/base/build_timestamp.h: -------------------------------------------------------------------------------- 1 | /** \file build_timestamp.h 2 | * 3 | * Timestamp generated at each build. 4 | */ 5 | 6 | // Copyright (C) 2024 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef BUILD_TIMESTAMP_H_ 10 | #define BUILD_TIMESTAMP_H_ 11 | 12 | extern const char * BUILD_DATE; 13 | extern const char * BUILD_TIME; 14 | 15 | #endif /* BUILD_TIMESTAMP_H_ */ 16 | -------------------------------------------------------------------------------- /src/base/ddc_command_codes.c: -------------------------------------------------------------------------------- 1 | /** \file ddc_command_codes.c 2 | * DDC/CI command codes 3 | */ 4 | 5 | // Copyright (C) 2014-2023 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #include "ddc_command_codes.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "util/string_util.h" 15 | 16 | // 17 | // DDC Command and Response Codes 18 | // 19 | 20 | typedef 21 | struct { 22 | Byte cmd_code; 23 | char * name; 24 | } Cmd_Code_Table_Entry; 25 | 26 | Cmd_Code_Table_Entry cmd_code_table[] = { 27 | {CMD_VCP_REQUEST , "VCP Request" }, 28 | {CMD_VCP_RESPONSE , "VCP Response" }, 29 | {CMD_VCP_SET , "VCP Set" }, 30 | {CMD_TIMING_REPLY , "Timing Reply "}, 31 | {CMD_TIMING_REQUEST , "Timing Request" }, 32 | {CMD_VCP_RESET , "VCP Reset" }, 33 | {CMD_SAVE_SETTINGS , "Save Settings" }, 34 | {CMD_SELF_TEST_REPLY , "Self Test Reply" }, 35 | {CMD_SELF_TEST_REQUEST , "Self Test Request" }, 36 | {CMD_ID_REPLY , "Identification Reply"}, 37 | {CMD_TABLE_READ_REQUST , "Table Read Request" }, 38 | {CMD_CAPABILITIES_REPLY , "Capabilities Reply" }, 39 | {CMD_TABLE_READ_REPLY , "Table Read Reply" }, 40 | {CMD_TABLE_WRITE , "Table Write" }, 41 | {CMD_ID_REQUEST , "Identification Request" }, 42 | {CMD_CAPABILITIES_REQUEST , "Capabilities Request" }, 43 | {CMD_ENABLE_APP_REPORT , "Enable Application Report" } 44 | }; 45 | static 46 | int ddc_cmd_code_count = sizeof(cmd_code_table)/sizeof(Cmd_Code_Table_Entry); 47 | 48 | 49 | static 50 | Cmd_Code_Table_Entry * get_ddc_cmd_struct_by_id(Byte cmd_id) { 51 | // DBGMSG("Starting. id=0x%02x ", id ); 52 | int ndx = 0; 53 | Cmd_Code_Table_Entry * result = NULL; 54 | for (;ndx < ddc_cmd_code_count; ndx++) { 55 | if (cmd_id == cmd_code_table[ndx].cmd_code) { 56 | result = &cmd_code_table[ndx]; 57 | break; 58 | } 59 | } 60 | // DBGMSG("Done. ndx=%d. returning %p", ndx, result); 61 | return result; 62 | } 63 | 64 | 65 | char * ddc_cmd_code_name(Byte command_id) { 66 | char * result = NULL; 67 | Cmd_Code_Table_Entry * cmd_entry = get_ddc_cmd_struct_by_id(command_id); 68 | if (cmd_entry) 69 | result = cmd_entry->name; 70 | else 71 | result ="Unrecognized operation code"; 72 | return result; 73 | } 74 | -------------------------------------------------------------------------------- /src/base/ddc_command_codes.h: -------------------------------------------------------------------------------- 1 | /** \file ddc_command_codes.h 2 | * DDC/CI command codes 3 | */ 4 | 5 | // Copyright (C) 2014-2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef DDC_COMMAND_CODES_H_ 9 | #define DDC_COMMAND_CODES_H_ 10 | 11 | #include "util/coredefs.h" 12 | 13 | // 14 | // DDC/CI Command and Response Codes 15 | // 16 | 17 | // Used in 3 ways: 18 | // - to identify commands within ddcutil 19 | // - as identifiers in command request and response packets 20 | // - in capabilities string 21 | 22 | #define CMD_VCP_REQUEST 0x01 23 | #define CMD_VCP_RESPONSE 0x02 24 | #define CMD_VCP_SET 0x03 25 | #define CMD_TIMING_REPLY 0x06 26 | #define CMD_TIMING_REQUEST 0x07 27 | #define CMD_VCP_RESET 0x09 28 | #define CMD_SAVE_SETTINGS 0x0c 29 | #define CMD_SELF_TEST_REPLY 0xa1 30 | #define CMD_SELF_TEST_REQUEST 0xb1 31 | #define CMD_ID_REPLY 0xe1 32 | #define CMD_TABLE_READ_REQUST 0xe2 33 | #define CMD_CAPABILITIES_REPLY 0xe3 34 | #define CMD_TABLE_READ_REPLY 0xe4 35 | #define CMD_TABLE_WRITE 0xe7 36 | #define CMD_ID_REQUEST 0xf1 37 | #define CMD_CAPABILITIES_REQUEST 0xf3 38 | #define CMD_ENABLE_APP_REPORT 0xf5 39 | 40 | char * ddc_cmd_code_name(Byte command_id); 41 | 42 | #endif /* DDC_COMMAND_CODES_H_ */ 43 | -------------------------------------------------------------------------------- /src/base/ddc_errno.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * Error codes internal to **ddcutil**. 3 | */ 4 | 5 | // Copyright (C) 2014-2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef DDC_ERRNO_H_ 9 | #define DDC_ERRNO_H_ 10 | 11 | #include "public/ddcutil_status_codes.h" 12 | 13 | #include "base/status_code_mgt.h" 14 | 15 | 16 | Status_Code_Info * ddcrc_find_status_code_info(int rc); 17 | 18 | bool ddc_error_name_to_number(const char * errno_name, Status_DDC * errnum_loc); 19 | 20 | // Returns status code description: 21 | char * ddcrc_desc_t(int rc); 22 | 23 | bool ddcrc_is_derived_status_code(Public_Status_Code gsc); 24 | 25 | bool ddcrc_is_not_error(Public_Status_Code gsc); 26 | 27 | #endif /* DDC_ERRNO_H_ */ 28 | -------------------------------------------------------------------------------- /src/base/display_lock.h: -------------------------------------------------------------------------------- 1 | /* @file display_lock.h 2 | */ 3 | 4 | // Copyright (C) 2018-2025 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef DISPLAY_LOCK_H_ 8 | #define DISPLAY_LOCK_H_ 9 | 10 | #include 11 | #include 12 | 13 | #include "ddcutil_types.h" 14 | 15 | #include "util/error_info.h" 16 | #include "base/core.h" 17 | 18 | 19 | typedef enum { 20 | DDISP_NONE = 0x00, ///< No flags set 21 | DDISP_WAIT = 0x01 ///< If set, #lock_display() should wait 22 | } Display_Lock_Flags; 23 | 24 | #define DISPLAY_LOCK_MARKER "DDSC" 25 | typedef struct { 26 | char marker[4]; 27 | DDCA_IO_Path io_path; 28 | GMutex display_mutex; 29 | GThread * display_mutex_thread; // thread owning mutex 30 | intmax_t linux_thread_id; 31 | } Display_Lock_Record; 32 | 33 | 34 | Display_Lock_Record * create_display_lock_record(DDCA_IO_Path io_path); 35 | void terminate_i2c_display_lock(); 36 | Error_Info * lock_display(Display_Lock_Record * id, Display_Lock_Flags flags); 37 | Error_Info * lock_display_by_dpath(DDCA_IO_Path dpath, Display_Lock_Flags flags); 38 | Error_Info * unlock_display(Display_Lock_Record * id); 39 | #ifdef UNUSED 40 | Error_Info * lock_display2(Display_Lock_Record * dlr, Display_Lock_Flags flags); 41 | Error_Info * unlock_display2(Display_Lock_Record * dlr); 42 | #endif 43 | Error_Info * unlock_display_by_dpath(DDCA_IO_Path dpath); 44 | void dbgrpt_display_locks(int depth); 45 | char * interpret_display_lock_flags_t(Display_Lock_Flags lock_flags); 46 | int unlock_all_displays_for_current_thread(); 47 | void init_i2c_display_lock(void); 48 | 49 | #endif /* DISPLAY_LOCK_H_ */ 50 | -------------------------------------------------------------------------------- /src/base/display_retry_data.h: -------------------------------------------------------------------------------- 1 | /** @file display_retry_data.h 2 | * 3 | * Maintain retry counts on a per-display basis. 4 | */ 5 | 6 | // Copyright (C) 2020-2023 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef DISPLAY_RETRY_DATA_H_ 10 | #define DISPLAY_RETRY_DATA_H_ 11 | 12 | #include "public/ddcutil_types.h" 13 | 14 | #include "base/per_display_data.h" 15 | 16 | 17 | // Maintain max_tries 18 | void drd_set_default_max_tries( 19 | Retry_Operation type_id, 20 | uint16_t new_maxtries); 21 | 22 | // Try Stats 23 | 24 | void drd_record_display_tries( 25 | Per_Display_Data * pdd, 26 | Retry_Operation type_id, 27 | int rc, 28 | int tryct); 29 | 30 | void report_display_try_typed_data_by_data( 31 | Retry_Operation try_type_id, 32 | bool for_all_displays_total, 33 | Per_Display_Data * data, 34 | int depth); 35 | 36 | void report_display_all_types_data_by_data( 37 | bool for_all_displays, // controls message 38 | Per_Display_Data * data, 39 | int depth); 40 | 41 | void drd_report_all_display_retry_data(int depth); 42 | 43 | #endif /* DISPLAY_RETRY_DATA_H_ */ 44 | -------------------------------------------------------------------------------- /src/base/drm_connector_state.h: -------------------------------------------------------------------------------- 1 | /** @file drm_connector_state.h */ 2 | 3 | // Copyright (C) 2020-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DRM_CONNECTOR_STATE_H_ 7 | #define DRM_CONNECTOR_STATE_H_ 8 | 9 | /** \cond */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include "util/drm_card_connector_util.h" 18 | #include "util/edid.h" 19 | /** \endcond */ 20 | 21 | typedef struct { 22 | int cardno; 23 | int connector_id; 24 | uint32_t connector_type; 25 | uint32_t connector_type_id; 26 | drmModeConnection connection; 27 | Parsed_Edid * edid; 28 | uint64_t link_status; 29 | uint64_t dpms; 30 | uint64_t subconnector; 31 | } Drm_Connector_State; 32 | 33 | void redetect_drm_connector_states(); 34 | void report_drm_connector_states(int depth); 35 | void report_drm_connector_states_basic(bool refresh, int depth); 36 | Drm_Connector_State * find_drm_connector_state(Drm_Connector_Identifier cid); 37 | void init_drm_connector_state(); 38 | 39 | #endif /* DRM_CONNECTOR_STATE_H_ */ 40 | -------------------------------------------------------------------------------- /src/base/dsa2.h: -------------------------------------------------------------------------------- 1 | /** @file dsa2.h Dynamic sleep algorithm 2 2 | */ 3 | 4 | // Copyright (C) 2023 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef DSA2_H_ 8 | #define DSA2_H_ 9 | 10 | #include 11 | 12 | #include "public/ddcutil_types.h" 13 | 14 | #include "util/error_info.h" 15 | #include "base/core.h" 16 | #include "base/status_code_mgt.h" 17 | 18 | extern int dsa2_step_floor; 19 | 20 | void dsa2_enable(bool yesno); 21 | bool dsa2_is_enabled(); 22 | 23 | bool dsa2_set_greatest_tries_upper_bound(int tries); 24 | bool dsa2_set_average_tries_upper_bound(DDCA_Sleep_Multiplier avg_tries); 25 | 26 | int dsa2_multiplier_to_step(DDCA_Sleep_Multiplier multiplier); 27 | DDCA_Sleep_Multiplier 28 | dsa2_step_to_multiplier(int step); 29 | DDCA_Sleep_Multiplier 30 | dsa2_get_minimum_multiplier(); 31 | struct Results_Table * 32 | dsa2_get_results_table_by_busno(int busno, bool create_if_not_found); 33 | bool dsa2_is_from_cache(struct Results_Table * dpath); 34 | void dsa2_reset_multiplier(DDCA_Sleep_Multiplier multiplier); 35 | void dsa2_reset_results_table(int busno, DDCA_Sleep_Multiplier sleep_multiplier); 36 | DDCA_Sleep_Multiplier 37 | dsa2_get_adjusted_sleep_mult(struct Results_Table * rtable); 38 | void dsa2_note_retryable_failure( 39 | struct Results_Table * rtable, 40 | DDCA_Status ddcrc, 41 | int remaining_tries); 42 | void dsa2_record_final( 43 | struct Results_Table * rtable, 44 | DDCA_Status ddcrc, 45 | int retries, 46 | bool null_adjustment_occurred); 47 | char * dsa2_stats_cache_file_name(); 48 | Status_Errno dsa2_save_persistent_stats(); 49 | Status_Errno dsa2_erase_persistent_stats(); 50 | Error_Info * dsa2_restore_persistent_stats(); 51 | void dsa2_report_internal(struct Results_Table * rtable, int depth); 52 | void dsa2_report_internal_all(int depth); 53 | 54 | void init_dsa2(); 55 | void terminate_dsa2(); // release all resources 56 | 57 | #endif /* DSA2_H_ */ 58 | -------------------------------------------------------------------------------- /src/base/feature_lists.h: -------------------------------------------------------------------------------- 1 | /** @file feature_lists.h 2 | */ 3 | 4 | // Copyright (C) 2018=2020 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | 8 | #ifndef FEATURE_LISTS_H_ 9 | #define FEATURE_LISTS_H_ 10 | 11 | #include 12 | 13 | #include "ddcutil_types.h" 14 | 15 | void 16 | feature_list_clear( 17 | DDCA_Feature_List* vcplist); 18 | 19 | void 20 | feature_list_add( 21 | DDCA_Feature_List* vcplist, 22 | uint8_t vcp_code); 23 | 24 | bool 25 | feature_list_contains( 26 | DDCA_Feature_List* vcplist, 27 | uint8_t vcp_code); 28 | 29 | DDCA_Feature_List 30 | feature_list_or( 31 | DDCA_Feature_List* vcplist1, 32 | DDCA_Feature_List* vcplist2); 33 | 34 | DDCA_Feature_List 35 | feature_list_and( 36 | DDCA_Feature_List* vcplist1, 37 | DDCA_Feature_List* vcplist2); 38 | 39 | DDCA_Feature_List 40 | feature_list_and_not( 41 | DDCA_Feature_List* vcplist1, 42 | DDCA_Feature_List* vcplist2); 43 | 44 | int 45 | feature_list_count( 46 | DDCA_Feature_List* feature_list); 47 | 48 | const char * 49 | feature_list_string( 50 | DDCA_Feature_List* feature_list, 51 | const char * value_prefix, 52 | const char * sepstr); 53 | 54 | 55 | #endif /* FEATURE_LISTS_H_ */ 56 | -------------------------------------------------------------------------------- /src/base/flock.h: -------------------------------------------------------------------------------- 1 | /** @file flock.h */ 2 | 3 | // Copyright (C) 2018-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef FLOCK_H_ 7 | #define FLOCK_H_ 8 | 9 | #include 10 | 11 | #include "public/ddcutil_status_codes.h" 12 | 13 | extern int flock_poll_millisec; 14 | extern int flock_max_wait_millisec; 15 | extern bool debug_flock; 16 | 17 | void i2c_enable_cross_instance_locks(bool yesno); 18 | Status_Errno flock_lock_by_fd(int fd, const char * filename, bool wait); 19 | Status_Errno flock_unlock_by_fd(int fd); 20 | void init_flock(); 21 | #endif /* FLOCK_H_ */ 22 | -------------------------------------------------------------------------------- /src/base/linux_errno.h: -------------------------------------------------------------------------------- 1 | /** \file linux_errno.h 2 | * Linux errno descriptions 3 | */ 4 | 5 | // Copyright (C) 2014-2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef BASE_LINUX_ERRNO_H_ 9 | #define BASE_LINUX_ERRNO_H_ 10 | 11 | #include "base/status_code_mgt.h" 12 | 13 | void init_linux_errno(); 14 | 15 | // Interpret system error number 16 | // not thread safe, always points to same internal buffer, contents overwritten on each call 17 | char * linux_errno_name(int error_number); 18 | char * linux_errno_desc(int error_number); 19 | 20 | Status_Code_Info * get_errno_info(int errnum); 21 | Status_Code_Info * get_negative_errno_info(int errnum); 22 | 23 | bool errno_name_to_number(const char * errno_name, int * perrno); 24 | bool errno_name_to_modulated_number(const char * errno_name, Public_Status_Code * p_error_number); 25 | 26 | #endif /* BASE_LINUX_ERRNO_H_ */ 27 | -------------------------------------------------------------------------------- /src/base/monitor_model_key.h: -------------------------------------------------------------------------------- 1 | /** @file monitor_model_key.h 2 | * Uniquely identifies a monitor model using its manufacturer id, 3 | * model name, and product code, as listed in the EDID. 4 | */ 5 | 6 | // Copyright (C) 2018-2024 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef MONITOR_MODEL_KEY_H_ 10 | #define MONITOR_MODEL_KEY_H_ 11 | 12 | #include 13 | 14 | #include "public/ddcutil_types.h" 15 | 16 | #include "util/edid.h" 17 | 18 | #define FIXUP_MODEL_NAME(_name) \ 19 | for (int i=0; _name[i] && i < EDID_MODEL_NAME_FIELD_SIZE; i++) { \ 20 | if (!isalnum(_name[i])) \ 21 | _name[i] = '_'; \ 22 | } 23 | 24 | 25 | /** Identifies a monitor model */ 26 | typedef struct { 27 | char mfg_id[DDCA_EDID_MFG_ID_FIELD_SIZE]; 28 | char model_name[DDCA_EDID_MODEL_NAME_FIELD_SIZE]; 29 | uint16_t product_code; 30 | bool defined; 31 | } Monitor_Model_Key; 32 | 33 | 34 | Monitor_Model_Key 35 | mmk_value( 36 | const char * mfg_id, 37 | const char * model_name, 38 | uint16_t product_code); 39 | 40 | Monitor_Model_Key 41 | mmk_undefined_value(); 42 | 43 | Monitor_Model_Key 44 | mmk_value_from_edid(Parsed_Edid * edid); 45 | 46 | Monitor_Model_Key * 47 | mmk_new( 48 | const char * mfg_id, 49 | const char * model_name, 50 | uint16_t product_code); 51 | 52 | Monitor_Model_Key * 53 | mmk_new_from_edid( 54 | Parsed_Edid * edid); 55 | 56 | Monitor_Model_Key 57 | mmk_value_from_string(const char * sval); 58 | 59 | Monitor_Model_Key * 60 | mmk_new_from_value(Monitor_Model_Key mmk); 61 | 62 | Monitor_Model_Key * 63 | mmk_new_from_string(const char * s); 64 | 65 | #ifdef UNUSED 66 | Monitor_Model_Key * 67 | monitor_model_key_undefined_new(); 68 | #endif 69 | 70 | void 71 | mmk_free( 72 | Monitor_Model_Key * model_id); 73 | 74 | char * 75 | mmk_model_id_string( 76 | const char * mfg, 77 | const char * model_name, 78 | uint16_t product_code); 79 | 80 | bool 81 | monitor_model_key_eq( 82 | Monitor_Model_Key mmk1, 83 | Monitor_Model_Key mmk2); 84 | 85 | #ifdef UNUSED 86 | bool monitor_model_key_is_defined(Monitor_Model_Key mmk); 87 | #endif 88 | 89 | char * 90 | mmk_string( 91 | Monitor_Model_Key * model_id); 92 | 93 | char * 94 | mmk_repr(Monitor_Model_Key mmk); 95 | 96 | void 97 | init_monitor_model_key(); 98 | 99 | #endif /* MONITOR_MODEL_KEY_H_ */ 100 | -------------------------------------------------------------------------------- /src/base/monitor_quirks.c: -------------------------------------------------------------------------------- 1 | /** @file monitor_quirks.c */ 2 | 3 | // Copyright (C) 2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include "util/coredefs_base.h" 7 | 8 | #include "base/core.h" 9 | #include "base/monitor_model_key.h" 10 | 11 | #include "base/monitor_quirks.h" 12 | 13 | typedef struct { 14 | Monitor_Model_Key mmk; 15 | Monitor_Quirk_Data data; 16 | } Monitor_Quirk_Table_Entry; 17 | 18 | static Monitor_Quirk_Table_Entry quirk_table[] = { 19 | {{ "XMI", "Mi Monitor", 13380, true}, { MQ_NO_SETTING, NULL}}, 20 | // {{ "DEL", "DELL U3011", 16485, true}, { MQ_NO_MFG_RANGE, "msg 1"}}, // for testing 21 | // {{ "NEC", "P241W", 26715, true}, { MQ_NO_SETTING, "msg 2"}}, // for testing 22 | }; 23 | int quirk_table_size = ARRAY_SIZE(quirk_table); 24 | 25 | 26 | Monitor_Quirk_Data * 27 | get_monitor_quirks(Monitor_Model_Key * mmk) { 28 | bool debug = false; 29 | DBGMSF(debug, "quirk_table_size=%d, mmk=%s", quirk_table_size, mmk_repr(*mmk)); 30 | Monitor_Quirk_Data * result = NULL; 31 | 32 | for (int ndx = 0; ndx < quirk_table_size; ndx++) { 33 | DBGMSF(debug, "ndx=%d, mmk=%s", ndx, mmk_repr(quirk_table[ndx].mmk)); 34 | if (monitor_model_key_eq(*mmk, quirk_table[ndx].mmk)) { 35 | result = &quirk_table[ndx].data; 36 | break; 37 | } 38 | } 39 | return result; 40 | } 41 | -------------------------------------------------------------------------------- /src/base/monitor_quirks.h: -------------------------------------------------------------------------------- 1 | /** @file monitor_quirks.h */ 2 | 3 | // Copyright (C) 2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef MONITOR_QUIRKS_H_ 7 | #define MONITOR_QUIRKS_H_ 8 | 9 | #include "base/monitor_model_key.h" 10 | 11 | typedef enum { 12 | MQ_NONE = 0, 13 | MQ_NO_SETTING = 1, 14 | MQ_NO_MFG_RANGE = 2, 15 | MQ_OTHER = 4, 16 | } Monitor_Quirk_Type; 17 | 18 | typedef struct { 19 | Monitor_Quirk_Type quirk_type; 20 | char * quirk_msg; 21 | } Monitor_Quirk_Data; 22 | 23 | Monitor_Quirk_Data * 24 | get_monitor_quirks(Monitor_Model_Key * mmk); 25 | 26 | #endif /* MONITOR_QUIRKS_H_ */ 27 | -------------------------------------------------------------------------------- /src/base/rtti.h: -------------------------------------------------------------------------------- 1 | /* @file rtti.h 2 | * Runtime trace information 3 | */ 4 | 5 | // Copyright (C) 2018-2023 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef RTTI_H_ 9 | #define RTTI_H_ 10 | 11 | #include 12 | 13 | #define RTTI_ADD_FUNC(_NAME) rtti_func_name_table_add(_NAME, #_NAME); 14 | 15 | void rtti_func_name_table_add(void * func_addr, const char * func_name); 16 | char * rtti_get_func_name_by_addr(void * ptr); 17 | void * rtti_get_func_addr_by_name(const char * name); 18 | void dbgrpt_rtti_func_name_table(int depth, bool show_internal); 19 | void report_rtti_func_name_table(int depth, char * msg); 20 | void terminate_rtti(); 21 | 22 | #endif /* RTTI_H_ */ 23 | -------------------------------------------------------------------------------- /src/base/stats.c: -------------------------------------------------------------------------------- 1 | // stats.c 2 | 3 | // Copyright (C) 2018-2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include "stats.h" 7 | 8 | #ifndef STATS_H 9 | #define STATS_H 10 | 11 | 12 | static char * retry_type_descriptions[] = { 13 | "write only", 14 | "write-read", 15 | "multi-part read", 16 | "multi-part write" 17 | }; 18 | 19 | static char * retry_type_names[] = { 20 | "WRITE_ONLY_TRIES_OP", 21 | "WRITE_READ_TRIES_OP", 22 | "MULTI_PART_READ_OP", 23 | "MULTI_PART_WRITE_OP" 24 | }; 25 | 26 | const char * retry_type_name(Retry_Operation type_id) { 27 | return retry_type_names[type_id]; 28 | } 29 | 30 | const char * retry_type_description(Retry_Operation type_id) { 31 | return retry_type_descriptions[type_id]; 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/base/stats.h: -------------------------------------------------------------------------------- 1 | /** @file stats.h 2 | */ 3 | 4 | // Copyright (C) 2023 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | 8 | #ifndef STATS_H_ 9 | #define STATS_H_ 10 | 11 | #include 12 | 13 | // 14 | // Retry management 15 | // 16 | 17 | //! I2C retry types 18 | typedef enum{ 19 | WRITE_ONLY_TRIES_OP, /**< write-only operation tries */ 20 | WRITE_READ_TRIES_OP, /**< read-write operation tries */ 21 | MULTI_PART_READ_OP, /**< multi-part read operation tries */ 22 | MULTI_PART_WRITE_OP /**< multi-part write operation tries */ 23 | } Retry_Operation; 24 | #define RETRY_OP_COUNT 4 25 | typedef uint16_t Retry_Op_Value; 26 | 27 | const char * retry_type_name(Retry_Operation stat_id); 28 | const char * retry_type_description(Retry_Operation retry_class); 29 | 30 | typedef struct { 31 | Retry_Operation retry_type; 32 | uint16_t max_highest_maxtries; 33 | uint16_t min_lowest_maxtries; 34 | } Global_Maxtries_Accumulator; 35 | 36 | #endif /* STATS_H_ */ 37 | -------------------------------------------------------------------------------- /src/base/trace_control.h: -------------------------------------------------------------------------------- 1 | /** @file trace_control.h 2 | * 3 | * Manage whether tracing is performed 4 | */ 5 | 6 | // Copyright (C) 2023-2024 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef TRACE_CONTROL_H_ 10 | #define TRACE_CONTROL_H_ 11 | 12 | #include 13 | 14 | #include "config.h" 15 | 16 | #include "public/ddcutil_types.h" 17 | 18 | #include "base/ddcutil_types_internal.h" 19 | 20 | extern DDCA_Trace_Group trace_levels; 21 | 22 | bool add_traced_function(const char * funcname); 23 | bool is_traced_function( const char * funcname); 24 | void dbgrpt_traced_function_table(int depth); 25 | 26 | bool add_traced_api_call(const char * funcname); 27 | bool is_traced_api_call( const char * funcname); 28 | 29 | bool add_traced_callstack_call(const char * funcname); 30 | bool is_traced_callstack_call( const char * funcname); 31 | void dbgrpt_traced_callstack_call_table(int depth); 32 | 33 | void add_traced_file(const char * filename); 34 | bool is_traced_file( const char * filename); 35 | 36 | DDCA_Trace_Group trace_class_name_to_value(const char * name); 37 | void set_trace_groups(DDCA_Trace_Group trace_flags); 38 | void add_trace_groups(DDCA_Trace_Group trace_flags); 39 | // char * get_active_trace_group_names(); // unimplemented 40 | 41 | void report_tracing(int depth); 42 | 43 | /** Checks if tracing is currently active for the globally defined TRACE_GROUP value, 44 | * current file and function. 45 | * 46 | * Wrappers call to **is_tracing()**, using the current **TRACE_GROUP** value, 47 | * filename, and function as implicit arguments. 48 | */ 49 | #define IS_TRACING() is_tracing(TRACE_GROUP, __FILE__, __func__) 50 | 51 | #define IS_TRACING_GROUP(grp) is_tracing((grp), __FILE__, __func__) 52 | 53 | #define IS_TRACING_BY_FUNC_OR_FILE() is_tracing(DDCA_TRC_NONE, __FILE__, __func__) 54 | 55 | #define IS_DBGTRC(debug_flag, group) \ 56 | ( (debug_flag) || is_tracing((group), __FILE__, __func__) ) 57 | 58 | #endif /* TRACE_CONTROL_H_ */ 59 | -------------------------------------------------------------------------------- /src/base/tuned_sleep.h: -------------------------------------------------------------------------------- 1 | /** @file tuned_sleep.h 2 | * 3 | * Perform sleep. The sleep time is determined by io mode, sleep event time, 4 | * and applicable multipliers. 5 | */ 6 | 7 | // Copyright (C) 2019-2022 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | #ifndef TUNED_SLEEP_H_ 11 | #define TUNED_SLEEP_H_ 12 | 13 | /** \cond */ 14 | #include 15 | // #include "public/ddcutil_types.h" 16 | /** \endcond */ 17 | #include "base/displays.h" 18 | #include "base/execution_stats.h" // for Sleep_Event_Type 19 | 20 | extern bool suppress_se_post_read; 21 | extern bool null_msg_adjustment_enabled; 22 | 23 | bool enable_deferred_sleep(bool enable); 24 | bool is_deferred_sleep_enabled(); 25 | 26 | void check_deferred_sleep( 27 | Display_Handle * dh, 28 | const char * func, 29 | int lineno, 30 | const char * filename); 31 | 32 | void tuned_sleep_with_trace( 33 | Display_Handle * dh, 34 | Sleep_Event_Type event_type, 35 | int special_sleep_time_millis, 36 | const char * func, 37 | int lineno, 38 | const char * filename, 39 | const char * msg); 40 | 41 | // Convenience macros: 42 | 43 | #define CHECK_DEFERRED_SLEEP(_dh) \ 44 | check_deferred_sleep(_dh, __func__, __LINE__, __FILE__) 45 | 46 | #define TUNED_SLEEP_WITH_TRACE(_dh, _event_type, _msg) \ 47 | tuned_sleep_with_trace(_dh, _event_type, 0, __func__, __LINE__, __FILE__, _msg) 48 | 49 | #define SPECIAL_TUNED_SLEEP_WITH_TRACE(_dh, _time_millis, _msg) \ 50 | tuned_sleep_with_trace(_dh, SE_SPECIAL, _time_millis, __func__, __LINE__, __FILE__, _msg) 51 | 52 | void init_tuned_sleep(); 53 | 54 | #endif /* TUNED_SLEEP_H_ */ 55 | -------------------------------------------------------------------------------- /src/bsd/linux_types.h: -------------------------------------------------------------------------------- 1 | /** \f linux_types.h 2 | * 3 | * Integer type definitions needed by private copies of 4 | * i2c.h, i2c-dev.h. Used if TARGET_BSD 5 | */ 6 | 7 | // Copyright (C) 2020 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | #ifndef LINUX_TYPES_H_ 11 | #define LINUX_TYPES_H_ 12 | 13 | #include 14 | 15 | #include // n.b. BSD version 16 | 17 | typedef uint8_t __u8; 18 | typedef uint16_t __u16; 19 | typedef uint32_t __u32; 20 | 21 | #endif /* LINUX_TYPES_H_ */ 22 | -------------------------------------------------------------------------------- /src/cmdline/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | -I$(top_srcdir)/src \ 4 | -I$(top_srcdir)/src/public 5 | 6 | AM_CFLAGS = $(AM_CFLAGS_STD) 7 | 8 | CLEANFILES = \ 9 | *expand 10 | 11 | # Intermediate Library 12 | noinst_LTLIBRARIES = libcmdline.la 13 | 14 | libcmdline_la_SOURCES = \ 15 | cmd_parser_aux.c \ 16 | cmd_parser_goption.c \ 17 | parsed_cmd.c 18 | -------------------------------------------------------------------------------- /src/cmdline/cmd_parser.h: -------------------------------------------------------------------------------- 1 | /** @file cmd_parser.h 2 | */ 3 | 4 | // Copyright (C) 2014-2023 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | // 8 | // This simple interface facilitated switching command parsers during 9 | // development. Candidate for removal. 10 | // 11 | 12 | #ifndef CMD_PARSER_H_ 13 | #define CMD_PARSER_H_ 14 | 15 | #include 16 | 17 | #include "public/ddcutil_types.h" 18 | 19 | #include "cmdline/parsed_cmd.h" 20 | 21 | bool parse_syslog_level( 22 | const char * sval, 23 | DDCA_Syslog_Level * result_loc, 24 | GPtrArray * errmsgs); 25 | 26 | Parsed_Cmd * parse_command( 27 | int argc, 28 | char * argv[], 29 | Parser_Mode parser_mode, 30 | GPtrArray * errmsgs); 31 | 32 | #endif /* CMD_PARSER_H_ */ 33 | -------------------------------------------------------------------------------- /src/cmdline/cmd_parser_aux.h: -------------------------------------------------------------------------------- 1 | /** \file cmd_parser_aux.c 2 | * 3 | * Functions and strings that are independent of the parser package used. 4 | */ 5 | 6 | // Copyright (C) 20014-2023 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | 10 | #ifndef CMD_PARSER_AUX_H_ 11 | #define CMD_PARSER_AUX_H_ 12 | 13 | #include 14 | 15 | #include "cmdline/parsed_cmd.h" 16 | 17 | void init_cmd_parser_base(); 18 | 19 | typedef enum { 20 | Option_None = 0, 21 | Option_Explicit_Display = 1 22 | } Cmd_Supported_Options; 23 | 24 | 25 | typedef 26 | struct { 27 | int cmd_id; 28 | const char * cmd_name; 29 | int minchars; 30 | int min_arg_ct; 31 | int max_arg_ct; 32 | Cmd_Supported_Options 33 | supported_options; 34 | } Cmd_Desc; 35 | 36 | Cmd_Desc * find_command(char * cmd); 37 | Cmd_Desc * get_command(int cmdid); 38 | void show_cmd_desc(Cmd_Desc * cmd_desc); // debugging function 39 | 40 | bool all_digits(char * val, int ct); 41 | bool parse_dot_separated_arg( const char * val, int * pv1, int * pv2); 42 | bool parse_colon_separated_arg(const char * val, int * pv1, int * pv2); 43 | bool parse_colon_separated_vid_pid(const char * val, uint16_t * pv1, uint16_t * pv2); 44 | bool parse_int_arg(char * val, int * pIval); 45 | 46 | bool parse_feature_id_or_subset(char * val, int cmd_id, Feature_Set_Ref * fsref); 47 | bool parse_feature_ids(char ** vals, int vals_ct, int cmd_id, Feature_Set_Ref * fsref); 48 | Feature_Set_Ref * parse_feature_ids_or_subset(int cmd_id, char **vals, int vals_ct); 49 | 50 | bool validate_output_level(Parsed_Cmd* parsed_cmd); 51 | 52 | char * assemble_command_argument_help(); 53 | 54 | extern char * commands_list_help; 55 | extern char * command_argument_help; 56 | extern char * monitor_selection_option_help; 57 | extern char * tracing_comma_separated_option_help; 58 | extern char * tracing_multiple_call_option_help; 59 | extern char * trcfunc_multiple_call_option_help; 60 | extern char * trcfile_multiple_call_option_help; 61 | extern char * stats_multiple_call_option_help; 62 | extern char * maxtries_option_help; 63 | 64 | #endif /* CMD_PARSER_AUX_H_ */ 65 | -------------------------------------------------------------------------------- /src/ddc/Makefile.am: -------------------------------------------------------------------------------- 1 | # src/ddc/Makefile.am 2 | 3 | AM_CPPFLAGS = \ 4 | $(LIBDRM_CFLAGS) \ 5 | $(GLIB_CFLAGS) \ 6 | $(JANSSON_CFLAGS) \ 7 | -I$(top_srcdir)/src \ 8 | -I$(top_srcdir)/src/public 9 | 10 | AM_CFLAGS = $(AM_CFLAGS_STD) 11 | 12 | 13 | CLEANFILES = \ 14 | *expand 15 | 16 | # Intermediate Library 17 | noinst_LTLIBRARIES = libddc.la 18 | 19 | libddc_la_SOURCES = \ 20 | ddc_common_init.c \ 21 | ddc_displays.c \ 22 | ddc_display_ref_reports.c \ 23 | ddc_display_selection.c \ 24 | ddc_dumpload.c \ 25 | ddc_initial_checks.c \ 26 | ddc_multi_part_io.c \ 27 | ddc_output.c \ 28 | ddc_packet_io.c \ 29 | ddc_phantom_displays.c \ 30 | ddc_read_capabilities.c \ 31 | ddc_save_current_settings.c \ 32 | ddc_serialize.c \ 33 | ddc_services.c \ 34 | ddc_strategy.c \ 35 | ddc_vcp.c \ 36 | ddc_vcp_version.c \ 37 | ddc_try_data.c 38 | 39 | # Rename to "all=local" for development 40 | all-local-disabled: 41 | @echo "" 42 | @echo "(src/Makefile:all-local) Variable values:" 43 | @echo " CLEANFILES: $(CLEANFILES)" 44 | @echo " CFLAGS: $(CFLAGS)" 45 | @echo " AM_CFLAGS: $(AM_CFLAGS)" 46 | @echo " CPPFLAGS: $(CPPFLAGS)" 47 | @echo " AM_CPPFLAGS: $(AM_CPPFLAGS)" 48 | @echo " ddcutil_FLAGS: $(ddcutil_CFLAGS)" 49 | @echo " AUTOMAKE_OPTIONS: $(AUTOMAKE_OPTIONS)" 50 | @echo " MAKELEVEL: $(MAKELEVEL)" 51 | @echo " MAKEFLAGS: $(MAKEFLAGS)" 52 | @echo " V: $(V)" 53 | @echo " AM_CFLAGS_STD: $(AM_CFLAGS_STD)" 54 | @echo "" 55 | -------------------------------------------------------------------------------- /src/ddc/ddc_common_init.h: -------------------------------------------------------------------------------- 1 | /** @file common_init.h 2 | * Initialization that must be performed very early by both ddcutil and libddcutil 3 | */ 4 | 5 | // Copyright (C) 2021-2024 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef DDC_COMMON_INIT_H_ 9 | #define DDC_COMMON_INIT_H_ 10 | 11 | #include 12 | 13 | #include "util/error_info.h" 14 | #include "cmdline/parsed_cmd.h" 15 | 16 | void i2c_discard_caches(Cache_Types caches); 17 | Error_Info * init_tracing(Parsed_Cmd * parsed_cmd); 18 | Error_Info * submaster_initializer(Parsed_Cmd * parsed_cmd); 19 | void init_ddc_common_init(); 20 | 21 | #endif /* DDC_COMMON_INIT_H_ */ 22 | -------------------------------------------------------------------------------- /src/ddc/ddc_display_ref_reports.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_display_ref_reports.h */ 2 | 3 | // Copyright (C) 2014-2022 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DDC_DISPLAY_REF_REPORTS_H_ 7 | #define DDC_DISPLAY_REF_REPORTS_H_ 8 | 9 | #include 10 | #include 11 | 12 | #include "base/displays.h" 13 | 14 | // Display_Ref Reports 15 | void ddc_report_display_by_dref(Display_Ref * dref, int depth); 16 | int ddc_report_displays(bool include_invalid_displays, int depth); 17 | void ddc_dbgrpt_display_ref(Display_Ref * drec, int depth); 18 | void ddc_dbgrpt_drefs(char * msg, GPtrArray* ptrarray, int depth); 19 | 20 | // Initialization 21 | void init_ddc_display_ref_reports(); 22 | 23 | #endif /* DDC_DISPLAY_REF_REPORTS_H_ */ 24 | -------------------------------------------------------------------------------- /src/ddc/ddc_display_selection.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_display_selection.h */ 2 | 3 | // Copyright (C) 2022-2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DDC_DISPLAY_SELECTION_H_ 7 | #define DDC_DISPLAY_SELECTION_H_ 8 | 9 | #include "base/core.h" 10 | #include "base/displays.h" 11 | 12 | Display_Ref* 13 | get_display_ref_for_display_identifier( 14 | Display_Identifier* pdid, 15 | Call_Options callopts); 16 | 17 | void 18 | init_ddc_display_selection(); 19 | #endif /* DDC_DISPLAY_SELECTION_H_ */ 20 | -------------------------------------------------------------------------------- /src/ddc/ddc_dumpload.h: -------------------------------------------------------------------------------- 1 | /** \file dumpload.h 2 | * 3 | * Load/store VCP settings from/to file. 4 | */ 5 | 6 | // Copyright (C) 2014-2021 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | 10 | #ifndef DDC_DUMPLOAD_H_ 11 | #define DDC_DUMPLOAD_H_ 12 | 13 | /** \cond */ 14 | #include 15 | 16 | #include "util/error_info.h" 17 | /** \endcond */ 18 | 19 | #include "base/displays.h" 20 | #include "base/status_code_mgt.h" 21 | 22 | #include "vcp/vcp_feature_values.h" 23 | 24 | 25 | /** 26 | Internal form data structure used to hold data being loaded or dumped. 27 | 28 | Whatever the external form, a file or a string, loadvcp converts the data to 29 | **Dumpload_Data** and then writes the data to the monitor. 30 | */ 31 | typedef 32 | struct { 33 | time_t timestamp_millis; ///< creation timestamp 34 | Byte edidbytes[128]; ///< 128 byte EDID, 35 | char edidstr[257]; ///< 128 byte EDID as hex string (for future use) 36 | char mfg_id[4]; ///< 3 character manufacturer id (from EDID) 37 | char model[14]; ///< model string (from EDID) 38 | char serial_ascii[14]; ///< serial number string (from EDID) 39 | uint16_t product_code; ///< numeric product code (from EDID) 40 | DDCA_MCCS_Version_Spec vcp_version; ///< monitor VCP/MCCS version 41 | int vcp_value_ct; ///< number of VCP values 42 | Vcp_Value_Set vcp_values; ///< VCP values 43 | } Dumpload_Data; 44 | 45 | void 46 | dbgrpt_dumpload_data(Dumpload_Data * data, int depth); 47 | 48 | void 49 | free_dumpload_data(Dumpload_Data * pdata); 50 | 51 | char * 52 | format_timestamp(time_t time_millis, char * buf, int bufsz); 53 | 54 | Error_Info * 55 | loadvcp_by_dumpload_data( 56 | Dumpload_Data* pdata, 57 | Display_Handle * dh); 58 | 59 | Error_Info * 60 | loadvcp_by_string( 61 | char * catenated, 62 | Display_Handle * dh); 63 | 64 | Error_Info * 65 | create_dumpload_data_from_g_ptr_array( 66 | GPtrArray * garray, 67 | Dumpload_Data ** dumpload_data_loc); 68 | 69 | GPtrArray * 70 | convert_dumpload_data_to_string_array( 71 | Dumpload_Data * data); 72 | 73 | Public_Status_Code 74 | dumpvcp_as_dumpload_data( 75 | Display_Handle * dh, 76 | Dumpload_Data** dumpload_data_loc); 77 | 78 | Public_Status_Code 79 | dumpvcp_as_string( 80 | Display_Handle * dh, 81 | char** result_loc); 82 | 83 | void init_ddc_dumpload(); 84 | 85 | #endif /* DDC_DUMPLOAD_H_ */ 86 | -------------------------------------------------------------------------------- /src/ddc/ddc_initial_checks.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_initial_checks.h */ 2 | 3 | // Copyright (C) 2014-2024 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DDC_INITIAL_CHECKS_H_ 7 | #define DDC_INITIAL_CHECKS_H_ 8 | 9 | #include 10 | 11 | #include "util/error_info.h" 12 | #include "base/displays.h" 13 | 14 | extern bool skip_ddc_checks; 15 | extern bool monitor_state_tests; 16 | 17 | Error_Info * ddc_initial_checks_by_dref(Display_Ref * dref, bool newly_added); 18 | void explore_monitor_state(Display_Handle* dh); 19 | 20 | void init_ddc_initial_checks(); 21 | 22 | #endif /* DDC_INITIAL_CHECKS_H_ */ 23 | -------------------------------------------------------------------------------- /src/ddc/ddc_multi_part_io.h: -------------------------------------------------------------------------------- 1 | /** \file ddc_multi_part_io.h 2 | * 3 | * Capabilities read and Table feature read/write that require multiple 4 | * reads and writes for completion. 5 | */ 6 | 7 | // Copyright (C) 2014-2023 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | #ifndef DDC_MULTI_PART_IO_H_ 11 | #define DDC_MULTI_PART_IO_H_ 12 | 13 | /** \cond */ 14 | #include 15 | 16 | #include "util/error_info.h" 17 | #include "util/data_structures.h" 18 | /** \endcond */ 19 | 20 | #include "base/displays.h" 21 | #include "base/status_code_mgt.h" 22 | 23 | #include "ddc/ddc_packet_io.h" 24 | 25 | //temp: 26 | extern int multi_part_null_adjustment_millis; 27 | 28 | Error_Info * 29 | multi_part_read_with_retry( 30 | Display_Handle * dh, 31 | Byte request_type, 32 | Byte request_subtype, // VCP feature code for table read, ignore for capabilities 33 | DDC_Write_Read_Flags write_read_flags, 34 | Buffer** ppbuffer); 35 | 36 | Error_Info * 37 | multi_part_write_with_retry( 38 | Display_Handle * dh, 39 | Byte vcp_code, 40 | Buffer * value_to_set); 41 | 42 | void 43 | init_ddc_multi_part_io(); 44 | 45 | #endif /* DDC_MULTI_PART_IO_H_ */ 46 | -------------------------------------------------------------------------------- /src/ddc/ddc_output.h: -------------------------------------------------------------------------------- 1 | /* \file ddc_output.h 2 | */ 3 | 4 | // Copyright (C) 2014-2024 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef DDC_OUTPUT_H_ 8 | #define DDC_OUTPUT_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "base/core.h" 15 | #include "base/displays.h" 16 | #include "base/status_code_mgt.h" 17 | 18 | #include "dynvcp/vcp_feature_set.h" 19 | #include "vcp/vcp_feature_values.h" 20 | 21 | 22 | // TODO: Should probably be in a more general location 23 | // Standard printf format strings for reporting feature codes values. 24 | extern const char* FMT_CODE_NAME_DETAIL_W_NL; 25 | extern const char* FMT_CODE_NAME_DETAIL_WO_NL; 26 | 27 | #ifdef FUTURE 28 | // not currently used 29 | Public_Status_Code 30 | check_valid_operation_by_feature_rec_and_version( 31 | VCP_Feature_Table_Entry * feature_rec, 32 | Version_Spec vcp_version, 33 | Version_Feature_Flags operation_flags); 34 | 35 | // not currently used 36 | Public_Status_Code 37 | check_valid_operation_by_feature_id_and_dh( 38 | Byte feature_id, 39 | Display_Handle * dh, 40 | Version_Feature_Flags operation_flags); 41 | #endif 42 | 43 | 44 | Public_Status_Code 45 | ddc_collect_raw_subset_values( 46 | Display_Handle * dh, 47 | VCP_Feature_Subset subset, 48 | Vcp_Value_Set vset, 49 | bool ignore_unsupported, 50 | FILE * msg_fh); 51 | 52 | Public_Status_Code 53 | ddc_get_formatted_value_for_dfm( 54 | Display_Handle * dh, 55 | Display_Feature_Metadata * dfm, 56 | bool suppress_unsupported, 57 | bool prefix_value_with_feature_code, 58 | char ** formatted_value_loc, 59 | FILE * msg_fh); 60 | 61 | Public_Status_Code 62 | ddc_show_vcp_values( 63 | Display_Handle * dh, 64 | VCP_Feature_Subset subset, 65 | GPtrArray * collector, 66 | Feature_Set_Flags flags, 67 | Bit_Set_256 * features_seen); 68 | 69 | 70 | void init_ddc_output(); 71 | #endif /* DDC_OUTPUT_H_ */ 72 | -------------------------------------------------------------------------------- /src/ddc/ddc_packet_io.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_packet_io.h 2 | * 3 | * Functions for performing DDC packet IO, Handles I2C bus retry. 4 | */ 5 | 6 | // Copyright (C) 2014-2025 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef DDC_PACKET_IO_H_ 10 | #define DDC_PACKET_IO_H_ 11 | 12 | #include 13 | 14 | #include "util/error_info.h" 15 | 16 | #include "base/core.h" 17 | #include "base/ddc_packets.h" 18 | #include "base/displays.h" 19 | 20 | 21 | extern bool DDC_Read_Bytewise; 22 | extern bool simulate_null_msg_means_unsupported; 23 | 24 | typedef enum { 25 | Write_Read_Flags_None = 0, 26 | Write_Read_Flag_All_Zero_Response_Ok = 1, 27 | Write_Read_Flag_Capabilities = 2, 28 | Write_Read_Flag_Table_Read = 4 29 | } DDC_Write_Read_Flags ; 30 | 31 | Error_Info * ddc_open_display( 32 | Display_Ref * dref, 33 | Call_Options callopts, 34 | Display_Handle** dh_loc); 35 | 36 | Error_Info * ddc_close_display( 37 | Display_Handle * dh); 38 | 39 | void ddc_close_display_wo_return( 40 | Display_Handle * dh); 41 | 42 | void ddc_close_all_displays(); 43 | void ddc_close_all_displays_for_current_thread(bool error_if_open); 44 | 45 | DDCA_Status ddc_validate_display_handle2(Display_Handle * dh); 46 | 47 | void ddc_dbgrpt_valid_display_handles(int depth); 48 | 49 | Error_Info * ddc_write_only( 50 | Display_Handle * dh, 51 | DDC_Packet * request_packet_ptr); 52 | 53 | Error_Info * ddc_write_only_with_retry( 54 | Display_Handle * dh, 55 | DDC_Packet * request_packet_ptr); 56 | 57 | Error_Info * ddc_write_read( 58 | Display_Handle * dh, 59 | DDC_Packet * request_packet_ptr, 60 | bool read_bytewise, 61 | int max_read_bytes, 62 | Byte expected_response_type, 63 | Byte expected_subtype, 64 | DDC_Packet ** response_packet_ptr_loc 65 | ); 66 | 67 | Error_Info * ddc_write_read_with_retry( 68 | Display_Handle * dh, 69 | DDC_Packet * request_packet_ptr, 70 | int max_read_bytes, 71 | Byte expected_response_type, 72 | Byte expected_subtype, 73 | DDC_Write_Read_Flags flags, 74 | DDC_Packet ** response_packet_ptr_loc 75 | ); 76 | 77 | void init_ddc_packet_io(); 78 | 79 | void terminate_ddc_packet_io(); 80 | 81 | #endif /* DDC_PACKET_IO_H_ */ 82 | 83 | -------------------------------------------------------------------------------- /src/ddc/ddc_phantom_displays.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_phantom_displays.h Phantom display detection */ 2 | 3 | // Copyright (C) 2024 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DDC_PHANTOM_DISPLAYS_H_ 7 | #define DDC_PHANTOM_DISPLAYS_H_ 8 | 9 | #include 10 | #include 11 | 12 | extern bool detect_phantom_displays; 13 | 14 | bool filter_phantom_displays(GPtrArray * all_displays); 15 | void init_ddc_phantom_displays(); 16 | 17 | #endif /* DDC_PHANTOM_DISPLAYS_H_ */ 18 | -------------------------------------------------------------------------------- /src/ddc/ddc_read_capabilities.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_read_capabilities.h 2 | */ 3 | 4 | // Copyright (C) 2014-2023 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef DDC_READ_CAPABILITIES_H_ 8 | #define DDC_READ_CAPABILITIES_H_ 9 | 10 | /** \cond */ 11 | #include "util/error_info.h" 12 | /** \endcond */ 13 | 14 | #include "base/displays.h" 15 | 16 | // Get capability string for monitor. 17 | 18 | Error_Info * 19 | ddc_get_capabilities_string( 20 | Display_Handle * dh, 21 | char** caps_loc); 22 | 23 | void init_ddc_read_capabilities(); 24 | 25 | #endif /* DDC_READ_CAPABILITIES_H_ */ 26 | -------------------------------------------------------------------------------- /src/ddc/ddc_save_current_settings.c: -------------------------------------------------------------------------------- 1 | /** @file ddc_save_current_settings.c 2 | * Implement DDC command Save Current Settings 3 | */ 4 | 5 | // Copyright (C) 2014-2024 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #include 9 | 10 | #include "public/ddcutil_status_codes.h" 11 | 12 | #include "util/error_info.h" 13 | 14 | #include "base/core.h" 15 | #include "base/ddc_packets.h" 16 | #include "base/displays.h" 17 | #include "base/rtti.h" 18 | 19 | #include "ddc_packet_io.h" 20 | 21 | #include "ddc_save_current_settings.h" 22 | 23 | 24 | // Trace class for this file 25 | static DDCA_Trace_Group TRACE_GROUP = DDCA_TRC_DDC; 26 | 27 | // 28 | // DDC command Save Current Settings 29 | // 30 | 31 | /** Executes the DDC Save Current Settings command. 32 | * 33 | * @param dh handle of open display device 34 | * @return NULL if success, pointer to #Error_Info if failure 35 | */ 36 | Error_Info * 37 | ddc_save_current_settings( 38 | Display_Handle * dh) 39 | { 40 | bool debug = false; 41 | DBGTRC_STARTING(debug, TRACE_GROUP, 42 | "Invoking DDC Save Current Settings command. dh=%s", dh_repr(dh)); 43 | 44 | Error_Info * ddc_excp = NULL; 45 | if (dh->dref->io_path.io_mode == DDCA_IO_USB) { 46 | // command line parser should block this case 47 | PROGRAM_LOGIC_ERROR("MCCS over USB does not have Save Current Settings command"); 48 | ddc_excp = ERRINFO_NEW(DDCRC_UNIMPLEMENTED, 49 | "MCCS over USB does not have Save Current Settings command" ); 50 | } 51 | else { 52 | DDC_Packet * request_packet_ptr = 53 | create_ddc_save_settings_request_packet("save_current_settings:request packet"); 54 | // DBGMSG("create_ddc_save_settings_request_packet returned packet_ptr=%p", request_packet_ptr); 55 | // dump_packet(request_packet_ptr); 56 | 57 | ddc_excp = ddc_write_only_with_retry(dh, request_packet_ptr); 58 | 59 | free_ddc_packet(request_packet_ptr); 60 | } 61 | 62 | DBGTRC_RET_ERRINFO(debug, TRACE_GROUP, ddc_excp, ""); 63 | return ddc_excp; 64 | } 65 | 66 | 67 | void 68 | init_ddc_save_current_settings() { 69 | RTTI_ADD_FUNC(ddc_save_current_settings); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/ddc/ddc_save_current_settings.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_save_current_settings.h 2 | * Implement DDC command Save Current Settings 3 | */ 4 | 5 | // Copyright (C) 2024 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef DDC_SAVE_CURRENT_SETTINGS_H_ 9 | #define DDC_SAVE_CURRENT_SETTINGS_H_ 10 | 11 | 12 | #include "util/error_info.h" 13 | 14 | #include "base/displays.h" 15 | 16 | Error_Info * 17 | ddc_save_current_settings( 18 | Display_Handle * dh); 19 | 20 | void 21 | init_ddc_save_current_settings(); 22 | 23 | #endif /* DDC_SAVE_CURRENT_SETTINGS_H_ */ 24 | -------------------------------------------------------------------------------- /src/ddc/ddc_serialize.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_serialize.h */ 2 | 3 | // Copyright (C) 2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DDC_SERIALIZE_H_ 7 | #define DDC_SERIALIZE_H_ 8 | 9 | #include 10 | #include 11 | 12 | #include "base/displays.h" 13 | 14 | extern bool display_caching_enabled; 15 | void ddc_enable_displays_cache(bool onoff); 16 | char * ddc_displays_cache_file_name(); 17 | bool ddc_store_displays_cache(); 18 | void ddc_restore_displays_cache(); 19 | void ddc_erase_displays_cache(); 20 | Display_Ref * ddc_find_deserialized_display(int busno, Byte* edidbytes); 21 | void init_ddc_serialize(); 22 | void terminate_ddc_serialize(); 23 | 24 | #endif /* DDC_SERIALIZE_H_ */ 25 | -------------------------------------------------------------------------------- /src/ddc/ddc_services.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_services.h 2 | * 3 | * ddc layer initialization and configuration, statistics management 4 | */ 5 | 6 | // Copyright (C) 2014-2023 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef DDC_SERVICES_H_ 10 | #define DDC_SERVICES_H_ 11 | 12 | #include 13 | #include 14 | 15 | #include "public/ddcutil_types.h" 16 | 17 | void init_ddc_services(); 18 | void terminate_ddc_services(); 19 | void ddc_reset_stats_main(); 20 | void ddc_report_stats_main( 21 | DDCA_Stats_Type stats, 22 | bool report_per_display, 23 | bool include_dsa_stats, 24 | bool stats_to_syslog_only, 25 | int depth); 26 | 27 | #endif /* DDC_SERVICES_H_ */ 28 | -------------------------------------------------------------------------------- /src/ddc/ddc_strategy.c: -------------------------------------------------------------------------------- 1 | /** @file ddc_strategy.c 2 | */ 3 | 4 | // Copyright (C) 2015-2023 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | /** \cond */ 8 | #include 9 | /** \endcond */ 10 | 11 | #include "ddc/ddc_strategy.h" 12 | 13 | // keep in sync w DDC_IO_Mode 14 | DDC_Strategy ddc_strategies[] = { 15 | {DDCA_IO_I2C, NULL, NULL }, 16 | {DDCA_IO_USB, NULL, NULL } 17 | }; 18 | 19 | void validate_ddc_strategies() { 20 | assert( ddc_strategies[DDCA_IO_I2C].io_mode == DDCA_IO_I2C); 21 | assert( ddc_strategies[DDCA_IO_USB].io_mode == DDCA_IO_USB); 22 | } 23 | 24 | DDC_Raw_Writer ddc_raw_writer(Display_Handle * dh) { 25 | assert(dh && dh->dref); 26 | return ddc_strategies[dh->dref->io_path.io_mode].writer; 27 | } 28 | 29 | DDC_Raw_Reader ddc_raw_reader(Display_Handle * dh) { 30 | assert(dh && dh->dref); 31 | return ddc_strategies[dh->dref->io_path.io_mode].reader; 32 | } 33 | 34 | void init_ddc_strategies() { 35 | validate_ddc_strategies(); 36 | } 37 | -------------------------------------------------------------------------------- /src/ddc/ddc_strategy.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_strategy.h 2 | */ 3 | 4 | // Copyright (C) 2017 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef DDC_STRATEGY_H_ 8 | #define DDC_STRATEGY_H_ 9 | 10 | #include "util/coredefs.h" 11 | 12 | #include "base/displays.h" 13 | #include "base/status_code_mgt.h" 14 | 15 | // For future use 16 | 17 | void init_ddc_strategies(); 18 | 19 | 20 | typedef Public_Status_Code (*DDC_Raw_Writer)(Display_Handle * dh, int bytect, Byte * bytes); 21 | typedef Public_Status_Code (*DDC_Raw_Reader)(Display_Handle * dh, int bufsize, Byte * buffer); 22 | 23 | typedef struct { 24 | DDCA_IO_Mode io_mode; 25 | DDC_Raw_Writer writer; 26 | DDC_Raw_Reader reader; 27 | } DDC_Strategy; 28 | 29 | DDC_Raw_Writer ddc_raw_writer(Display_Handle * dh); 30 | DDC_Raw_Reader ddc_raw_reader(Display_Handle * dh); 31 | 32 | #endif /* DDC_STRATEGY_H_ */ 33 | -------------------------------------------------------------------------------- /src/ddc/ddc_try_data.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_try_stats.h 2 | * 3 | * Maintains statistics on DDC retries and also maxtries settings. 4 | * 5 | * These statistics are global, not broken out by thread. 6 | */ 7 | 8 | // Copyright (C) 2014-2023 Sanford Rockowitz 9 | // SPDX-License-Identifier: GPL-2.0-or-later 10 | 11 | #ifndef TRY_STATS_H_ 12 | #define TRY_STATS_H_ 13 | 14 | #include 15 | 16 | #include "ddcutil_types.h" 17 | 18 | #include "base/displays.h" 19 | #include "base/stats.h" 20 | 21 | void try_data_init_retry_type(Retry_Operation retry_type, Retry_Op_Value maxtries); 22 | void init_ddc_try_data(); 23 | bool try_data_lock(); 24 | void try_data_unlock(bool this_function_owns_lock); 25 | Retry_Op_Value 26 | try_data_get_maxtries2(Retry_Operation retry_type); 27 | void try_data_set_maxtries2(Retry_Operation retry_type, Retry_Op_Value new_maxtries); 28 | void try_data_reset2_all(); 29 | void try_data_record_tries2(Display_Handle * dh, Retry_Operation retry_type, DDCA_Status rc, int tryct); 30 | 31 | void ddc_report_max_tries(int depth); 32 | void ddc_report_ddc_stats(int depth); 33 | 34 | #endif /* TRY_STATS_H_ */ 35 | -------------------------------------------------------------------------------- /src/ddc/ddc_vcp.h: -------------------------------------------------------------------------------- 1 | /** \file ddc_vcp.h 2 | * Virtual Control Panel access 3 | * Basic functions to get and set single values and save current settings. 4 | */ 5 | 6 | // Copyright (C) 2014-2024 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef DDC_VCP_H_ 10 | #define DDC_VCP_H_ 11 | 12 | /** \cond */ 13 | #include 14 | #include 15 | 16 | #include "util/error_info.h" 17 | /** \endcond */ 18 | 19 | #include "base/core.h" 20 | #include "base/displays.h" 21 | #include "base/status_code_mgt.h" 22 | 23 | #include "vcp/vcp_feature_codes.h" 24 | #include "vcp/vcp_feature_values.h" 25 | 26 | extern bool enable_mock_data; 27 | extern bool setvcp_verify_default; 28 | extern int max_setvcp_verify_tries; 29 | 30 | bool 31 | ddc_set_verify_setvcp( 32 | bool onoff); 33 | 34 | bool 35 | ddc_get_verify_setvcp(); 36 | 37 | 38 | Error_Info * 39 | ddc_set_nontable_vcp_value( 40 | Display_Handle * dh, 41 | Byte feature_code, 42 | int new_value); 43 | 44 | Error_Info * 45 | ddc_set_vcp_value( 46 | Display_Handle * dh, 47 | DDCA_Any_Vcp_Value * vrec, 48 | DDCA_Any_Vcp_Value ** newval_loc); 49 | 50 | Error_Info * 51 | ddc_set_verified_vcp_value_with_retry( 52 | Display_Handle * dh, 53 | DDCA_Any_Vcp_Value * vrec, 54 | DDCA_Any_Vcp_Value ** newval_loc); 55 | 56 | Error_Info * 57 | ddc_get_table_vcp_value( 58 | Display_Handle * dh, 59 | Byte feature_code, 60 | Buffer** table_bytes_loc); 61 | 62 | Error_Info * 63 | ddc_get_nontable_vcp_value( 64 | Display_Handle * dh, 65 | Byte feature_code, 66 | Parsed_Nontable_Vcp_Response** parsed_response_loc); 67 | 68 | Error_Info * 69 | ddc_get_vcp_value( 70 | Display_Handle * dh, 71 | Byte feature_code, 72 | DDCA_Vcp_Value_Type call_type, 73 | DDCA_Any_Vcp_Value ** valrec_loc); 74 | 75 | void 76 | init_ddc_vcp(); 77 | 78 | #endif /* DDC_VCP_H_ */ 79 | -------------------------------------------------------------------------------- /src/ddc/ddc_vcp_version.h: -------------------------------------------------------------------------------- 1 | /** @file ddc_vcp_version.h 2 | * 3 | * Functions to obtain the VCP (MCCS) version for a display. 4 | * These functions are in a separate source file to simplify 5 | * the acyclic graph of #includes within the ddc source directory. 6 | */ 7 | 8 | // Copyright (C) 2014-2025 Sanford Rockowitz 9 | // SPDX-License-Identifier: GPL-2.0-or-later 10 | 11 | #ifndef DDC_VCP_VERSION_H_ 12 | #define DDC_VCP_VERSION_H_ 13 | 14 | #include "base/displays.h" 15 | #include "base/vcp_version.h" 16 | 17 | DDCA_MCCS_Version_Spec get_overriding_vcp_version(Display_Ref * dref); 18 | DDCA_MCCS_Version_Spec set_vcp_version_xdf_by_dh(Display_Handle * dh); 19 | DDCA_MCCS_Version_Spec get_vcp_version_by_dh( Display_Handle * dh); 20 | DDCA_MCCS_Version_Spec get_vcp_version_by_dref( Display_Ref * dref); 21 | 22 | void init_ddc_vcp_version(); 23 | 24 | #endif /* DDC_VCP_VERSION_H_ */ 25 | -------------------------------------------------------------------------------- /src/dw/Makefile.am: -------------------------------------------------------------------------------- 1 | # src/dw/Makefile.am 2 | 3 | AM_CPPFLAGS = \ 4 | $(LIBDRM_CFLAGS) \ 5 | $(GLIB_CFLAGS) \ 6 | $(JANSSON_CFLAGS) \ 7 | -I$(top_srcdir)/src \ 8 | -I$(top_srcdir)/src/public 9 | 10 | AM_CFLAGS = $(AM_CFLAGS_STD) 11 | 12 | 13 | CLEANFILES = \ 14 | *expand 15 | 16 | # Intermediate Library 17 | noinst_LTLIBRARIES = libdw.la 18 | 19 | libdw_la_SOURCES = \ 20 | dw_status_events.c 21 | 22 | if ENABLE_UDEV_COND 23 | libdw_la_SOURCES += \ 24 | dw_common.c \ 25 | dw_main.c \ 26 | dw_poll.c \ 27 | dw_dref.c \ 28 | dw_udev.c \ 29 | dw_recheck.c \ 30 | dw_services.c 31 | endif 32 | 33 | if ENABLE_UDEV_COND 34 | if USE_X11_COND 35 | libdw_la_SOURCES += \ 36 | dw_xevent.c 37 | endif 38 | endif 39 | 40 | # Rename to "all=local" for development 41 | all-local-disabled: 42 | @echo "" 43 | @echo "(src/Makefile:all-local) Variable values:" 44 | @echo " CLEANFILES: $(CLEANFILES)" 45 | @echo " CFLAGS: $(CFLAGS)" 46 | @echo " AM_CFLAGS: $(AM_CFLAGS)" 47 | @echo " CPPFLAGS: $(CPPFLAGS)" 48 | @echo " AM_CPPFLAGS: $(AM_CPPFLAGS)" 49 | @echo " ddcutil_FLAGS: $(ddcutil_CFLAGS)" 50 | @echo " AUTOMAKE_OPTIONS: $(AUTOMAKE_OPTIONS)" 51 | @echo " MAKELEVEL: $(MAKELEVEL)" 52 | @echo " MAKEFLAGS: $(MAKEFLAGS)" 53 | @echo " V: $(V)" 54 | @echo " AM_CFLAGS_STD: $(AM_CFLAGS_STD)" 55 | @echo "" 56 | -------------------------------------------------------------------------------- /src/dw/dw_dref.h: -------------------------------------------------------------------------------- 1 | /** @file dw_dref.h 2 | * Functions that modify persistent Display_Ref related data structures when 3 | * display connection and disconnection are detected. 4 | */ 5 | 6 | // Copyright (C) 2024-2025 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #include 10 | 11 | #include "util/error_info.h" 12 | 13 | #include "base/displays.h" 14 | #include "base/i2c_bus_base.h" 15 | 16 | #ifndef DW_DREF_H_ 17 | #define DW_DREF_H_ 18 | 19 | void dw_add_display_ref(Display_Ref * dref); 20 | void dw_mark_display_ref_removed(Display_Ref* dref); 21 | Display_Ref* dw_add_display_by_businfo(I2C_Bus_Info * businfo); 22 | Display_Ref* dw_remove_display_by_businfo(I2C_Bus_Info * businfo); 23 | Error_Info* dw_recheck_dref(Display_Ref * dref); 24 | 25 | void init_dw_dref(); 26 | 27 | #endif /* DW_DREF_H_ */ 28 | -------------------------------------------------------------------------------- /src/dw/dw_main.h: -------------------------------------------------------------------------------- 1 | /** @file dw_main.h */ 2 | 3 | // Copyright (C) 2024-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DW_MAIN_H_ 7 | #define DW_MAIN_H_ 8 | 9 | /** \cond */ 10 | #include 11 | 12 | #include "public/ddcutil_types.h" 13 | 14 | #include "util/error_info.h" 15 | /** \endcond */ 16 | 17 | extern DDC_Watch_Mode watch_displays_mode; 18 | extern bool enable_watch_displays; 19 | 20 | Error_Info * dw_start_watch_displays(DDCA_Display_Event_Class event_classes); 21 | DDCA_Status dw_stop_watch_displays(bool wait, DDCA_Display_Event_Class* enabled_classes); 22 | DDCA_Status dw_get_active_watch_classes(DDCA_Display_Event_Class * classes_loc); 23 | void dw_redetect_displays(); 24 | bool dw_is_watch_displays_executing(); 25 | void dw_get_display_watch_settings(DDCA_DW_Settings * settings_buffer); 26 | DDCA_Status dw_set_display_watch_settings(DDCA_DW_Settings * settings_buffer); 27 | void init_dw_main(); 28 | 29 | #endif /* DW_MAIN_H_ */ 30 | -------------------------------------------------------------------------------- /src/dw/dw_poll.h: -------------------------------------------------------------------------------- 1 | /** @file dw_poll.h */ 2 | 3 | // Copyright (C) 2024-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DW_POLL_H_ 7 | #define DW_POLL_H_ 8 | 9 | #include 10 | 11 | extern int nonudev_poll_loop_millisec; 12 | extern int retry_thread_sleep_factor_millisec; 13 | extern bool stabilize_added_buses_w_edid; 14 | extern bool recheck_thread_active; // ?? needed? 15 | extern GMutex process_event_mutex; 16 | 17 | gpointer dw_watch_display_connections(gpointer data); 18 | void init_dw_poll(); 19 | 20 | #endif /* DW_POLL_H_ */ 21 | -------------------------------------------------------------------------------- /src/dw/dw_recheck.h: -------------------------------------------------------------------------------- 1 | /** @file dw_recheck.h */ 2 | 3 | // Copyright (C) 2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DW_RECHECK_H_ 7 | #define DW_RECHECK_H_ 8 | 9 | #include 10 | 11 | void dw_put_recheck_queue(Display_Ref* dref); 12 | gpointer dw_recheck_displays_func(gpointer data); 13 | 14 | void init_dw_recheck(); 15 | 16 | #endif /* DW_RECHECK_H_ */ 17 | -------------------------------------------------------------------------------- /src/dw/dw_services.c: -------------------------------------------------------------------------------- 1 | /** @file dw_services.c 2 | * 3 | * display watch layer initialization and configuration 4 | */ 5 | 6 | // Copyright (C) 2024-2025 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #include "config.h" 10 | 11 | #include "dw/dw_common.h" 12 | #include "dw/dw_dref.h" 13 | #include "dw/dw_main.h" 14 | #include "dw/dw_poll.h" 15 | #include "dw/dw_recheck.h" 16 | #include "dw/dw_status_events.h" 17 | #include "dw/dw_udev.h" 18 | #ifdef USE_X11 19 | #include "dw/dw_xevent.h" 20 | #endif 21 | 22 | #include "dw_services.h" 23 | 24 | 25 | /** Initialize files in dw directory */ 26 | void init_dw_services() { 27 | bool debug = false; 28 | DBGMSF(debug, "Starting"); 29 | 30 | init_dw_common(); 31 | init_dw_dref(); 32 | init_dw_main(); 33 | init_dw_poll(); 34 | init_dw_recheck(); 35 | init_dw_status_events(); 36 | init_dw_udev(); 37 | #ifdef USE_X11 38 | init_dw_xevent(); 39 | #endif 40 | 41 | DBGMSF(debug, "Done"); 42 | } 43 | 44 | 45 | /** Termination for files in dw directory */ 46 | void terminate_dw_services() { 47 | bool debug = false; 48 | DBGTRC_STARTING(debug, DDCA_TRC_CONN, ""); 49 | 50 | DBGTRC_DONE(debug, DDCA_TRC_CONN, ""); 51 | } 52 | -------------------------------------------------------------------------------- /src/dw/dw_services.h: -------------------------------------------------------------------------------- 1 | /** @file dw_services.h 2 | * 3 | * dw layer initialization and configuration, statistics management 4 | */ 5 | 6 | // Copyright (C) 2024-2025 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef DW_SERVICES_H_ 10 | #define DW_SERVICES_H_ 11 | 12 | #include 13 | #include 14 | 15 | #include "public/ddcutil_types.h" 16 | 17 | void init_dw_services(); 18 | void terminate_dw_services(); 19 | 20 | #endif /* DW_SERVICES_H_ */ 21 | -------------------------------------------------------------------------------- /src/dw/dw_status_events.h: -------------------------------------------------------------------------------- 1 | /** @file dw_status_events.h */ 2 | 3 | // Copyright (C) 2024-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DW_STATUS_EVENTS_H_ 7 | #define DW_STATUS_EVENTS_H_ 8 | 9 | #include "glib-2.0/glib.h" 10 | 11 | #include "public/ddcutil_types.h" 12 | 13 | #include "base/displays.h" 14 | 15 | 16 | typedef struct { 17 | DDCA_Display_Status_Callback_Func func; 18 | DDCA_Display_Status_Event event; 19 | } Callback_Queue_Entry; 20 | 21 | gpointer dw_execute_callback_func(gpointer data); 22 | 23 | 24 | // Display Status Events 25 | DDCA_Status dw_register_display_status_callback(DDCA_Display_Status_Callback_Func func); 26 | DDCA_Status dw_unregister_display_status_callback(DDCA_Display_Status_Callback_Func func); 27 | const char * dw_display_event_class_name(DDCA_Display_Event_Class class); 28 | const char* dw_display_event_type_name(DDCA_Display_Event_Type event_type); 29 | char * display_status_event_repr(DDCA_Display_Status_Event evt); 30 | char * display_status_event_repr_t(DDCA_Display_Status_Event evt); 31 | DDCA_Display_Status_Event 32 | dw_create_display_status_event(DDCA_Display_Event_Type event_type, 33 | const char * connector_name, 34 | Display_Ref* dref, 35 | DDCA_IO_Path io_path); 36 | void dw_emit_display_status_record(DDCA_Display_Status_Event evt); 37 | void dw_emit_or_queue_display_status_event(DDCA_Display_Event_Type event_type, 38 | const char * connector_name, 39 | Display_Ref* dref, 40 | DDCA_IO_Path io_path, 41 | GArray* queue); 42 | void init_dw_status_events(); 43 | 44 | #endif /* DW_STATUS_EVENTS_H_ */ 45 | -------------------------------------------------------------------------------- /src/dw/dw_udev.h: -------------------------------------------------------------------------------- 1 | /** @file dw_udev.h 2 | * Watch for monitor addition and removal using UDEV 3 | */ 4 | 5 | // Copyright (C) 2019-2025 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef DW_UDEV_H_ 9 | #define DW_UDEV_H_ 10 | 11 | /** \cond */ 12 | #include 13 | #include 14 | 15 | #include "public/ddcutil_types.h" 16 | /** \endcond */ 17 | 18 | extern bool use_sysfs_connector_id; 19 | extern bool report_udev_events; 20 | 21 | gpointer dw_watch_displays_udev(gpointer data); 22 | void init_dw_udev(); 23 | 24 | #endif /* DW_UDEV_H_ */ 25 | -------------------------------------------------------------------------------- /src/dw/dw_xevent.h: -------------------------------------------------------------------------------- 1 | /** @file dw_xevent.h */ 2 | 3 | // Copyright (C) 2024-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DW_XEVENT_H_ 7 | #define DW_XEVENT_H_ 8 | 9 | #include 10 | #include 11 | 12 | typedef struct { 13 | Display* dpy; 14 | int screen; 15 | Window w; 16 | int rr_event_base; 17 | int rr_error_base; 18 | int screen_change_eventno; 19 | } XEvent_Data; 20 | 21 | void dw_dbgrpt_xevent_data(XEvent_Data* evdata, int depth); 22 | void dw_deinit_xevent_screen_change_notification(XEvent_Data * evdata); 23 | XEvent_Data * dw_init_xevent_screen_change_notification(); 24 | bool dw_detect_xevent_screen_change(XEvent_Data * evdata, int poll_interval); 25 | bool dw_next_X11_event_of_interest(XEvent_Data * evdata); 26 | void dw_send_x11_termination_message(XEvent_Data * evdata); 27 | 28 | void init_dw_xevent(); 29 | 30 | #endif /* DW_XEVENT_H_ */ 31 | -------------------------------------------------------------------------------- /src/dynvcp/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | -I$(top_srcdir)/src \ 4 | -I$(top_srcdir)/src/public 5 | 6 | AM_CFLAGS = $(AM_CFLAGS_STD) 7 | 8 | CLEANFILES = \ 9 | *expand 10 | 11 | # Intermediate Library 12 | noinst_LTLIBRARIES = libdynvcp.la 13 | 14 | libdynvcp_la_SOURCES = \ 15 | vcp_feature_set.c \ 16 | dyn_feature_set.c \ 17 | dyn_parsed_capabilities.c \ 18 | dyn_feature_codes.c \ 19 | dyn_feature_files.c 20 | -------------------------------------------------------------------------------- /src/dynvcp/dyn_feature_files.h: -------------------------------------------------------------------------------- 1 | /** \file dyn_feature_files.h 2 | * 3 | * Maintain dynamic feature files 4 | */ 5 | // Copyright (C) 2018-2023 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef DYN_FEATURE_FILES_H_ 9 | #define DYN_FEATURE_FILES_H_ 10 | 11 | /** \cond */ 12 | #include "ddcutil_types.h" 13 | 14 | #include "util/error_info.h" 15 | /** \endcond */ 16 | 17 | #include "base/displays.h" 18 | 19 | extern bool enable_dynamic_features; 20 | 21 | char * 22 | dfr_find_feature_def_file( 23 | const char * simple_fn); 24 | 25 | Error_Info * 26 | dfr_load_by_mmk( 27 | Monitor_Model_Key mmk, 28 | Dynamic_Features_Rec ** dfr_loc); 29 | 30 | Error_Info * dfr_check_by_dref(Display_Ref * dref); 31 | Error_Info * dfr_check_by_dh(Display_Handle * dh); 32 | #ifdef UNUSED 33 | Error_Info * dfr_check_by_mmk(Monitor_Model_Key mmk); 34 | #endif 35 | 36 | void init_dyn_feature_files(); 37 | 38 | #endif /* DYN_FEATURE_FILES_H_ */ 39 | -------------------------------------------------------------------------------- /src/dynvcp/dyn_parsed_capabilities.h: -------------------------------------------------------------------------------- 1 | /** @file dyn_parsed_capabilities.h 2 | * 3 | * Report parsed capabilities, taking into account dynamic feature definitions. 4 | */ 5 | 6 | // Copyright (C) 2014-2024 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef DYN_PARSED_CAPABILITIES_H_ 10 | #define DYN_PARSED_CAPABILITIES_H_ 11 | 12 | #include "base/displays.h" 13 | #include "vcp/parse_capabilities.h" 14 | 15 | #ifdef UNNEEDED 16 | #include "base/vcp_version.h" 17 | #include "vcp/parsed_capabilities_feature.h" 18 | 19 | void report_capabilities_feature( 20 | Capabilities_Feature_Record * vfr, 21 | DDCA_MCCS_Version_Spec vcp_version, 22 | int depth); 23 | #endif 24 | 25 | void dyn_report_parsed_capabilities( 26 | Parsed_Capabilities* pcaps, 27 | Display_Handle * dh, 28 | Display_Ref * dref, 29 | int depth); 30 | 31 | void init_dyn_parsed_capabilities(); 32 | 33 | #endif /* DYN_PARSED_CAPABILITIES_H_ */ 34 | -------------------------------------------------------------------------------- /src/dynvcp/vcp_feature_set.h: -------------------------------------------------------------------------------- 1 | /** @file vcp_feature_set.h 2 | * Struct VCP_Feature_Set holds VCP_Feature_Table_Entry(s) for 3 | * some collection of VCP features. 4 | */ 5 | 6 | // Copyright (C) 2014-2024 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef VCP_FEATURE_SET_H_ 10 | #define VCP_FEATURE_SET_H_ 11 | 12 | #include "public/ddcutil_types.h" 13 | 14 | /** \cond */ 15 | #include 16 | #include 17 | 18 | #include "util/coredefs.h" 19 | /** \endcond */ 20 | 21 | #include "base/feature_set_ref.h" 22 | 23 | #include "vcp/vcp_feature_codes.h" 24 | 25 | #define VCP_FEATURE_SET_MARKER "FSET" 26 | typedef struct vcp_feature_set { 27 | char marker[4]; 28 | VCP_Feature_Subset subset; // subset identifier 29 | GPtrArray * members; // array of pointers to VCP_Feature_Table_Entry 30 | } VCP_Feature_Set; 31 | 32 | void free_vcp_feature_set(VCP_Feature_Set * fset); 33 | 34 | typedef bool (*VCP_Feature_Set_Filter_Func)(VCP_Feature_Table_Entry * ventry); 35 | 36 | VCP_Feature_Table_Entry * 37 | get_vcp_feature_set_entry(VCP_Feature_Set * feature_set, unsigned index); 38 | 39 | int get_vcp_feature_set_size(VCP_Feature_Set * feature_set); 40 | void report_vcp_feature_set(VCP_Feature_Set * feature_set, int depth); 41 | void dbgrpt_vcp_feature_set(VCP_Feature_Set * feature_set, int depth); 42 | 43 | VCP_Feature_Set * 44 | create_vcp_feature_set_from_feature_set_ref( 45 | Feature_Set_Ref * fsref, 46 | DDCA_MCCS_Version_Spec vcp_version, 47 | Feature_Set_Flags flags); 48 | // bool force); 49 | 50 | 51 | 52 | #ifdef UNUSED 53 | VCP_Feature_Set * create_single_feature_set_by_vcp_entry(VCP_Feature_Table_Entry * vcp_entry); 54 | VCP_Feature_Set * create_single_feature_set_by_hexid(Byte id, bool force); 55 | void replace_vcp_feature_set_entry( 56 | VCP_Feature_Set * feature_set, 57 | unsigned index, 58 | VCP_Feature_Table_Entry * new_entry); 59 | VCP_Feature_Subset get_feature_set_subset_id(VCP_Feature_Set * feature_set); 60 | void filter_feature_set(VCP_Feature_Set * fset, VCP_Feature_Set_Filter_Func func); 61 | DDCA_Feature_List feature_list_from_feature_set(VCP_Feature_Set * feature_set); 62 | #endif 63 | 64 | void init_vcp_feature_set(); 65 | 66 | #endif /* VCP_FEATURE_SET_H_ */ 67 | -------------------------------------------------------------------------------- /src/i2c/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | $(LIBDRM_CFLAGS) \ 4 | -I$(top_srcdir)/src \ 5 | -I$(top_srcdir)/src/public 6 | 7 | AM_CFLAGS = -Wall 8 | if WARNINGS_ARE_ERRORS_COND 9 | AM_CFLAGS += -Werror 10 | endif 11 | # AM_CFLAGS += -Wpedantic 12 | 13 | if ENABLE_CALLGRAPH_COND 14 | AM_CFLAGS += -fdump-rtl-expand 15 | endif 16 | 17 | CLEANFILES = \ 18 | *expand 19 | 20 | # Intermediate Library 21 | noinst_LTLIBRARIES = libi2c.la 22 | 23 | libi2c_la_SOURCES = \ 24 | i2c_bus_core.c \ 25 | i2c_bus_selector.c \ 26 | i2c_edid.c \ 27 | i2c_execute.c \ 28 | i2c_services.c \ 29 | i2c_strategy_dispatcher.c 30 | -------------------------------------------------------------------------------- /src/i2c/i2c_bus_selector.h: -------------------------------------------------------------------------------- 1 | /** @file i2c_bus_selector.h 2 | * 3 | * Generalized bus_info finder, now used only within usb_edid.c to find 4 | * a fallback EDID 5 | */ 6 | // Copyright (C) 2014-2019 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef I2C_BUS_SELECTOR_H_ 10 | #define I2C_BUS_SELECTOR_H_ 11 | 12 | #include "util/coredefs.h" 13 | 14 | #include "i2c_bus_core.h" 15 | 16 | // Complex Bus_Info retrieval 17 | I2C_Bus_Info * i2c_find_bus_info_by_mfg_model_sn( 18 | const char * mfg_id, 19 | const char * model, 20 | const char * sn, 21 | Byte findopts); 22 | 23 | 24 | #endif /* I2C_BUS_SELECTOR_H_ */ 25 | -------------------------------------------------------------------------------- /src/i2c/i2c_edid.h: -------------------------------------------------------------------------------- 1 | /** \file i2c_edid.h 2 | */ 3 | 4 | // Copyright (C) 2018-2023 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef I2C_EDID_H_ 8 | #define I2C_EDID_H_ 9 | 10 | /** \cond */ 11 | #include 12 | /** \endcond */ 13 | 14 | #include "util/edid.h" 15 | #include "util/data_structures.h" 16 | 17 | #include "base/core.h" 18 | #include "base/status_code_mgt.h" 19 | 20 | extern bool EDID_Read_Uses_I2C_Layer; 21 | extern bool EDID_Read_Bytewise; 22 | extern bool EDID_Write_Before_Read; 23 | extern int EDID_Read_Size; 24 | #ifdef TEST_EDID_SMBUS 25 | extern bool EDID_Read_Uses_Smbus; 26 | #endif 27 | 28 | Status_Errno_DDC i2c_get_raw_edid_by_fd(int fd, Buffer * rawedid); 29 | Status_Errno_DDC i2c_get_parsed_edid_by_fd(int fd, Parsed_Edid ** edid_ptr_loc); 30 | 31 | void init_i2c_edid(); 32 | 33 | #endif /* I2C_EDID_H_ */ 34 | -------------------------------------------------------------------------------- /src/i2c/i2c_execute.h: -------------------------------------------------------------------------------- 1 | /** @file i2c_execute.h 2 | * 3 | * Low level functions for writing to and reading from the I2C bus, 4 | * using various mechanisms. 5 | */ 6 | // Copyright (C) 2014-2022 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef I2C_EXECUTE_H_ 10 | #define I2C_EXECUTE_H_ 11 | 12 | #include "util/coredefs.h" 13 | #include "base/status_code_mgt.h" 14 | 15 | // Controls whether function #i2c_set_addr() retries from EBUSY error by 16 | // changing ioctl op I2C_SLAVE to op I2C_SLAVE_FORCE. 17 | extern bool i2c_forceable_slave_addr_flag; 18 | 19 | Status_Errno i2c_set_addr(int fd, int addr); 20 | 21 | /** Function template for I2C write function */ 22 | typedef Status_Errno_DDC (*I2C_Writer)( 23 | int fd, 24 | Byte slave_address, 25 | int bytect, 26 | Byte * bytes_to_write); 27 | 28 | /** Function template for I2C read function */ 29 | typedef Status_Errno_DDC (*I2C_Reader)( 30 | int fd, 31 | Byte slave_addr, 32 | bool read_bytewise, 33 | int bytect, 34 | Byte * readbuf); 35 | 36 | Status_Errno_DDC i2c_fileio_writer( 37 | int fd, 38 | Byte slave_address, 39 | int bytect, 40 | Byte * pbytes); 41 | 42 | Status_Errno_DDC i2c_fileio_reader ( 43 | int fd, 44 | Byte slave_address, 45 | bool read_bytewise, 46 | int bytect, 47 | Byte * readbuf); 48 | 49 | Status_Errno_DDC i2c_ioctl_writer( 50 | int fd, 51 | Byte slave_address, 52 | int bytect, 53 | Byte * pbytes); 54 | 55 | Status_Errno_DDC i2c_ioctl_reader( 56 | int fd, 57 | Byte slave_address, 58 | bool read_bytewise, 59 | int bytect, 60 | Byte * readbuf); 61 | 62 | void init_i2c_execute(); 63 | 64 | #endif /* I2C_EXECUTE_H_ */ 65 | -------------------------------------------------------------------------------- /src/i2c/i2c_services.c: -------------------------------------------------------------------------------- 1 | /** @file i2c_services.c */ 2 | 3 | // Copyright (C) 2022-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include "base/i2c_bus_base.h" 7 | 8 | #include "i2c_bus_core.h" 9 | #include "i2c_edid.h" 10 | #include "i2c_execute.h" 11 | #include "i2c_strategy_dispatcher.h" 12 | 13 | /** Master initializer for directory i2c */ 14 | void init_i2c_services() { 15 | init_i2c_bus_core(); 16 | init_i2c_edid(); 17 | init_i2c_execute(); 18 | init_i2c_strategy_dispatcher(); 19 | } 20 | 21 | void terminate_i2c_services() { 22 | terminate_i2c_bus_base(); 23 | } 24 | -------------------------------------------------------------------------------- /src/i2c/i2c_services.h: -------------------------------------------------------------------------------- 1 | /* @file i2c_services.h 2 | */ 3 | 4 | // Copyright (C) 2022 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef I2C_SERVICES_H_ 8 | #define I2C_SERVICES_H_ 9 | 10 | void init_i2c_services(); 11 | void terminate_i2c_services(); 12 | 13 | #endif /* I2C_SERVICES_H_ */ 14 | -------------------------------------------------------------------------------- /src/i2c/i2c_strategy_dispatcher.h: -------------------------------------------------------------------------------- 1 | /** \file i2c_strategy_dispatcher.h 2 | * 3 | * Vestigial code for testing alternative mechanisms to read from and write to 4 | * the IC2 bus. 5 | */ 6 | // Copyright (C) 2014-2022 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef I2C_STRATEGY_DISPATCHER_H_ 10 | #define I2C_STRATEGY_DISPATCHER_H_ 11 | 12 | #include "util/coredefs.h" 13 | 14 | #include "base/execution_stats.h" 15 | #include "base/status_code_mgt.h" 16 | 17 | #include "i2c_execute.h" 18 | 19 | 20 | /** I2C IO strategy ids */ 21 | typedef enum { 22 | I2C_IO_STRATEGY_NOT_SET, 23 | I2C_IO_STRATEGY_FILEIO, ///< use file write() and read() 24 | I2C_IO_STRATEGY_IOCTL} ///< use ioctl(I2C_RDWR) 25 | I2C_IO_Strategy_Id; 26 | 27 | char * 28 | i2c_io_strategy_id_name(I2C_IO_Strategy_Id id); 29 | 30 | /** Describes one I2C IO strategy */ 31 | typedef struct { 32 | I2C_IO_Strategy_Id strategy_id; ///< id of strategy 33 | char * strategy_name; ///< name of strategy 34 | I2C_Writer i2c_writer; ///< writer function 35 | I2C_Reader i2c_reader; ///< read function 36 | char * i2c_writer_name; ///< write function name 37 | char * i2c_reader_name; ///< read function name 38 | } I2C_IO_Strategy; 39 | 40 | bool 41 | is_nvidia_einval_bug(I2C_IO_Strategy_Id strategy_id, int busno, int rc); 42 | 43 | void 44 | i2c_set_io_strategy_by_id(I2C_IO_Strategy_Id strategy_id); 45 | 46 | I2C_IO_Strategy_Id 47 | i2c_get_io_strategy_id(); 48 | 49 | Status_Errno_DDC 50 | invoke_i2c_writer( 51 | int fd, 52 | Byte slave_address, 53 | int bytect, 54 | Byte * bytes_to_write); 55 | 56 | Status_Errno_DDC 57 | invoke_i2c_reader( 58 | int fd, 59 | Byte slave_address, 60 | bool read_bytewise, 61 | int bytect, 62 | Byte * readbuf); 63 | 64 | void init_i2c_strategy_dispatcher(); 65 | 66 | #endif /* I2C_STRATEGY_DISPATCHER_H_ */ 67 | -------------------------------------------------------------------------------- /src/i2c/wrap_i2c-dev.h: -------------------------------------------------------------------------------- 1 | /** \file wrap_i2c-dev.h 2 | * 3 | * Including file i2c-dev.h presents multiple issues. 4 | * This header file addresses those issues in one place. 5 | * 6 | * Currently this file is included by i2c_base_io.c and i2c_do_io.c. 7 | * 8 | * This code is in a separate file instead of an existing header 9 | * file because it is not part of the public interface of any 10 | * header file. 11 | */ 12 | // Copyright (C) 2014-2016 Sanford Rockowitz 13 | // SPDX-License-Identifier: GPL-2.0-or-later 14 | 15 | #ifndef WRAP_I2C_DEV_H_ 16 | #define WRAP_I2C_DEV_H_ 17 | 18 | // On Fedora 23 and SUSE 13.2, there is no problem with NULL. 19 | // But on Fedora 22 and SUSE 13.1, we get an error that NULL is 20 | // undefined. Including stddef.h does not solve the problem - apparently 21 | // the dummy version in /usr/include/linux/i2c-dev.h is picked up. 22 | // This hack seems to solve that problem. 23 | 24 | #ifndef NULL 25 | #define NULL ((void*)0) 26 | #endif 27 | 28 | 29 | // On Fedora, i2c-dev.h is minimal. i2c.h is required for struct i2c_msg and 30 | // other stuff. On Ubuntu and SuSE, including both causes redefinition errors. 31 | // If I2C_FUNC_I2C is not defined, the definition is present in the full version 32 | // of i2c-dev.h but not in the abbreviated version, so i2c.h must be included. 33 | 34 | #include 35 | #ifndef I2C_FUNC_I2C 36 | #include 37 | #endif 38 | 39 | #endif /* WRAP_I2C_DEV_H_ */ 40 | -------------------------------------------------------------------------------- /src/libmain/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | -I$(top_srcdir)/src \ 4 | -I$(top_srcdir)/src/public 5 | 6 | AM_CFLAGS = $(AM_CFLAGS_STD) 7 | if WARNINGS_ARE_ERRORS_COND 8 | AM_CFLAGS += -Werror 9 | endif 10 | # AM_CFLAGS += -Wpedantic 11 | 12 | if ENABLE_CALLGRAPH_COND 13 | AM_CFLAGS += -fdump-rtl-expand 14 | endif 15 | 16 | CLEANFILES = \ 17 | *expand 18 | 19 | # Intermediate Library 20 | noinst_LTLIBRARIES = libsharedlib.la 21 | 22 | libsharedlib_la_SOURCES = \ 23 | api_base.c \ 24 | api_displays.c \ 25 | api_error_info_internal.c \ 26 | api_metadata.c \ 27 | api_feature_access.c \ 28 | api_capabilities.c \ 29 | api_services_internal.c 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/libmain/api_capabilities_internal.h: -------------------------------------------------------------------------------- 1 | /** @file api_capabilities_internal.h 2 | */ 3 | 4 | // Copyright (C) 2018-2025 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef API_CAPABILITIES_INTERNAL_H_ 8 | #define API_CAPABILITIES_INTERNAL_H_ 9 | 10 | #include "public/ddcutil_types.h" 11 | 12 | 13 | #ifdef UNUSED 14 | 15 | // 16 | // MCCS Version Id 17 | // 18 | 19 | /** \deprecated 20 | * Returns the symbolic name of a #DDCA_MCCS_Version_Id, 21 | * e.g. "DDCA_MCCS_V20." 22 | * 23 | * @param[in] version_id version id value 24 | * @return symbolic name (do not free) 25 | */ 26 | __attribute__ ((deprecated)) 27 | char * 28 | ddca_mccs_version_id_name( 29 | DDCA_MCCS_Version_Id version_id); 30 | 31 | /** \deprecated 32 | * Returns the descriptive name of a #DDCA_MCCS_Version_Id, 33 | * e.g. "2.0". 34 | * 35 | * @param[in] version_id version id value 36 | * @return descriptive name (do not free) 37 | * 38 | * @remark added to replace ddca_mccs_version_id_desc() during 0.9 39 | * development, but then use of DDCA_MCCS_Version_Id deprecated 40 | */ 41 | __attribute__ ((deprecated)) 42 | char * 43 | ddca_mccs_version_id_desc( 44 | DDCA_MCCS_Version_Id version_id) ; 45 | 46 | #endif 47 | 48 | void init_api_capabilities(); 49 | 50 | #endif /* API_CAPABILITIES_INTERNAL_H_ */ 51 | 52 | -------------------------------------------------------------------------------- /src/libmain/api_error_info_internal.h: -------------------------------------------------------------------------------- 1 | // api_error_info_internal.h 2 | 3 | // Copyright (C) 2021-2024 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef API_ERROR_INFO_INTERNAL_H_ 7 | #define API_ERROR_INFO_INTERNAL_H_ 8 | 9 | #include "ddcutil_types.h" 10 | 11 | #include "util/error_info.h" 12 | 13 | DDCA_Error_Detail * new_ddca_error_detail(DDCA_Status ddcrc, const char * format, ...); 14 | DDCA_Error_Detail * error_info_to_ddca_detail(Error_Info * erec); 15 | DDCA_Error_Detail * dup_error_detail(DDCA_Error_Detail * old); 16 | void free_error_detail(DDCA_Error_Detail * ddca_erec); 17 | void report_error_detail(DDCA_Error_Detail * ddca_erec, int depth); 18 | 19 | void free_thread_error_detail(); 20 | DDCA_Error_Detail * get_thread_error_detail(); 21 | void save_thread_error_detail(DDCA_Error_Detail * error_detail); 22 | 23 | #endif /* API_ERROR_INFO_INTERNAL_H_ */ 24 | -------------------------------------------------------------------------------- /src/libmain/api_feature_access_internal.h: -------------------------------------------------------------------------------- 1 | /** @file api_feature_access_internal.h 2 | * 3 | * Contains declarations of functions used only by other api_... files, 4 | * and of otherwise unpublished and archived functions. 5 | */ 6 | 7 | // Copyright (C) 2015-2023 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | #ifndef API_FEATURE_ACCESS_INTERNAL_H_ 11 | #define API_FEATURE_ACCESS_INTERNAL_H_ 12 | 13 | // here because there's no api_feature_access.h 14 | void init_api_feature_access(); 15 | 16 | #endif /* API_FEATURE_ACCESS_INTERNAL_H_ */ 17 | -------------------------------------------------------------------------------- /src/libmain/api_services_internal.c: -------------------------------------------------------------------------------- 1 | /** @file api_services_internal.c */ 2 | 3 | // Copyright (C) 2021-2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include 7 | 8 | #include "base/core.h" 9 | 10 | #include "api_capabilities_internal.h" 11 | #include "api_displays_internal.h" 12 | #include "api_feature_access_internal.h" 13 | #include "api_metadata_internal.h" 14 | 15 | #include "api_services_internal.h" 16 | 17 | 18 | void init_api_services() { 19 | init_api_capabilities(); 20 | init_api_displays(); 21 | init_api_feature_access(); 22 | init_api_metadata(); 23 | } 24 | -------------------------------------------------------------------------------- /src/libmain/api_services_internal.h: -------------------------------------------------------------------------------- 1 | // api_services_intenral.h 2 | 3 | // Copyright (C) 2021 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef API_SERVICES_INTERNAL_H_ 7 | #define API_SERVICES_INTERNAL_H_ 8 | 9 | void init_api_services(); 10 | 11 | #endif /* API_SERVICES_INTERNAL_H_ */ 12 | -------------------------------------------------------------------------------- /src/public/ddcutil_macros.h.in: -------------------------------------------------------------------------------- 1 | /** @file ddcutil_macros.h.in 2 | * 3 | * Macros for checking ddcutil version at compile time. 4 | * The Autotools build system converts this file to ddcutil.macros.h. 5 | * The version values are set from those in configure.ac. 6 | */ 7 | 8 | // Copyright (C) 2018-2021 Sanford Rockowitz 9 | // SPDX-License-Identifier: GPL-2.0-or-later 10 | 11 | 12 | #define DDCUTIL_VMAJOR @VERSION_VMAJOR@ 13 | #define DDCUTIL_VMINOR @VERSION_VMINOR@ 14 | #define DDCUTIL_VMICRO @VERSION_VMICRO@ 15 | #define DDCUTIL_VSUFFIX @VERSION_VSUFFIX@ 16 | 17 | -------------------------------------------------------------------------------- /src/sample_clients/Makefile.am: -------------------------------------------------------------------------------- 1 | # File src/sample_clients/Makefile.am 2 | # Makefile for sample and test programs for libddcutil 3 | 4 | AM_CPPFLAGS= \ 5 | -I$(srcdir) \ 6 | -I$(top_srcdir)/src/public \ 7 | -I$(top_srcdir)/src 8 | 9 | AM_CFLAGS = -Wall -fPIC 10 | # AM_CFLAGS += -Werror 11 | 12 | check_PROGRAMS = 13 | if ENABLE_SHARED_LIB_COND 14 | # Sample C client program for shared library: 15 | check_PROGRAMS += \ 16 | laclient \ 17 | demo_capabilities \ 18 | demo_display_selection \ 19 | demo_feature_list \ 20 | demo_get_set_vcp \ 21 | demo_global_settings \ 22 | demo_profile_features \ 23 | demo_redirection \ 24 | demo_vcpinfo 25 | endif 26 | 27 | laclient_SOURCES = clmain.c 28 | demo_capabilities_SOURCES = demo_capabilities.c 29 | demo_display_selection_SOURCES = demo_display_selection.c 30 | demo_feature_list_SOURCES = demo_feature_list.c 31 | demo_get_set_vcp_SOURCES = demo_get_set_vcp.c 32 | demo_global_settings_SOURCES = demo_global_settings.c 33 | demo_profile_features_SOURCES = demo_profile_features.c 34 | demo_redirection_SOURCES = demo_redirection.c 35 | demo_vcpinfo_SOURCES = demo_vcpinfo.c 36 | 37 | LDADD = ../libddcutil.la 38 | AM_LDFLAGS = -pie 39 | 40 | 41 | clean-local: 42 | @echo "(src/sample_clients/Makefile) clean-local" 43 | 44 | mostlyclean-local: 45 | @echo "(src/sample_clients/Makefile) mostlyclean-local" 46 | 47 | distclean-local: 48 | @echo "(src/sample_clients/Makefile) distclean-local" 49 | 50 | 51 | # Make this a dependency of something to enable it: 52 | show_vars: 53 | @echo "src/sample_clients/Makefile" 54 | @echo "srcdir: ${srcdir}" 55 | @echo "top_srcdir: ${top_srcdir}" 56 | 57 | .PHONY: show_vars 58 | 59 | -------------------------------------------------------------------------------- /src/sample_clients/demo_global_settings.c: -------------------------------------------------------------------------------- 1 | /** \file demo_global_settings.c 2 | * 3 | * Sample program illustrating the use of libddcutil's functions for 4 | * querying build information and global settings management. 5 | */ 6 | 7 | // Copyright (C) 2014-2023 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | #include 11 | #include 12 | 13 | #include "public/ddcutil_c_api.h" 14 | #include "public/ddcutil_status_codes.h" 15 | 16 | 17 | void demo_build_information() { 18 | printf("\nProbe static build information...\n"); 19 | 20 | // Get the ddcutil version as a string in the form "major.minor.micro". 21 | printf(" ddcutil version by ddca_ddcutil_version_string(): %s\n", ddca_ddcutil_version_string() ); 22 | 23 | // Get the ddcutil version as a struct of integers 24 | DDCA_Ddcutil_Version_Spec vspec = ddca_ddcutil_version(); 25 | printf(" ddcutil version by ddca_ddcutil_version(): %d.%d.%d\n", vspec.major, vspec.minor, vspec.micro); 26 | 27 | // Get build options 28 | uint8_t build_options = ddca_build_options(); 29 | printf(" Built with USB support: %s\n", (build_options & DDCA_BUILT_WITH_USB) ? "yes" : "no"); 30 | printf(" Built with failure simulation: %s\n", (build_options & DDCA_BUILT_WITH_FAILSIM) ? "yes" : "no"); 31 | } 32 | 33 | 34 | int main(int argc, char** argv) { 35 | demo_build_information(); 36 | } 37 | -------------------------------------------------------------------------------- /src/sample_clients/demo_redirection.c: -------------------------------------------------------------------------------- 1 | /** @file demo_redirection.c 2 | * 3 | * Sample program illustrating the use of libddcutil's functions for 4 | * redirecting and capturing program output. 5 | */ 6 | 7 | // Copyright (C) 2018-2024 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "public/ddcutil_c_api.h" 18 | 19 | 20 | void capture_output_using_convenience_functions() { 21 | printf("\nCapturing output using API convenience functions...\n"); 22 | 23 | ddca_start_capture(DDCA_CAPTURE_NOOPTS); 24 | int logical_indentation_depth = 1; 25 | ddca_report_displays(false, logical_indentation_depth); 26 | char * output = ddca_end_capture(); 27 | printf("Captured output:\n%s\n", output); 28 | free(output); 29 | } 30 | 31 | 32 | void capture_output_using_basic_functions() { 33 | printf("\nCapturing output to in core buffer using basic API functions..\n"); 34 | 35 | size_t size; 36 | char * ptr; 37 | // Alternatively, use fmemopen() to use a pre-allocated in-memory buffer 38 | // or fopen() to open a file. 39 | FILE * f = open_memstream(&ptr, &size); 40 | if (!f) { 41 | perror("Error opening file "); 42 | return; 43 | } 44 | 45 | ddca_set_fout(f); 46 | int logical_indentation_depth = 1; 47 | ddca_report_displays(false, logical_indentation_depth); 48 | // Ensure output actually written to FILE: 49 | int rc = fflush(f); 50 | if (rc < 0) { 51 | perror("fflush() failed"); 52 | return; 53 | } 54 | 55 | // size does not include trailing null appended by fmemopen() 56 | printf("Size after writing to buffer: %zd\n", size); 57 | ddca_set_fout_to_default(); 58 | // must copy data before closing buffer 59 | char * result = strdup(ptr); 60 | rc = fclose(f); 61 | if (rc < 0) { 62 | perror("Error closing in core buffer"); 63 | free(result); 64 | return; 65 | } 66 | 67 | printf("Output:\n"); 68 | printf("%s\n", result); 69 | free(result); 70 | } 71 | 72 | 73 | int main(int argc, char** argv) { 74 | capture_output_using_convenience_functions(); 75 | capture_output_using_basic_functions(); 76 | } 77 | -------------------------------------------------------------------------------- /src/sysfs/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | $(LIBDRM_CFLAGS) \ 4 | -I$(top_srcdir)/src \ 5 | -I$(top_srcdir)/src/public 6 | 7 | AM_CFLAGS = -Wall 8 | if WARNINGS_ARE_ERRORS_COND 9 | AM_CFLAGS += -Werror 10 | endif 11 | # AM_CFLAGS += -Wpedantic 12 | 13 | if ENABLE_CALLGRAPH_COND 14 | AM_CFLAGS += -fdump-rtl-expand 15 | endif 16 | 17 | CLEANFILES = \ 18 | *expand 19 | 20 | # Intermediate Library 21 | noinst_LTLIBRARIES = libsysfs.la 22 | 23 | libsysfs_la_SOURCES = \ 24 | sysfs_base.c \ 25 | sysfs_conflicting_drivers.c \ 26 | sysfs_dpms.c \ 27 | sysfs_i2c_info.c \ 28 | sysfs_i2c_sys_info.c \ 29 | sysfs_sys_drm_connector.c \ 30 | sysfs_top.c \ 31 | sysfs_services.c 32 | -------------------------------------------------------------------------------- /src/sysfs/sysfs_conflicting_drivers.h: -------------------------------------------------------------------------------- 1 | /** @file sysfs_conflicting_drivers.h */ 2 | 3 | // Copyright (C) 2020-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef SYSFS_CONFLICTING_DRIVERS_H_ 7 | #define SYSFS_CONFLICTING_DRIVERS_H_ 8 | 9 | #include 10 | 11 | #include "util/coredefs.h" 12 | 13 | typedef struct { 14 | int i2c_busno; 15 | char * n_nnnn; 16 | char * name; // n_nnnn/name 17 | char * driver_module; // basename(realpath(n_nnnn/driver/module)) 18 | char * modalias; // n_nnnn/modalias 19 | Byte * eeprom_edid_bytes; 20 | gsize eeprom_edid_size; 21 | } Sys_Conflicting_Driver; 22 | 23 | GPtrArray * collect_conflicting_drivers(int busno, int depth); 24 | GPtrArray * collect_conflicting_drivers_for_any_bus(int depth); 25 | void report_conflicting_drivers(GPtrArray * conflicts, int depth); // for a single busno 26 | void free_conflicting_drivers(GPtrArray* conflicts); 27 | GPtrArray * conflicting_driver_names(GPtrArray * conflicts); 28 | char * conflicting_driver_names_string_t(GPtrArray * conflicts); 29 | void init_i2c_sysfs_conflicting_drivers(); 30 | 31 | #endif /* SYSFS_CONFLICTING_DRIVERS_H_ */ 32 | -------------------------------------------------------------------------------- /src/sysfs/sysfs_dpms.h: -------------------------------------------------------------------------------- 1 | /** @file sysfs_dpms.h 2 | * DPMS related functions 3 | */ 4 | 5 | // Copyright (C) 2023-2025 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef SYSFS_DPMS_H_ 9 | #define SYSFS_DPMS_H_ 10 | 11 | #include 12 | 13 | #include "config.h" 14 | 15 | #include "base/displays.h" 16 | #include "base/i2c_bus_base.h" 17 | 18 | // DPMS Detection 19 | #ifdef USE_X11 20 | #define DPMS_STATE_X11_CHECKED 0x01 21 | #define DPMS_STATE_X11_ASLEEP 0x02 22 | #endif 23 | #define DPMS_SOME_DRM_ASLEEP 0x04 24 | #define DPMS_ALL_DRM_ASLEEP 0x08 25 | typedef Byte Dpms_State; 26 | 27 | extern Dpms_State dpms_state; 28 | 29 | char * interpret_dpms_state_t(Dpms_State state); 30 | bool dpms_is_x11_asleep(); 31 | bool dpms_check_drm_asleep_by_connector(const char * drm_connector_name); 32 | bool dpms_check_drm_asleep_by_businfo(I2C_Bus_Info * businfo); 33 | bool dpms_check_drm_asleep_by_dref(Display_Ref * dref); 34 | void init_sysfs_dpms(); 35 | 36 | #endif /* SYSFS_DPMS_H_ */ 37 | -------------------------------------------------------------------------------- /src/sysfs/sysfs_i2c_info.h: -------------------------------------------------------------------------------- 1 | /** @file sysfs_i2c_info.h */ 2 | 3 | // Copyright (C) 2020-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef SYSFS_I2C_INFO_H_ 7 | #define SYSFS_I2C_INFO_H_ 8 | 9 | #include 10 | 11 | #include "util/data_structures.h" 12 | 13 | typedef struct { 14 | int busno; 15 | char * name; 16 | char * adapter_path; 17 | char * adapter_class; 18 | char * driver; 19 | char * driver_version; 20 | GPtrArray * conflicting_driver_names; 21 | } Sysfs_I2C_Info; 22 | 23 | void free_sysfs_i2c_info(Sysfs_I2C_Info * info); 24 | Sysfs_I2C_Info * get_i2c_driver_info(int busno, int depth); 25 | Sysfs_I2C_Info * get_basic_i2c_driver_info(int busno); 26 | GPtrArray * get_all_sysfs_i2c_info(bool rescan, int depth); 27 | void dbgrpt_sysfs_i2c_info(Sysfs_I2C_Info * info, int depth); 28 | void dbgrpt_all_sysfs_i2c_info(GPtrArray * infos, int depth); 29 | #ifdef UNUSED 30 | char * get_conflicting_drivers_for_bus(int busno); 31 | #endif 32 | Bit_Set_256 get_possible_ddc_ci_bus_numbers_using_sysfs_i2c_info(); 33 | void init_i2c_sysfs_i2c_info(); 34 | void terminate_i2c_sysfs_i2c_info(); 35 | 36 | #endif /* SYSFS_I2C_INFO_H_ */ 37 | -------------------------------------------------------------------------------- /src/sysfs/sysfs_i2c_sys_info.h: -------------------------------------------------------------------------------- 1 | /** @file sysfs_i2c_sys_info.h */ 2 | 3 | // Copyright (C) 2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef SYSFS_SYS_INFO_H_ 7 | #define SYSFS_SYS_INFO_H_ 8 | 9 | #include "util/data_structures.h" 10 | 11 | typedef struct { 12 | int busno; 13 | bool is_amdgpu_display_port; 14 | char * pci_device_path; 15 | char * drm_connector_path; 16 | char * connector; 17 | char * ddc_path; 18 | char * linked_ddc_filename; 19 | char * device_name; 20 | char * drm_dp_aux_name; 21 | char * drm_dp_aux_dev; 22 | char * i2c_dev_name; 23 | char * i2c_dev_dev; 24 | char * driver; 25 | char * ddc_name; 26 | char * ddc_i2c_dev_name; 27 | char * ddc_i2c_dev_dev; 28 | } I2C_Sys_Info; 29 | 30 | #ifdef FUTURE 31 | // In progress: Simplified I2C_Sys_Info for production as opposed to exploratory use 32 | typedef struct { 33 | char * pci_device_path; 34 | char * driver; 35 | char * connector; 36 | char * drm_connector_path; 37 | char * device_name; 38 | int busno; 39 | } I2C_Fixed_Sys_Info; 40 | #endif 41 | 42 | 43 | // WAS used in i2c_dbgrpt_bus_info() in i2c_bus_base.c: ELIMINATED 44 | // get_i2c_sys_info(), free_i2c_sys_info(), dbgrpt_i2c_sys_info() 45 | // used in query_sysenv_sysfs.c: dbgrpt_sys_bus_i2c 46 | 47 | I2C_Sys_Info * get_i2c_sys_info(int busno, int depth); 48 | void free_i2c_sys_info(I2C_Sys_Info * info); 49 | void dbgrpt_i2c_sys_info(I2C_Sys_Info * info, int depth); 50 | void dbgrpt_sys_bus_i2c(int depth); 51 | 52 | void init_i2c_sysfs_i2c_sys_info(); 53 | 54 | #endif /* I2C_SYSFS_I2C_SYS_INFO_H_ */ 55 | -------------------------------------------------------------------------------- /src/sysfs/sysfs_services.c: -------------------------------------------------------------------------------- 1 | /** @file sysfs_services.c */ 2 | 3 | // Copyright (C) 2022-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include "sysfs/sysfs_base.h" 7 | #include "sysfs/sysfs_conflicting_drivers.h" 8 | #include "sysfs/sysfs_dpms.h" 9 | #include "sysfs/sysfs_i2c_sys_info.h" 10 | #include "sysfs/sysfs_sys_drm_connector.h" 11 | #include "sysfs/sysfs_i2c_info.h" 12 | 13 | #include "sysfs_services.h" 14 | 15 | /** Master initializer for directory sysfs */ 16 | void init_sysfs_services() { 17 | init_sysfs_dpms(); 18 | init_sysfs_sys_drm_connector(); 19 | init_i2c_sysfs_i2c_sys_info(); 20 | init_i2c_sysfs_base(); 21 | init_i2c_sysfs_conflicting_drivers(); 22 | init_i2c_sysfs_i2c_info(); 23 | } 24 | 25 | void terminate_sysfs_services() { 26 | terminate_i2c_sysfs_i2c_info(); 27 | } 28 | -------------------------------------------------------------------------------- /src/sysfs/sysfs_services.h: -------------------------------------------------------------------------------- 1 | /* @file sysfs_services.h 2 | */ 3 | 4 | // Copyright (C) 2022-2025 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef SYSFS_SERVICES_H_ 8 | #define SYSFS_SERVICES_H_ 9 | 10 | void init_sysfs_services(); 11 | void terminate_sysfs_services(); 12 | 13 | #endif /* SYSFS_SERVICES_H_ */ 14 | -------------------------------------------------------------------------------- /src/sysfs/sysfs_top.c: -------------------------------------------------------------------------------- 1 | /** @file sysfs_top.c */ 2 | 3 | // Copyright (C) 2020-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include 7 | 8 | #include "util/data_structures.h" 9 | #include "util/report_util.h" 10 | 11 | #include "sysfs_conflicting_drivers.h" 12 | #include "sysfs_i2c_info.h" 13 | #include "sysfs_sys_drm_connector.h" 14 | 15 | #include "sysfs_top.h" 16 | 17 | 18 | void consolidated_i2c_sysfs_report(int depth) { 19 | int d0 = depth; 20 | int d1 = depth+1; 21 | 22 | rpt_label(d0, "*** Sys_Drm_Connector report: Detailed /sys/class/drm report: ***"); 23 | report_sys_drm_connectors(true, d1); 24 | rpt_nl(); 25 | 26 | // not currently used, and leaks memory 27 | // rpt_label(d0, "*** Sys_Drm_Connector_FixedInfo report: Simplified /sys/class/drm report: ***"); 28 | // report_sys_drm_connectors_fixedinfo(d1); 29 | // rpt_nl(); 30 | 31 | rpt_label(d0, "*** Sysfs_I2C_Info report ***"); 32 | GPtrArray * reports = get_all_sysfs_i2c_info(true, -1); 33 | dbgrpt_all_sysfs_i2c_info(reports, d1); 34 | rpt_nl(); 35 | 36 | rpt_label(d0, "*** Sysfs I2C devices possibly associated with displays ***"); 37 | Bit_Set_256 buses = get_possible_ddc_ci_bus_numbers_using_sysfs_i2c_info(); 38 | rpt_vstring(d0, "I2C buses to check: %s", bs256_to_string_t(buses, "x", " ")); 39 | rpt_nl(); 40 | 41 | rpt_label(d0, "*** Sys_Conflicting_Driver report: Check for Conflicting Device Drivers ***"); 42 | GPtrArray * conflicts = collect_conflicting_drivers_for_any_bus(-1); 43 | if (conflicts && conflicts->len > 0) { 44 | report_conflicting_drivers(conflicts, d1); 45 | rpt_vstring(d1, "Likely conflicting drivers found: %s\n", conflicting_driver_names_string_t(conflicts)); 46 | } 47 | else 48 | rpt_label(d1, "No conflicting drivers found"); 49 | free_conflicting_drivers(conflicts); 50 | rpt_nl(); 51 | 52 | rpt_label(0, "*** Sysfs Reports Done ***"); 53 | rpt_nl(); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/sysfs/sysfs_top.h: -------------------------------------------------------------------------------- 1 | /** @file sysfs_top.h */ 2 | 3 | // Copyright (C) 2024-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef SYSFS_TOP_H_ 7 | #define SYSFS_TOP_H_ 8 | 9 | void consolidated_i2c_sysfs_report(int depth); 10 | 11 | #endif /* SYSFS_TOP_H_ */ 12 | -------------------------------------------------------------------------------- /src/test/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | -I$(top_srcdir) \ 4 | -I$(top_srcdir)/src \ 5 | -I$(top_srcdir)/src/public 6 | 7 | AM_CFLAGS = -Wall -Werror 8 | 9 | CLEANFILES = \ 10 | *expand 11 | 12 | 13 | # Intermediate library 14 | noinst_LTLIBRARIES = libtestcases.la 15 | 16 | if INCLUDE_TESTCASES_COND 17 | libtestcases_la_SOURCES = \ 18 | i2c/i2c_testutil.c \ 19 | testcase_table.c \ 20 | testcases.c 21 | else 22 | libtestcases_la_SOURCES = \ 23 | testcase_mock_table.c 24 | endif 25 | -------------------------------------------------------------------------------- /src/test/i2c/i2c_testutil.h: -------------------------------------------------------------------------------- 1 | // i2c_testutil.h 2 | 3 | // Copyright (C) 2014-2018 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include 7 | 8 | 9 | #ifndef I2C_TESTUTIL_H_ 10 | #define I2C_TESTUTIL_H_ 11 | 12 | bool i2c_verify_functions_supported(int busno, char * write_func_name, char * read_func_name); 13 | 14 | 15 | #endif /* I2C_TESTUTIL_H_ */ 16 | -------------------------------------------------------------------------------- /src/test/testcase_mock_table.c: -------------------------------------------------------------------------------- 1 | /* testcase_mock_table.c 2 | * 3 | * 4 | * Copyright (C) 2014-2016 Sanford Rockowitz 5 | * 6 | * Licensed under the GNU General Public License Version 2 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | * 22 | */ 23 | 24 | #include "testcase_table.h" 25 | 26 | Testcase_Descriptor testcase_catalog[] = {}; 27 | int testcase_catalog_ct = sizeof(testcase_catalog)/sizeof(Testcase_Descriptor); 28 | -------------------------------------------------------------------------------- /src/test/testcase_table.c: -------------------------------------------------------------------------------- 1 | /* testcase_table.c 2 | * 3 | * 4 | * Copyright (C) 2014-2022 Sanford Rockowitz 5 | * 6 | * Licensed under the GNU General Public License Version 2 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | * 22 | */ 23 | 24 | #include "config.h" 25 | 26 | #include "testcase_table.h" 27 | 28 | Testcase_Descriptor testcase_catalog[] = { 29 | // {"get_luminosity_sample_code", DisplayRefBus, NULL, get_luminosity_sample_code, NULL, NULL}, 30 | // {"demo_p2411_problem", DisplayRefBus, NULL, demo_p2411_problem, NULL, NULL} 31 | }; 32 | int testcase_catalog_ct = sizeof(testcase_catalog)/sizeof(Testcase_Descriptor); 33 | 34 | -------------------------------------------------------------------------------- /src/test/testcase_table.h: -------------------------------------------------------------------------------- 1 | /* testcase_table.h 2 | * 3 | * 4 | * Copyright (C) 2014-2016 Sanford Rockowitz 5 | * 6 | * Licensed under the GNU General Public License Version 2 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | * 22 | */ 23 | 24 | #ifndef TESTCASE_TABLE_H_ 25 | #define TESTCASE_TABLE_H_ 26 | 27 | #include "base/displays.h" 28 | 29 | // type of display reference required/supported by the command 30 | typedef enum {DisplayRefNone, DisplayRefAny, DisplayRefBus, DisplayRefAdl} DisplayRefType; 31 | 32 | typedef void (*NoArgFunction)(); 33 | typedef void (*BusArgFunction)(int busno); 34 | typedef void (*AdlArgFunction)(int iAdapterIndex, int iDisplayIndex); 35 | typedef void (*DisplayRefArgFunction)(Display_Ref * dref); 36 | 37 | typedef 38 | struct { 39 | char * name; // testcase description 40 | DisplayRefType drefType; 41 | // should really be a union 42 | NoArgFunction fp_noarg; 43 | BusArgFunction fp_bus; 44 | AdlArgFunction fp_adl; 45 | DisplayRefArgFunction fp_dr; 46 | } Testcase_Descriptor; 47 | 48 | extern Testcase_Descriptor testcase_catalog[]; 49 | extern int testcase_catalog_ct; 50 | 51 | // Testcase_Descriptor ** get_testcase_catalog(); 52 | // int get_testcase_catalog_ct(); 53 | 54 | #endif /* TESTCASE_TABLE_H_ */ 55 | -------------------------------------------------------------------------------- /src/test/testcases.h: -------------------------------------------------------------------------------- 1 | /* testcases.h 2 | * 3 | * Manages test cases 4 | * 5 | * 6 | * Copyright (C) 2014-2016 Sanford Rockowitz 7 | * 8 | * Licensed under the GNU General Public License Version 2 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 23 | * 24 | */ 25 | 26 | #ifndef TESTCASES_H_ 27 | #define TESTCASES_H_ 28 | 29 | #include 30 | 31 | #include 32 | 33 | void show_test_cases(); 34 | bool execute_testcase(int testnum, Display_Identifier* pdid); 35 | 36 | #endif /* TESTCASES_H_ */ 37 | -------------------------------------------------------------------------------- /src/usb/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | -I$(top_srcdir) \ 4 | -I$(top_srcdir)/src \ 5 | -I$(top_srcdir)/src/public 6 | 7 | AM_CFLAGS = $(AM_CFLAGS_STD) 8 | 9 | CLEANFILES = \ 10 | *expand 11 | 12 | clean-local: 13 | @echo "(src/usb/Makefile) clean-local" 14 | 15 | mostlyclean-local: 16 | @echo "(src/usb/Makefile) mostlyclean-local" 17 | 18 | 19 | distclean-local: 20 | @echo "(src/usb/Makefile) distclean-local" 21 | 22 | 23 | dist-hook: 24 | @echo "(src/usb/Makefile) dist-hook. top_distdir=$(top_distdir) distdir=$(distdir)" 25 | find $(distdir) -name "*.o" 26 | find $(distdir) -name "*.lo" 27 | 28 | 29 | if ENABLE_USB_COND 30 | # Intermediate library 31 | noinst_LTLIBRARIES = libusb.la 32 | 33 | libusb_la_SOURCES = \ 34 | usb_base.c \ 35 | usb_displays.c \ 36 | usb_edid.c \ 37 | usb_services.c \ 38 | usb_vcp.c 39 | endif 40 | -------------------------------------------------------------------------------- /src/usb/usb_displays.h: -------------------------------------------------------------------------------- 1 | /** @file usb_displays.h 2 | */ 3 | 4 | // Copyright (C) 2016-2024 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef USB_DISPLAYS_H_ 8 | #define USB_DISPLAYS_H_ 9 | 10 | /** \cond */ 11 | #include 12 | #include // for __u32 13 | /** \endcond */ 14 | 15 | #include "util/coredefs.h" 16 | 17 | #include "base/core.h" 18 | #include "base/display_lock.h" 19 | #include "base/displays.h" 20 | #include "base/ddc_packets.h" 21 | #ifdef ALT_DISPLAY_LOCK 22 | #include "base/display_lock.h" 23 | #endif 24 | 25 | #include "vcp/vcp_feature_values.h" 26 | 27 | #include "usb/usb_base.h" 28 | 29 | 30 | bool check_usb_monitor( char * device_name ); 31 | 32 | #ifdef OLD 33 | Display_Info_List usb_get_valid_displays(); 34 | #endif 35 | 36 | bool usb_is_valid_display_ref( Display_Ref * dref, bool emit_error_msg); 37 | void usb_show_active_display_by_dref( Display_Ref * dref, int depth); 38 | Parsed_Edid * usb_get_parsed_edid_by_dref( Display_Ref * dref); 39 | Parsed_Edid * usb_get_parsed_edid_by_dh( Display_Handle * dh); 40 | char * usb_get_capabilities_string_by_dh(Display_Handle * dh); 41 | 42 | // struct defs here for sharing with usb_vcp 43 | 44 | /* Used to record hiddev settings for reading and 45 | * writing a VCP feature code 46 | */ 47 | #define USB_MONITOR_VCP_REC_MARKER "UMVR" 48 | typedef struct usb_monitor_vcp_rec { 49 | char marker[4]; 50 | Byte vcp_code; 51 | __u32 report_type; // type? 52 | // have both indexes and struct pointers - redundant 53 | int report_id; 54 | int field_index; 55 | int usage_index; 56 | struct hiddev_report_info * rinfo; 57 | struct hiddev_field_info * finfo; 58 | struct hiddev_usage_ref * uref; 59 | } Usb_Monitor_Vcp_Rec; 60 | 61 | 62 | void dbgrpt_usb_monitor_info(Usb_Monitor_Info * moninfo, int depth); 63 | Usb_Monitor_Info * 64 | usb_find_monitor_by_dh(Display_Handle * dh); 65 | bool is_possible_monitor_by_hiddev_name(const char * hiddev_name); 66 | GPtrArray * get_usb_monitor_list(); 67 | GPtrArray * get_usb_open_errors(); 68 | void discard_usb_monitor_list(); 69 | void init_usb_displays(); 70 | void terminate_usb_displays(); 71 | 72 | #endif /* USB_DISPLAYS_H_ */ 73 | -------------------------------------------------------------------------------- /src/usb/usb_edid.h: -------------------------------------------------------------------------------- 1 | /** @file usb_edid.h 2 | * 3 | * Functions to get EDID for USB connected monitors 4 | */ 5 | 6 | // Copyright (C) 2014-2023 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef USB_EDID_H_ 10 | #define USB_EDID_H_ 11 | 12 | #include 13 | 14 | #include "util/edid.h" 15 | 16 | Parsed_Edid * get_hiddev_edid_with_fallback(int fd, struct hiddev_devinfo * dev_info); 17 | 18 | void init_usb_edid(); 19 | 20 | #endif /* USB_EDID_H_ */ 21 | -------------------------------------------------------------------------------- /src/usb/usb_services.c: -------------------------------------------------------------------------------- 1 | /** @file usb_services.c */ 2 | 3 | // Copyright (C) 2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #include "usb_base.h" 7 | #include "usb_displays.h" 8 | #include "usb_edid.h" 9 | 10 | #include "usb_services.h" 11 | 12 | void init_usb_services() { 13 | init_usb_base(); 14 | init_usb_displays(); 15 | init_usb_edid(); 16 | } 17 | 18 | void terminate_usb_services() { 19 | // terminate_usb_displays(); // already called from termindate_ddc_services 20 | terminate_usb_base(); 21 | } 22 | -------------------------------------------------------------------------------- /src/usb/usb_services.h: -------------------------------------------------------------------------------- 1 | /** @file usb_services.h */ 2 | 3 | // Copyright (C) 2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef USB_SERVICES_H_ 7 | #define USB_SERVICES_H_ 8 | 9 | void init_usb_services(); 10 | void terminate_usb_services(); 11 | 12 | #endif /* USB_SERVICES_H_ */ 13 | -------------------------------------------------------------------------------- /src/usb/usb_vcp.h: -------------------------------------------------------------------------------- 1 | /* \file usb_vcp.h 2 | * 3 | * Get and set VCP feature codes for USB connected monitors. 4 | */ 5 | 6 | // Copyright (C) 2016-2018 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef USB_VCP_H_ 10 | #define USB_VCP_H_ 11 | 12 | #include 13 | 14 | #include "ddcutil_types.h" 15 | 16 | #include "util/coredefs.h" 17 | 18 | #include "base/displays.h" 19 | #include "base/ddc_packets.h" 20 | 21 | #include "vcp/vcp_feature_values.h" 22 | 23 | 24 | Public_Status_Code 25 | usb_get_usage_value_by_report_type_and_ucode( 26 | int fd, 27 | __u32 report_type, 28 | __u32 usage_code, 29 | __s32 * maxval, 30 | __s32 * curval); 31 | 32 | Public_Status_Code usb_get_nontable_vcp_value( 33 | Display_Handle * dh, 34 | Byte feature_code, 35 | Parsed_Nontable_Vcp_Response** ppInterpretedCode); 36 | 37 | Public_Status_Code usb_get_vcp_value( 38 | Display_Handle * dh, 39 | Byte feature_code, 40 | DDCA_Vcp_Value_Type call_type, 41 | DDCA_Any_Vcp_Value ** pvalrec); 42 | 43 | Public_Status_Code usb_set_nontable_vcp_value( 44 | Display_Handle * dh, 45 | Byte feature_code, 46 | int new_value); 47 | 48 | Public_Status_Code usb_set_vcp_value( 49 | Display_Handle * dh, 50 | DDCA_Any_Vcp_Value * pvalrec); 51 | 52 | __s32 usb_get_vesa_version(int fd); 53 | 54 | #endif /* USB_VCP_H_ */ 55 | -------------------------------------------------------------------------------- /src/usb_util/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | -I$(top_srcdir)/src 4 | 5 | 6 | AM_CFLAGS = $(AM_CFLAGS_STD) 7 | 8 | # lots of arguments for %p in format strings need (void*) casts if -Wpedantic 9 | # AM_CFLAGS += -Wpedantic 10 | 11 | 12 | CLEANFILES = \ 13 | *expand 14 | 15 | clean-local: 16 | @echo "(src/usbutil/Makefile) clean-local" 17 | 18 | mostlyclean-local: 19 | @echo "(src/usbutil/Makefile) mostlyclean-local" 20 | 21 | 22 | distclean-local: 23 | @echo "(src/usbutil/Makefile) distclean-local" 24 | 25 | # The dist-hook find statements here find nothing, but the corresponding 26 | # statements in src/Makefile.am do. why? 27 | 28 | dist-hook: 29 | @echo "(src/usbutil/Makefile) dist-hook. top_distdir=$(top_distdir) distdir=$(distdir)" 30 | find $(distdir) -name "*.o" 31 | find $(distdir) -name "*.lo" 32 | 33 | 34 | if ENABLE_USB_COND 35 | # Intermediate Libraries 36 | 37 | noinst_LTLIBRARIES = libusbutil.la 38 | 39 | libusbutil_la_SOURCES = \ 40 | usb_hid_common.c \ 41 | hiddev_reports.c \ 42 | hiddev_util.c \ 43 | hidraw_util.c \ 44 | libusb_reports.c \ 45 | libusb_util.c \ 46 | base_hid_report_descriptor.c \ 47 | hid_report_descriptor.c 48 | 49 | 50 | endif 51 | 52 | -------------------------------------------------------------------------------- /src/usb_util/base_hid_report_descriptor.h: -------------------------------------------------------------------------------- 1 | /* base_hid_report_descriptor.h 2 | * 3 | * Functions to perform basic parsing of the HID Report Descriptor and 4 | * display the contents of the Report Descriptor in the format used 5 | * in HID documentation. 6 | * 7 | * 8 | * Copyright (C) 2016 Sanford Rockowitz 9 | * 10 | * Licensed under the GNU General Public License Version 2 11 | * 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program; if not, write to the Free Software 24 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 | * 26 | */ 27 | 28 | #ifndef BASE_HID_REPORT_DESCRIPTOR_H_ 29 | #define BASE_HID_REPORT_DESCRIPTOR_H_ 30 | 31 | #include 32 | 33 | #include "util/coredefs.h" 34 | 35 | typedef struct hid_report_item { 36 | struct hid_report_item * next; 37 | 38 | Byte raw_bytes[5]; 39 | Byte btype; // 0=Main, 1=Global, 2=Local, prefix bits 2-3 40 | Byte btag; 41 | Byte bsize_bytect; // number of bytes, as opposed to indicator, i.e 4 means 4 bytes 42 | uint32_t data; 43 | 44 | // alternative, as done in struct hid_item in kernel header file hid.h: 45 | union { 46 | uint8_t u8; 47 | int8_t s8; 48 | uint16_t u16; 49 | int8_t s16; 50 | uint32_t u32; 51 | int32_t s32; 52 | uint8_t *longdata; 53 | } data_alt; 54 | 55 | } Hid_Report_Descriptor_Item; 56 | 57 | void report_hid_report_item_list(Hid_Report_Descriptor_Item * head, int depth); 58 | void free_hid_report_item_list(Hid_Report_Descriptor_Item * head); 59 | Hid_Report_Descriptor_Item * tokenize_hid_report_descriptor(Byte * b, int l) ; 60 | bool is_monitor_by_tokenized_hid_report_descriptor(Hid_Report_Descriptor_Item * report_item_list); 61 | 62 | #endif /* BASE_HID_REPORT_DESCRIPTOR_H_ */ 63 | -------------------------------------------------------------------------------- /src/usb_util/hiddev_reports.h: -------------------------------------------------------------------------------- 1 | /** @file hiddev_reports.h 2 | */ 3 | 4 | // Copyright (C) 2016-2019 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | 8 | #ifndef HIDDEV_REPORTS_H_ 9 | #define HIDDEV_REPORTS_H_ 10 | 11 | #include 12 | #include 13 | 14 | void init_hiddev_reports(); 15 | 16 | void dbgrpt_hiddev_devinfo(struct hiddev_devinfo * devinfo, bool lookup_names, int depth); 17 | void dbgrpt_hiddev_device_by_fd(int fd, int depth); 18 | 19 | void dbgrpt_hiddev_usage_ref(struct hiddev_usage_ref * uref, int depth); 20 | void dbgrpt_hiddev_usage_ref_multi(struct hiddev_usage_ref_multi * uref_multi, int depth); 21 | 22 | void dbgrpt_hiddev_report_info(struct hiddev_report_info * rinfo, int depth); 23 | void dbgrpt_hiddev_field_info(struct hiddev_field_info * finfo, int depth); 24 | 25 | char * hiddev_interpret_report_id(__u32 report_id); 26 | 27 | char * hiddev_interpret_usage_code(int usage_code ); 28 | 29 | #endif /* UTIL_HIDDEV_REPORTS_H_ */ 30 | -------------------------------------------------------------------------------- /src/usb_util/hidraw_util.h: -------------------------------------------------------------------------------- 1 | /* hidraw_util.h 2 | * 3 | * 4 | * 5 | * Copyright (C) 2016 Sanford Rockowitz 6 | * 7 | * Licensed under the GNU General Public License Version 2 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 | * 23 | */ 24 | 25 | #ifndef HIDRAW_UTIL_H_ 26 | #define HIDRAW_UTIL_H_ 27 | 28 | void probe_hidraw(bool show_monitors_only, int depth); 29 | 30 | bool hidraw_is_monitor_device(char * devname); 31 | 32 | #endif /* _HIDRAW_UTIL_H_ */ 33 | -------------------------------------------------------------------------------- /src/usb_util/libusb_util.h: -------------------------------------------------------------------------------- 1 | /** @file libusb_util.h 2 | */ 3 | 4 | // Copyright (C) 2014-2019 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef LIBUSB_UTIL_H_ 8 | #define LIBUSB_UTIL_H_ 9 | 10 | #include 11 | #include 12 | // #include 13 | 14 | #include "usb_util/libusb_reports.h" 15 | 16 | 17 | char *make_path(int bus_number, int device_address, int interface_number); 18 | char *make_path_from_libusb_device(libusb_device *dev, int interface_number); 19 | 20 | // bool possible_monitor_dev(libusb_device * dev, bool check_forced_monitor); 21 | 22 | // singly linked list of possible monitors 23 | typedef 24 | struct possible_monitor_device { 25 | libusb_device * libusb_device; 26 | int bus; 27 | int device_address; 28 | int alt_setting; 29 | int interface; 30 | gushort vid; 31 | gushort pid; 32 | char * manufacturer_name; 33 | char * product_name; 34 | // conversion is annoying, just retrieve both ascii and wchar version of the serial number 35 | // wchar_t * serial_number_wide; 36 | char * serial_number; // retrieved as ASCII, note some usages expect wchar 37 | struct possible_monitor_device * next; 38 | } Possible_Monitor_Device; 39 | 40 | struct possible_monitor_device * get_possible_monitors(); 41 | 42 | void report_possible_monitors(struct possible_monitor_device * mondev_head, int depth); 43 | 44 | #ifdef UNTESTED 45 | void free_possible_monitor_device_list(struct possible_monitor_device * head); 46 | #endif 47 | 48 | void probe_libusb(bool possible_monitors_only,int depth); 49 | 50 | bool libusb_is_monitor_by_path(gushort busno, gushort devno, gushort intfno); 51 | 52 | #endif /* LIBUSB_UTIL_H_ */ 53 | -------------------------------------------------------------------------------- /src/usb_util/usb_hid_common.h: -------------------------------------------------------------------------------- 1 | /** @file usb_hid_common.h 2 | * 3 | * Functions that are common to the wrappers for multiple USB HID 4 | * packages such as libusb, hiddev 5 | */ 6 | 7 | // Copyright (C) 2014-2019 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | #ifndef USB_HID_COMMON_H_ 11 | #define USB_HID_COMMON_H_ 12 | 13 | /** \cond */ 14 | #include 15 | #include 16 | /** \endcond */ 17 | 18 | const char * collection_type_name(uint8_t collection_type); 19 | 20 | bool force_hid_monitor_by_vid_pid(int16_t vid, int16_t pid); 21 | bool deny_hid_monitor_by_vid_pid(int16_t vid, int16_t pid); 22 | 23 | #endif /* USB_HID_COMMON_H_ */ 24 | -------------------------------------------------------------------------------- /src/util/backtrace.h: -------------------------------------------------------------------------------- 1 | /** @file backtrace.h */ 2 | 3 | // Copyright (C) 2016-2024 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef BACKTRACE_H_ 7 | #define BACKTRACE_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | 15 | GPtrArray * get_backtrace(int stack_adjust); 16 | void backtrace_to_syslog(int priority, int stack_adjust); 17 | 18 | #ifdef __cplusplus 19 | } // extern "C" 20 | #endif 21 | 22 | #endif /* BACKTRACE_H_ */ 23 | -------------------------------------------------------------------------------- /src/util/common_inlines.h: -------------------------------------------------------------------------------- 1 | /** @file common_inlines.h */ 2 | 3 | // Copyright (C) 2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef COMMON_INLINES_H_ 7 | #define COMMON_INLINES_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | 16 | // TODO: merge tid(), pid() with linux_errno.c/h 17 | 18 | static inline pid_t tid() { 19 | static __thread pid_t thread_id2; 20 | if (!thread_id2) 21 | thread_id2 = syscall(SYS_gettid); 22 | return thread_id2; 23 | } 24 | 25 | #define TID() (intmax_t) tid() 26 | 27 | static inline pid_t pid() { 28 | static __thread pid_t process_id; 29 | if (!process_id) 30 | process_id = syscall(SYS_gettid); 31 | return process_id; 32 | } 33 | 34 | #define PID() (intmax_t) pid() 35 | 36 | #ifdef __cplusplus 37 | } // extern "C" 38 | #endif 39 | 40 | #endif /* COMMON_INLINES_H_ */ 41 | -------------------------------------------------------------------------------- /src/util/common_printf_formats.h: -------------------------------------------------------------------------------- 1 | /** @file common_printf_formats.h */ 2 | 3 | // Copyright (C) 2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef COMMON_PRINTF_FORMATS_H_ 7 | #define COMMON_PRINTF_FORMATS_H_ 8 | 9 | #define PRItid "[%6jd]" 10 | 11 | #endif /* COMMON_PRINTF_FORMATS_H_ */ 12 | -------------------------------------------------------------------------------- /src/util/coredefs.h: -------------------------------------------------------------------------------- 1 | /** @file coredefs.h 2 | * Basic definitions that are not application specific 3 | */ 4 | 5 | // Copyright (C) 2014-2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | 9 | #ifndef COREDEFS_H_ 10 | #define COREDEFS_H_ 11 | 12 | #include // for MIN() 13 | #include // for memcpy(), strlen() 14 | 15 | #include "coredefs_base.h" // shared with ddcui 16 | 17 | 18 | #endif /* COREDEFS_H_ */ 19 | -------------------------------------------------------------------------------- /src/util/ddcutil_config_file.h: -------------------------------------------------------------------------------- 1 | /** @file ddcutil_config_file.h */ 2 | 3 | // Copyright (C) 2021-2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DDCUTIL_CONFIG_FILE_H_ 7 | #define DDCUTIL_CONFIG_FILE_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | 15 | #include "error_info.h" 16 | 17 | int tokenize_options_line( 18 | const char * string, 19 | char *** tokens_loc); 20 | 21 | int read_ddcutil_config_file( 22 | const char * ddcutil_application, 23 | char ** config_fn_loc, 24 | char ** untokenized_option_string_loc, 25 | GPtrArray * errmsgs); 26 | 27 | int apply_config_file( 28 | const char * ddcutil_application, // "ddcutil", "ddcui", "libddcutil" 29 | int old_argc, 30 | char ** old_argv, 31 | int * new_argc_loc, 32 | char *** new_argv_loc, 33 | char ** untokenized_option_string_loc, 34 | char ** configure_fn_loc, 35 | GPtrArray * errmsgs); 36 | 37 | #ifdef __cplusplus 38 | } // extern "C" 39 | #endif 40 | 41 | #endif /* DDCUTIL_CONFIG_FILE_H_ */ 42 | -------------------------------------------------------------------------------- /src/util/debug_util.h: -------------------------------------------------------------------------------- 1 | /** @file debug_util.h 2 | * 3 | * Functions for debugging 4 | */ 5 | 6 | // Copyright (C) 2016-2025 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef DEBUG_UTIL_H_ 10 | #define DEBUG_UTIL_H_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | #include "backtrace.h" // so existing code doesn't need to include 20 | 21 | #define ASSERT_WITH_BACKTRACE(_condition) \ 22 | do { \ 23 | if ( !(_condition) ) { \ 24 | show_backtrace(0); \ 25 | assert(_condition); \ 26 | } \ 27 | } while(0) 28 | 29 | void show_backtrace(int stack_adjust); 30 | 31 | void set_simple_dbgmsg_min_funcname_size(int new_size); 32 | 33 | bool simple_dbgmsg( 34 | bool debug_flag, 35 | const char * funcname, 36 | const int lineno, 37 | const char * filename, 38 | const char * format, 39 | ...); 40 | 41 | #define DBGF(debug_flag, format, ...) \ 42 | do { if (debug_flag) simple_dbgmsg(debug_flag, __func__, __LINE__, __FILE__, format, ##__VA_ARGS__); } while(0) 43 | 44 | #define DBG(format, ...) \ 45 | simple_dbgmsg(true, __func__, __LINE__, __FILE__, format, ##__VA_ARGS__) 46 | 47 | #ifdef __cplusplus 48 | } // extern "C" 49 | #endif 50 | 51 | #endif /* DEBUG_UTIL_H_ */ 52 | -------------------------------------------------------------------------------- /src/util/drm_card_connector_util.h: -------------------------------------------------------------------------------- 1 | /** @file drm_card_connector_util.h */ 2 | 3 | // Copyright (C) 2024-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef DRM_CARD_CONNECTOR_UTIL_H_ 7 | #define DRM_CARD_CONNECTOR_UTIL_H_ 8 | 9 | #include 10 | #include 11 | 12 | bool check_video_adapters_list_implements_drm(GPtrArray * adapter_devices); 13 | bool check_all_video_adapters_implement_drm(); 14 | 15 | typedef struct { 16 | int cardno; 17 | int connector_id; 18 | int connector_type; 19 | int connector_type_id; 20 | } Drm_Connector_Identifier; 21 | 22 | char * dci_repr(Drm_Connector_Identifier dci); 23 | char * dci_repr_t(Drm_Connector_Identifier dci); 24 | bool dci_eq(Drm_Connector_Identifier dci1, Drm_Connector_Identifier dci2); 25 | int dci_cmp(Drm_Connector_Identifier dci1, Drm_Connector_Identifier dci2); 26 | int sys_drm_connector_name_cmp0(const char * s1, const char * s2); 27 | int sys_drm_connector_name_cmp(gconstpointer connector_name1, gconstpointer connector_name2); 28 | Drm_Connector_Identifier parse_sys_drm_connector_name(const char * drm_connector); 29 | 30 | #ifdef UNUSED 31 | Bit_Set_32 get_sysfs_drm_card_numbers(); 32 | #endif 33 | 34 | #endif /* DRM_CARD_CONNECTOR_UTIL_H_ */ 35 | -------------------------------------------------------------------------------- /src/util/file_util_base.h: -------------------------------------------------------------------------------- 1 | /** \file file_util_base.h 2 | * Core file utility functions. 3 | * This file exists so that includes in util directory can form 4 | * a directed graph. 5 | */ 6 | 7 | // Copyright (C) 2018-2022 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | #ifndef FILE_UTIL_BASE_H_ 11 | #define FILE_UTIL_BASE_H_ 12 | 13 | #include 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | int file_getlines( 21 | const char * fn, 22 | GPtrArray* line_array, 23 | bool verbose) 24 | ; 25 | #ifdef __cplusplus 26 | } // extern "C" 27 | #endif 28 | 29 | #endif /* FILE_UTIL_BASE_H_ */ 30 | -------------------------------------------------------------------------------- /src/util/glib_string_util.h: -------------------------------------------------------------------------------- 1 | /** @file glib_string_util.h 2 | * 3 | * Functions that depend on both glib_util.c and string_util.c 4 | * 5 | * glib_string_util.c/h exist to avoid circular dependencies. 6 | */ 7 | 8 | // Copyright (C) 2014-2023 Sanford Rockowitz 9 | // SPDX-License-Identifier: GPL-2.0-or-later 10 | 11 | 12 | /** \cond */ 13 | #include 14 | /** \endcond */ 15 | 16 | #ifndef GLIB_STRING_UTIL_H_ 17 | #define GLIB_STRING_UTIL_H_ 18 | 19 | char * join_string_g_ptr_array(GPtrArray* strings, char * sepstr); 20 | char * join_string_g_ptr_array_t(GPtrArray* strings, char * sepstr); 21 | char * join_string_g_ptr_array2(GPtrArray* strings, char * sepstr, bool sort); 22 | char * join_string_g_ptr_array2_t(GPtrArray* strings, char * sepstr, bool sort); 23 | 24 | int gaux_string_ptr_array_find(GPtrArray * haystack, const char * needle); 25 | bool gaux_unique_string_ptr_arrays_equal(GPtrArray *first, GPtrArray* second); 26 | GPtrArray * gaux_unique_string_ptr_arrays_minus(GPtrArray *first, GPtrArray* second); 27 | void gaux_unique_string_ptr_array_include(GPtrArray * arry, char * new_value); 28 | 29 | #endif /* GLIB_STRING_UTIL_H_ */ 30 | -------------------------------------------------------------------------------- /src/util/glib_util.h: -------------------------------------------------------------------------------- 1 | /** @file glib_util.h 2 | * 3 | * Utility functions for glib. 4 | */ 5 | 6 | // Copyright (C) 2014-2021 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | 10 | #ifndef GLIB_UTIL_H_ 11 | #define GLIB_UTIL_H_ 12 | 13 | /** \cond */ 14 | #include 15 | #include 16 | /** \endcond */ 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | gpointer * 23 | g_list_to_g_array( 24 | GList * glist, 25 | guint * length); 26 | 27 | gint 28 | gaux_ptr_scomp( 29 | gconstpointer a, 30 | gconstpointer b); 31 | 32 | gint 33 | gaux_ptr_intcomp( 34 | gconstpointer a, 35 | gconstpointer b); 36 | 37 | void * 38 | get_thread_dynamic_buffer( 39 | GPrivate * buf_key_ptr, 40 | GPrivate * bufsz_key_ptr, 41 | guint16 required_size); 42 | 43 | void * 44 | get_thread_fixed_buffer( 45 | GPrivate * buf_key_ptr, 46 | guint16 required_size); 47 | 48 | GPtrArray * 49 | gaux_ptr_array_truncate( 50 | GPtrArray * gpa, 51 | int limit); 52 | 53 | // Future: 54 | typedef gpointer (*GAuxDupFunc)(gpointer src); 55 | 56 | GPtrArray * 57 | gaux_ptr_array_append_array( 58 | GPtrArray * dest, 59 | GPtrArray * src, 60 | GAuxDupFunc dup_func); 61 | 62 | GPtrArray * 63 | gaux_ptr_array_join( 64 | GPtrArray * gpa1, 65 | GPtrArray * gpa2, 66 | GAuxDupFunc dup_func, 67 | GDestroyNotify element_free_func); 68 | 69 | GPtrArray * 70 | gaux_ptr_array_copy( 71 | GPtrArray * src, 72 | GAuxDupFunc dup_func, 73 | GDestroyNotify element_free_func); 74 | 75 | GPtrArray * 76 | gaux_deep_copy_string_array( 77 | GPtrArray * old_names); 78 | 79 | GPtrArray * 80 | gaux_ptr_array_from_null_terminated_array( 81 | gpointer * src, 82 | GAuxDupFunc dup_func, 83 | GDestroyNotify element_free_func); 84 | 85 | gboolean 86 | gaux_streq( // alternative to g_str_equal(), has GEqualFunc signature 87 | gconstpointer a, 88 | gconstpointer b); 89 | 90 | gboolean 91 | gaux_ptr_array_find_with_equal_func( 92 | GPtrArray * haystack, 93 | gconstpointer needle, 94 | GEqualFunc equal_func, 95 | guint * index_); 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | 102 | 103 | #endif /* GLIB_UTIL_H_ */ 104 | -------------------------------------------------------------------------------- /src/util/i2c_util.h: -------------------------------------------------------------------------------- 1 | /** @file i2c_util.h 2 | * 3 | * I2C utility functions 4 | */ 5 | 6 | // Copyright (C) 2014-2022 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef I2C_UTIL_H_ 10 | #define I2C_UTIL_H_ 11 | 12 | #include 13 | 14 | int i2c_name_to_busno(const char * name); 15 | int extract_number_after_hyphen(const char * name); 16 | int i2c_compare(const void * v1, const void * v2); 17 | 18 | unsigned long i2c_get_functionality_flags_by_fd(int fd); 19 | char * i2c_interpret_functionality_flags(unsigned long functionality); 20 | void i2c_report_functionality_flags(long functionality, int maxline, int depth); 21 | bool dev_i2c_devices_exist(); 22 | 23 | #endif /* I2C_UTIL_H_ */ 24 | -------------------------------------------------------------------------------- /src/util/libdrm_aux_util.h: -------------------------------------------------------------------------------- 1 | /** @file libdrm_aux_util.h */ 2 | 3 | // Copyright (C) 2024-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef LIBDRM_AUX_UTIL_H_ 7 | #define LIBDRM_AUX_UTIL_H_ 8 | 9 | /** \cond */ 10 | #include 11 | #include 12 | #include 13 | 14 | #include "data_structures.h" 15 | /** \endcond */ 16 | 17 | const char * drm_bus_type_name(uint8_t bus); 18 | bool check_drm_supported_using_drm_api(char * busid2); 19 | bool adapter_supports_drm_using_drm_api(const char * adapter_path); 20 | bool all_displays_drm_using_drm_api(); 21 | GPtrArray * get_dri_device_names_using_filesys(); 22 | bool all_video_adapters_support_drm_using_drm_api(GPtrArray * adapter_paths); 23 | None_Some_All check_drivers_support_drm_using_drm_api(); 24 | 25 | #endif /* LIBDRM_AUX_UTIL_H_ */ 26 | -------------------------------------------------------------------------------- /src/util/libdrm_util.h: -------------------------------------------------------------------------------- 1 | /** @file libdrm_util.h 2 | * Utilities for use with libdrm 3 | */ 4 | 5 | // Copyright (C) 2017-2024 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef LIBDRM_UTIL_H_ 9 | #define LIBDRM_UTIL_H_ 10 | 11 | /** \cond */ 12 | #include 13 | #include 14 | #include 15 | /** \endcond */ 16 | 17 | extern Value_Name_Title_Table drm_connector_type_table; 18 | int lookup_drm_connector_type(const char * name); 19 | char * drm_connector_type_name(Byte val); 20 | char * drm_connector_type_title(Byte val); 21 | 22 | // char * drm_connector_type_name( Byte val); 23 | // char * drm_connector_type_title(Byte val); 24 | char * connector_status_name( drmModeConnection val); 25 | char * connector_status_title(drmModeConnection val); 26 | char * encoder_type_title(uint32_t encoder_type); 27 | 28 | void report_drmModeRes( drmModeResPtr res, int depth); 29 | void report_drmModePropertyBlob( drmModePropertyBlobPtr blob_ptr, int depth); 30 | void report_drmModeConnector( int fd, drmModeConnector * p, int depth); 31 | void report_drm_modeProperty( drmModePropertyRes * p, int depth); 32 | 33 | void summarize_drm_modeProperty(drmModePropertyRes * p, int depth); 34 | void report_property_value(int fd, drmModePropertyPtr prop_ptr, uint64_t prop_value, int depth) ; 35 | 36 | #endif /* LIBDRM_UTIL_H_ */ 37 | -------------------------------------------------------------------------------- /src/util/linux_util.h: -------------------------------------------------------------------------------- 1 | /** \file linux_util.h 2 | * Miscellaneous Linux utilities 3 | */ 4 | 5 | // Copyright (C) 2021-2024 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef LINUX_UTIL_H_ 9 | #define LINUX_UTIL_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | int get_kernel_config_parm(const char * parm_name, char * buffer, int bufsz); 16 | bool is_module_built_in(const char * module_name); 17 | 18 | #define KERNEL_MODULE_NOT_FOUND 0 // not found 19 | #define KERNEL_MODULE_BUILTIN 1 // module is built into kernel 20 | #define KERNEL_MODULE_LOADABLE_FILE 2 // module is a loadable file 21 | 22 | int module_status_by_modules_builtin_or_existence(const char * module_name); 23 | bool is_module_loadable(const char * module_name); 24 | 25 | intmax_t get_thread_id(); 26 | intmax_t get_process_id(); 27 | bool is_valid_thread_or_process(pid_t id); 28 | 29 | void rpt_lsof(const char * fqfn, int depth); 30 | GPtrArray* rpt_lsof_collect(const char * fqfn); 31 | 32 | #endif /* LINUX_UTIL_H_ */ 33 | -------------------------------------------------------------------------------- /src/util/msg_util.h: -------------------------------------------------------------------------------- 1 | /** @file msg_util.h */ 2 | 3 | // Copyright (C) 2024-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef MSG_UTIL_H_ 7 | #define MSG_UTIL_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | 16 | extern bool dbgtrc_show_time; // prefix debug/trace messages with elapsed time 17 | extern bool dbgtrc_show_wall_time; // prefix debug/trace messages with wall time 18 | extern bool dbgtrc_show_thread_id; // prefix debug/trace messages with thread id 19 | extern bool dbgtrc_show_process_id; // prefix debug/trace messages with process id 20 | extern bool dbgtrc_trace_to_syslog_only; 21 | extern bool stdout_stderr_redirected; 22 | 23 | extern __thread bool msg_decoration_suspended; 24 | 25 | char* get_msg_decoration(char * buf, uint bufsize, bool dest_syslog); 26 | char* formatted_wall_time(); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif /* MSG_UTIL_H_ */ 33 | -------------------------------------------------------------------------------- /src/util/multi_level_map.h: -------------------------------------------------------------------------------- 1 | /** @file multi_level_map.h */ 2 | 3 | // Copyright (C) 2021-2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | /** @file multi_level_map.h 7 | * Multi_Level_Map data structure 8 | */ 9 | 10 | #ifndef MULTI_LEVEL_TABLE_H_ 11 | #define MULTI_LEVEL_TABLE_H_ 12 | 13 | /** \cond */ 14 | #include 15 | /** \endcond */ 16 | 17 | #define MLT_MAX_LEVELS 4 18 | 19 | typedef struct { 20 | int levels; 21 | char * names[MLT_MAX_LEVELS]; 22 | } Multi_Level_Names; 23 | 24 | typedef struct { 25 | int levels; 26 | guint ids[MLT_MAX_LEVELS]; 27 | } Multi_Level_Ids; 28 | 29 | 30 | typedef struct { 31 | gushort level; 32 | guint code; 33 | char * name; 34 | GPtrArray * children; 35 | } MLM_Node; 36 | 37 | /* Used to both describe a level in a **Multi_Level_Map** table, 38 | * /and maintain data about that level 39 | */ 40 | typedef struct { 41 | char * name; 42 | int initial_size; 43 | int total_entries; 44 | MLM_Node * cur_entry; 45 | } MLM_Level; 46 | 47 | void report_mlm_level(MLM_Level * level_desc, int depth); 48 | 49 | typedef struct { 50 | char* table_name; 51 | char* segment_tag; 52 | int levels; 53 | GPtrArray * root; 54 | MLM_Level level_detail[]; 55 | // MLM_Level * level_detail; 56 | } Multi_Level_Map; 57 | 58 | 59 | Multi_Level_Map * mlm_create(char * table_name, int levels, MLM_Level* level_detail); 60 | MLM_Node * mlm_add_node(Multi_Level_Map * mlm, MLM_Node * parent, guint key, char * value); 61 | 62 | void report_multi_level_map(Multi_Level_Map * mlm, int depth); 63 | 64 | Multi_Level_Names mlm_get_names(Multi_Level_Map * mlm, int argct, ...); 65 | 66 | Multi_Level_Names mlm_get_names2(Multi_Level_Map * mlm, int levelct, guint* ids); 67 | 68 | #endif /* MULTI_LEVEL_TABLE_H_ */ 69 | -------------------------------------------------------------------------------- /src/util/pnp_ids.h: -------------------------------------------------------------------------------- 1 | /** \file pnp_ids.h 2 | * 3 | * Provides a lookup table of 3 character manufacturer codes, 4 | * which are used, e.g. in EDIDs. 5 | */ 6 | 7 | // Copyright (C) 2022 Sanford Rockowitz 8 | // SPDX-License-Identifier: GPL-2.0-or-later 9 | 10 | #ifndef PNP_IDS_H_ 11 | #define PNP_IDS_H_ 12 | 13 | char * pnp_name(char * id); 14 | 15 | #ifdef TESTS 16 | void pnp_id_tests(); 17 | #endif 18 | 19 | #endif /* PNP_IDS_H_ */ 20 | -------------------------------------------------------------------------------- /src/util/regex_util.h: -------------------------------------------------------------------------------- 1 | // regex_util.h 2 | 3 | // Copyright (C) 2024 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef REGEX_UTIL_H_ 7 | #define REGEX_UTIL_H_ 8 | 9 | #include 10 | #include 11 | 12 | void free_regex_hash_table(); 13 | 14 | bool compile_and_eval_regex(const char * pattern, const char * value); 15 | 16 | bool compile_and_eval_regex_with_matches( 17 | const char * pattern, 18 | const char * value, 19 | size_t max_matches, 20 | regmatch_t * pm); 21 | 22 | #endif /* REGEX_UTIL_H_ */ 23 | -------------------------------------------------------------------------------- /src/util/simple_ini_file.h: -------------------------------------------------------------------------------- 1 | /** \file simple_ini_file.h 2 | * 3 | * Reads an INI style configuration file 4 | */ 5 | 6 | // Copyright (C) 2021-2023 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef SIMPLE_INI_FILE_H_ 10 | #define SIMPLE_INI_FILE_H_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | #include "error_info.h" 20 | 21 | #define PARSED_INI_FILE_MARKER "INIF" 22 | typedef struct { 23 | char marker[4]; 24 | char * config_fn; 25 | GHashTable * hash_table; 26 | } Parsed_Ini_File; 27 | 28 | int ini_file_load( 29 | const char * ini_filename, 30 | GPtrArray* errmsgs, 31 | Parsed_Ini_File** ini_file_loc); 32 | 33 | char * ini_file_get_value( 34 | Parsed_Ini_File * ini_file, 35 | const char * segment, 36 | const char * id); 37 | 38 | void ini_file_dump( 39 | Parsed_Ini_File * ini_file); 40 | 41 | void ini_file_free( 42 | Parsed_Ini_File * parsed_ini_file); 43 | 44 | #ifdef __cplusplus 45 | } // extern "C" 46 | #endif 47 | 48 | #endif /* SIMPLE_INI_FILE_H_ */ 49 | -------------------------------------------------------------------------------- /src/util/subprocess_util.h: -------------------------------------------------------------------------------- 1 | /** @file subprocess_util.h 2 | * 3 | * Functions to execute shell commands 4 | */ 5 | 6 | // Copyright (C) 2014-2021 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef SUBPROCESS_UTIL_H_ 10 | #define SUBPROCESS_UTIL_H_ 11 | 12 | /** \cond */ 13 | #include 14 | #include 15 | /** \endcond */ 16 | 17 | bool execute_shell_cmd( const char * shell_cmd); 18 | bool execute_shell_cmd_rpt( const char * shell_cmd, int depth); 19 | GPtrArray * execute_shell_cmd_collect( const char * shell_cmd); 20 | int execute_cmd_collect_with_filter( 21 | const char * shell_cmd, 22 | char ** filter_terms, 23 | bool ignore_case, 24 | int limit, 25 | GPtrArray ** result_loc); 26 | 27 | char * execute_shell_cmd_one_line_result(const char * shell_cmd); 28 | bool is_command_in_path( const char * cmd); 29 | int test_command_executability( const char * cmd); 30 | 31 | #endif /* SUBPROCESS_UTIL_H_ */ 32 | -------------------------------------------------------------------------------- /src/util/sysfs_filter_functions.h: -------------------------------------------------------------------------------- 1 | /** \f sysfs_filter_functions.h 2 | */ 3 | 4 | //// Copyright (C) 2021-2025 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef SYSFS_FILTER_FUNCTIONS_H_ 8 | #define SYSFS_FILTER_FUNCTIONS_H_ 9 | 10 | #include 11 | 12 | #include "data_structures.h" 13 | 14 | // Filename_Filter_Func 15 | 16 | bool predicate_cardN( const char * value); 17 | bool predicate_cardN_connector(const char * value); 18 | bool predicate_i2c_N( const char * value); 19 | bool predicate_any_D_00hh( const char * value); 20 | 21 | // Filename_Filter_Func_With_Arg 22 | 23 | bool fn_equal( const char * filename, const char * val); 24 | bool fn_starts_with( const char * filename, const char * val); 25 | bool predicate_exact_D_00hh(const char * value, const char * sbusno); 26 | 27 | // Dir_Filter_Func 28 | 29 | bool is_drm_connector( const char * dirname, const char * simple_fn); 30 | bool is_i2cN_dir( const char * dirname, const char * fn_ignored); // for e.g. dirname i2c-3 31 | bool is_drm_dp_aux_subdir( const char * dirname, const char * val); 32 | bool is_card_connector_dir(const char * dirname, const char * simple_fn); // for e.g. card0-DP-1 33 | bool is_cardN_dir( const char * dirname, const char * simple_fn); // for e.g. card0 34 | bool has_class_display_or_docking_station(const char * dirname, const char * simple_fn); 35 | bool has_class_display( const char * dirname, const char * simple_fn); 36 | 37 | #endif /* SYSFS_FILTER_FUNCTIONS_H_ */ 38 | -------------------------------------------------------------------------------- /src/util/sysfs_i2c_util.h: -------------------------------------------------------------------------------- 1 | /** @file sysfs_i2c_util.h 2 | * i2c specific /sys functions 3 | */ 4 | 5 | // Copyright (C) 2020-2025 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef SYSFS_I2C_UTIL_H_ 9 | #define SYSFS_I2C_UTIL_H_ 10 | 11 | #include 12 | #include 13 | 14 | #include "data_structures.h" 15 | 16 | bool is_module_loaded_using_sysfs(const char * module_name); 17 | 18 | GPtrArray * get_video_adapter_devices(); 19 | 20 | #endif /* SYSFS_I2C_UTIL_H_ */ 21 | 22 | -------------------------------------------------------------------------------- /src/util/systemd_util.h: -------------------------------------------------------------------------------- 1 | /** @file systemd_util.h 2 | */ 3 | 4 | // Copyright (C) 2017-2023 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef SYSTEMD_UTIL_H_ 8 | #define SYSTEMD_UTIL_H_ 9 | 10 | #include 11 | 12 | GPtrArray * get_current_boot_messages(char ** filter_terms, bool ignore_case, int limit); 13 | 14 | #endif /* SYSTEMD_UTIL_H_ */ 15 | -------------------------------------------------------------------------------- /src/util/timestamp.h: -------------------------------------------------------------------------------- 1 | /** @file timestamp.h 2 | * 3 | * Timestamp management 4 | */ 5 | 6 | // Copyright (C) 2014-2025 Sanford Rockowitz 7 | // SPDX-License-Identifier: GPL-2.0-or-later 8 | 9 | #ifndef TIMESTAMP_H_ 10 | #define TIMESTAMP_H_ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | /** \cond */ 17 | #include 18 | /** \endcond */ 19 | 20 | // 21 | // Timestamp Generation 22 | // 23 | uint64_t cur_realtime_nanosec(); // Returns the current value of the realtime clock in nanoseconds 24 | void show_timestamp_history(); // For debugging 25 | uint64_t elapsed_time_nanosec(); // nanoseconds since start of program, first call initializes 26 | char * formatted_elapsed_time_t(guint precision); // printable elapsed time 27 | char * formatted_time_t(uint64_t nanos); 28 | char * formatted_epoch_time_t(time_t epoch_seconds); 29 | 30 | #define NANOS2MICROS( _nanosec ) (((_nanosec) + 500)/1000) 31 | #define NANOS2MILLIS( _nanosec ) (((_nanosec)+500000)/1000000) 32 | #define MILLIS2NANOS( _millisec) (_millisec*(uint64_t)1000000) 33 | #define MILLIS2MICROS(_millisec) (_millisec*(uint64_t)1000) 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif /* TIMESTAMP_H_ */ 40 | -------------------------------------------------------------------------------- /src/util/traced_function_stack.h: -------------------------------------------------------------------------------- 1 | /** @file traced_function_stack.h */ 2 | 3 | // Copyright (C) 2024-2025 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef TRACED_FUNCTION_STACK_H_ 7 | #define TRACED_FUNCTION_STACK_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | 16 | extern bool traced_function_stack_enabled; 17 | extern bool traced_function_stack_errors_fatal; 18 | extern __thread GQueue * traced_function_stack; 19 | extern __thread bool traced_function_stack_suspended; 20 | extern __thread bool debug_tfs; 21 | 22 | bool set_debug_thread_tfs(bool newval); 23 | 24 | void push_traced_function(const char * funcname); 25 | char* peek_traced_function(); 26 | void pop_traced_function(const char * funcname); 27 | 28 | void collect_traced_function_stack(GPtrArray* collector, GQueue * stack, bool reverse, int stack_adjust); 29 | void debug_current_traced_function_stack(bool reverse); 30 | GPtrArray* get_current_traced_function_stack_contents(bool most_recent_last); 31 | void current_traced_function_stack_to_syslog(int syslog_priority, bool reverse); 32 | 33 | void reset_current_traced_function_stack(); 34 | void free_current_traced_function_stack(); 35 | void free_all_traced_function_stacks(); 36 | 37 | #ifdef __cplusplus 38 | } // extern "C" 39 | #endif 40 | 41 | #endif /* TRACED_FUNCTION_STACK_H_ */ 42 | -------------------------------------------------------------------------------- /src/util/udev_i2c_util.h: -------------------------------------------------------------------------------- 1 | /** @file udev_i2c_util.h 2 | * I2C specific udev utilities 3 | */ 4 | 5 | // Copyright (C) 2016-2021 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef UDEV_I2C_UTIL_H_ 9 | #define UDEV_I2C_UTIL_H_ 10 | 11 | /** \cond */ 12 | #include 13 | #include 14 | /** \endcond */ 15 | 16 | #include "data_structures.h" 17 | #include "udev_util.h" 18 | 19 | GPtrArray * // array of Udev_Device_Summary 20 | get_i2c_devices_using_udev(); 21 | 22 | int udev_i2c_device_summary_busno(Udev_Device_Summary * summary); 23 | 24 | void 25 | report_i2c_udev_device_summaries( 26 | GPtrArray * summaries, // array of Udev_Device_Summary 27 | char * title, 28 | int depth) ; 29 | 30 | 31 | 32 | /** Signature of function that tests sys attribute name */ 33 | typedef bool (*Sysattr_Name_Filter)(const char * sysattr_name); 34 | 35 | Byte_Value_Array 36 | get_i2c_device_numbers_using_udev_w_sysattr_name_filter(Sysattr_Name_Filter keep_func); 37 | 38 | #endif /* UDEV_I2C_UTIL_H_ */ 39 | -------------------------------------------------------------------------------- /src/util/udev_util.h: -------------------------------------------------------------------------------- 1 | /** @file udev_util.h 2 | * UDEV utility functions 3 | */ 4 | 5 | // Copyright (C) 2016-2023 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef UDEV_UTIL_H_ 9 | #define UDEV_UTIL_H_ 10 | 11 | /** \cond */ 12 | #include 13 | #include 14 | #include 15 | /** \endcond */ 16 | 17 | #define UDEV_DEVICE_SUMMARY_MARKER "UDSM" 18 | /** Summary information for one UDEV device 19 | */ 20 | typedef struct udev_device_summary { 21 | char marker[4]; ///< always "UDSM" 22 | char * sysname; ///< e.g. i2c-3 23 | char * devpath; ///< device path 24 | char * sysattr_name; ///< sysattr name 25 | char * subsystem; ///< subsystem, e.g. usbmisc 26 | } Udev_Device_Summary; 27 | 28 | void free_udev_device_summaries(GPtrArray* summaries); 29 | GPtrArray * summarize_udev_subsystem_devices(char * subsystem); 30 | GPtrArray * find_devices_by_sysattr_name(char * name); 31 | 32 | // Function returns true if keep, false if discard 33 | typedef bool (*Udev_Summary_Filter_Func)(Udev_Device_Summary * summary); 34 | GPtrArray * filter_device_summaries(GPtrArray * summaries, Udev_Summary_Filter_Func func); 35 | 36 | void report_udev_device(struct udev_device * dev, int depth); 37 | 38 | void show_udev_list_entries( 39 | struct udev_list_entry * entries, 40 | char * title); 41 | void show_sysattr_list_entries( 42 | struct udev_device * dev, 43 | struct udev_list_entry * head); 44 | 45 | #endif /* UDEV_UTIL_H_ */ 46 | -------------------------------------------------------------------------------- /src/util/util.md: -------------------------------------------------------------------------------- 1 | /** \dir 2 | 3 | Directory util provides services that are independent of **ddcutil** and could be used in other applications. 4 | 5 | Most files provide general purpose functions such as data structures, and output management. 6 | 7 | Some files, such as udev_util.c, provide functions to simplify use of specific system libraries. 8 | USB related utility files have been segregated to directory usb_util. 9 | 10 | 11 | */ 12 | -------------------------------------------------------------------------------- /src/util/utilrpt.c: -------------------------------------------------------------------------------- 1 | /* utilrpt.c 2 | * 3 | * 4 | * Copyright (C) 2014-2017 Sanford Rockowitz 5 | * 6 | * Licensed under the GNU General Public License Version 2 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | * 22 | */ 23 | 24 | /** \f 25 | * Report functions for other utility modules. 26 | * Avoids complex dependencies between report_util.c and other 27 | * util files. 28 | */ 29 | 30 | #include "data_structures.h" 31 | #include "report_util.h" 32 | 33 | #include "utilrpt.h" 34 | 35 | /** Displays all fields of a #Buffer. 36 | * This is a debugging function. 37 | * 38 | * @param buffer pointer to Buffer instance 39 | * @param depth logical indentation depth 40 | * 41 | * @remark 42 | * Output is written to the current report destination. 43 | */ 44 | void dbgrpt_buffer(Buffer * buffer, int depth) { 45 | rpt_vstring(depth, 46 | "Buffer at %p, bytes addr=%p, len=%d, max_size=%d", 47 | buffer, buffer->bytes, buffer->len, buffer->buffer_size); 48 | // printf(" bytes end addr=%p\n", buffer->bytes+buffer->buffer_size); 49 | if (buffer->bytes) 50 | rpt_hex_dump(buffer->bytes, buffer->len, depth); 51 | } 52 | -------------------------------------------------------------------------------- /src/util/utilrpt.h: -------------------------------------------------------------------------------- 1 | /* utilrpt.h 2 | * 3 | * 4 | * Copyright (C) 2014-2017 Sanford Rockowitz 5 | * 6 | * Licensed under the GNU General Public License Version 2 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | * 22 | */ 23 | 24 | /** \f 25 | * Report functions for other utility modules. 26 | * Avoids complex dependencies between report_util.c and other 27 | * util files. 28 | */ 29 | 30 | #ifndef UTILRPT_H_ 31 | #define UTILRPT_H_ 32 | 33 | #include "data_structures.h" 34 | 35 | void dbgrpt_buffer(Buffer * buffer, int depth); 36 | 37 | #endif /* UTILRPT_H_ */ 38 | -------------------------------------------------------------------------------- /src/util/x11_util.h: -------------------------------------------------------------------------------- 1 | /** @file x11_util.h Utilities for X11 2 | */ 3 | 4 | // Copyright (C) 2014-2023 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef X11_UTIL_H_ 8 | #define X11_UTIL_H_ 9 | 10 | /** \cond */ 11 | #include 12 | /** \endcond */ 13 | 14 | #include "coredefs.h" 15 | 16 | /** Represents one EDID known to X11 */ 17 | typedef struct { 18 | char * output_name; ///< RandR output name 19 | Byte * edidbytes; ///< pointer to 128 byte EDID 20 | } X11_Edid_Rec; 21 | 22 | GPtrArray * get_x11_edids(bool use_screen_resources_current); // returns array of X11_Edid_Rec 23 | void free_x11_edids(GPtrArray * edidrecs); 24 | bool get_x11_dpms_info(unsigned short * power_level, unsigned char * state); 25 | const char* dpms_power_level_name(unsigned short power_level); 26 | 27 | #endif /* X11_UTIL_H_ */ 28 | -------------------------------------------------------------------------------- /src/util/xdg_util.h: -------------------------------------------------------------------------------- 1 | /** \file xdg_util.h 2 | * Implement XDG Base Directory Specification 3 | */ 4 | 5 | // Copyright (C) 2020-2021 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef XDG_UTIL_H_ 9 | #define XDG_UTIL_H_ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | char * xdg_data_home_dir(); // $XDG_DATA_HOME or $HOME/.local/share 16 | char * xdg_config_home_dir(); // $XDG_CONFIG_HOME or $HOME/.config 17 | char * xdg_cache_home_dir(); // $XDG_CACHE_HOME or $HOME/.cache 18 | char * xdg_state_home_dir(); // $XDG_STATE_HOME or $HOME/.local/state 19 | 20 | char * xdg_data_dirs(); // $XDG_DATA_DIRS or /usr/local/share:/usr/share 21 | char * xdg_config_dirs(); // $XDG_CONFIG_DIRS or /etc/xdg 22 | 23 | char * xdg_data_path(); // XDG_DATA_HOME directory, followed by XDG_DATA_DIRS 24 | char * xdg_config_path(); // XDG_CONFIG_HOME directory, followed by XDG_CONFIG_DIRS 25 | 26 | char * xdg_data_home_file( const char * application, const char * simple_fn); 27 | char * xdg_config_home_file(const char * application, const char * simple_fn); 28 | char * xdg_cache_home_file( const char * application, const char * simple_fn); 29 | char * xdg_state_home_file( const char * application, const char * simple_fn); 30 | 31 | char * find_xdg_data_file( const char * application, const char * simple_fn); 32 | char * find_xdg_config_file(const char * application, const char * simple_fn); 33 | char * find_xdg_cache_file( const char * application, const char * simple_fn); 34 | char * find_xdg_state_file( const char * application, const char * simple_fn); 35 | 36 | void xdg_tests(); 37 | 38 | #ifdef __cplusplus 39 | } // extern "C" 40 | #endif 41 | 42 | #endif /* XDG_UTIL_H_ */ 43 | -------------------------------------------------------------------------------- /src/vcp/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = \ 2 | $(GLIB_CFLAGS) \ 3 | -I$(top_srcdir)/src \ 4 | -I$(top_srcdir)/src/public 5 | 6 | AM_CFLAGS = $(AM_CFLAGS_STD) 7 | 8 | if WARNINGS_ARE_ERRORS_COND 9 | AM_CFLAGS += "-Werror" 10 | endif 11 | 12 | # vcp_feature_codes.c requires extensive changes if -Wpedantic 13 | # AM_CFLAGS += -Wpedantic 14 | 15 | CLEANFILES = \ 16 | *expand 17 | 18 | clean-local: 19 | @echo "(src/vcp/Makefile) clean-local" 20 | 21 | mostlyclean-local: 22 | @echo "(src/vcp/Makefile) mostlyclean-local" 23 | 24 | distclean-local: 25 | @echo "(src/vcp/Makefile) distclean-local" 26 | 27 | dist-hook: 28 | @echo "(src/vcp/Makefile) dist-hook" 29 | 30 | # Intermediate Library 31 | noinst_LTLIBRARIES = libvcp.la 32 | 33 | libvcp_la_SOURCES = \ 34 | parse_capabilities.c \ 35 | parsed_capabilities_feature.c \ 36 | persistent_capabilities.c \ 37 | vcp_feature_codes.c \ 38 | vcp_feature_values.c 39 | -------------------------------------------------------------------------------- /src/vcp/parse_capabilities.h: -------------------------------------------------------------------------------- 1 | /** @file parse_capabilities.h 2 | */ 3 | 4 | // Copyright (C) 2014-2022 Sanford Rockowitz 5 | // SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | #ifndef PARSE_CAPABILITIES_H_ 8 | #define PARSE_CAPABILITIES_H_ 9 | 10 | /** \cond */ 11 | #include 12 | 13 | #include "util/data_structures.h" 14 | /** \endcond */ 15 | 16 | #include "base/vcp_version.h" 17 | 18 | typedef enum { 19 | CAPABILITIES_VALID, 20 | CAPABILITIES_USABLE, 21 | CAPABILITIES_INVALID 22 | } Parsed_Capabilities_Validity; 23 | 24 | 25 | #define PARSED_CAPABILITIES_MARKER "CAPA" 26 | /** Contains parsed capabilities information */ 27 | typedef struct { 28 | char marker[4]; // always "CAPA" 29 | char * raw_value; 30 | bool raw_value_synthesized; 31 | char * model; 32 | char * mccs_version_string; 33 | DDCA_MCCS_Version_Spec parsed_mccs_version; // parsed mccs_version_string, DDCA_VSPEC_UNKNOWN if parsing fails 34 | bool raw_cmds_segment_seen; 35 | bool raw_cmds_segment_valid; 36 | Byte_Value_Array commands; // each stored byte is command id 37 | bool raw_vcp_features_seen; 38 | GPtrArray * vcp_features; // entries are Capabilities_Feature_Record * 39 | Parsed_Capabilities_Validity caps_validity; 40 | GPtrArray * messages; 41 | } Parsed_Capabilities; 42 | 43 | 44 | Parsed_Capabilities* parse_capabilities_string(char * capabilities); 45 | void free_parsed_capabilities(Parsed_Capabilities * pcaps); 46 | Bit_Set_256 get_parsed_capabilities_feature_ids(Parsed_Capabilities * pcaps, bool readable_only); 47 | bool parsed_capabilities_supports_table_commands(Parsed_Capabilities * pcaps); 48 | char * parsed_capabilities_validity_name(Parsed_Capabilities_Validity validity); 49 | void dbgrpt_parsed_capabilities(Parsed_Capabilities * pcaps, int depth); 50 | void init_parse_capabilities(); 51 | 52 | 53 | // Tests 54 | void test_segments(); 55 | void test_parse_caps(); 56 | 57 | #endif /* PARSE_CAPABILITIES_H_ */ 58 | -------------------------------------------------------------------------------- /src/vcp/parsed_capabilities_feature.h: -------------------------------------------------------------------------------- 1 | /** \file parsed_capabilitied_feature.h 2 | * Parses the description of a VCP feature extracted from a capabilities string. 3 | */ 4 | 5 | // Copyright (C) 2015-2022 Sanford Rockowitz 6 | // SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | #ifndef PARSED_CAPABILITIES_FEATURE_H 9 | #define PARSED_CAPABILITIES_FEATURE_H 10 | 11 | #include 12 | 13 | #include "util/data_structures.h" 14 | 15 | #include "base/core.h" 16 | #include "base/feature_set_ref.h" 17 | 18 | #include "vcp/vcp_feature_codes.h" 19 | 20 | // define both for testing 21 | #define CFR_BVA // Use Byte_Value_Array for values 22 | #undef CFR_BBF // Use Byte_Bit_Flags for values 23 | 24 | #define CAPABILITIES_FEATURE_MARKER "VCPF" 25 | /** Parsed description of a VCP Feature in a capabilities string. */ 26 | typedef struct { 27 | char marker[4]; ///< always "VCPF" 28 | Byte feature_id; ///< VCP feature code 29 | Byte_Value_Array values; ///< need unsorted values for feature x72 gamma 30 | #ifdef CFR_BBF 31 | Byte_Bit_Flags bbflags; // alternative, but sorts values, screws up x72 gamma 32 | #endif 33 | char * value_string; ///< value substring from capabilities string 34 | bool valid_values; ///< string is valid 35 | } Capabilities_Feature_Record; 36 | 37 | Capabilities_Feature_Record * parse_capabilities_feature( 38 | Byte feature_id, 39 | char * value_string_start, 40 | int value_string_len, 41 | GPtrArray* error_messages); 42 | 43 | void free_capabilities_feature_record( 44 | Capabilities_Feature_Record * vfr); 45 | 46 | void dbgrpt_capabilities_feature_record( 47 | Capabilities_Feature_Record * vfr, int depth); 48 | 49 | #endif /* PARSED_CAPABILITIES_FEATURE_H */ 50 | -------------------------------------------------------------------------------- /src/vcp/persistent_capabilities.h: -------------------------------------------------------------------------------- 1 | /** \f persistent_capabilities.h */ 2 | 3 | // Copyright (C) 2021-2023 Sanford Rockowitz 4 | // SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | #ifndef PERSISTENT_CAPABILITIES_H_ 7 | #define PERSISTENT_CAPABILITIES_H_ 8 | 9 | #include "util/error_info.h" 10 | 11 | #include "base/monitor_model_key.h" 12 | 13 | bool enable_capabilities_cache(bool onoff); 14 | char * capabilities_cache_file_name(); 15 | void delete_capabilities_file(); 16 | char * get_persistent_capabilities(Monitor_Model_Key* mmk); 17 | void set_persistent_capabilites(Monitor_Model_Key* mmk, const char * capabilities); 18 | void dbgrpt_capabilities_hash(int depth, const char * msg); 19 | void init_persistent_capabilities(); 20 | void terminate_persistent_capabilities(); 21 | 22 | #endif /* PERSISTENT_CAPABILITIES_H_ */ 23 | --------------------------------------------------------------------------------