Last active
June 21, 2020 08:56
-
-
Save defremov/a29f94429d8d3b78345ce711d0bf7c83 to your computer and use it in GitHub Desktop.
Load default color profiles for all currently active displays
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env bash | |
set -Eeuo pipefail | |
PATH=/sbin:/usr/sbin:/bin:/usr/bin | |
export PATH | |
APP_TITLE='Load Color Profile' | |
PROGNAME="${0##*/}" | |
MESSAGE_FAIL='Failed to load color profile' | |
MESSAGE_FAIL_FOR="${MESSAGE_FAIL} for " | |
MESSAGE_FAIL_ANY="${MESSAGE_FAIL}s" | |
MESSAGE_SCRIPT="${APP_TITLE} script" | |
# Tell dispwin to use colord | |
export ARGYLL_USE_COLORD='yes' | |
USE_NOTIFY='' | |
notify_send() { | |
local expire_time="${1}" | |
local icon="${2}" | |
local summary="${3}" | |
shift 3 | |
local body="${*}" | |
if [[ "${USE_NOTIFY}" ]] ; then | |
notify-send \ | |
${PROGNAME:+"--app-name=${PROGNAME}"}\ | |
${expire_time:+"--expire-time=${expire_time}"}\ | |
${icon:+"--icon=${icon}"}\ | |
"${summary}" \ | |
"${body}" | |
else | |
>&2 printf '%b\n%b\n' "${summary}" "${body}" | |
fi | |
} | |
log_error() { | |
local summary="${1}" | |
shift 1 | |
local body="${*}" | |
notify_send 0 'messagebox_critical' "${summary}" "${body}" | |
} | |
log_warning() { | |
local summary="${1}" | |
shift 1 | |
local body="${*}" | |
notify_send 0 'messagebox_warning' "${summary}" "${body}" | |
} | |
log_info() { | |
local summary="${1}" | |
shift 1 | |
local body="${*}" | |
notify_send '' 'video-display' "${summary}" "${body}" | |
} | |
colord_object_get_property() { | |
local object="${1}" | |
local prop_key="${2}" | |
awk -F':\\s+' "/^${prop_key}\\W/ { print \$2; }" <<< $1 | |
} | |
colord_object_get_metadata() { | |
local object="${1}" | |
local meta_key="${2}" | |
awk -F'=' \ | |
"/^Metadata:\\s+${meta_key}\\W/ { print \$2; }" \ | |
<<< $1 | |
} | |
colord_device_get_by_id() { | |
local device_id="${1}" | |
colormgr 'find-device' "${device_id}" | |
} | |
colord_device_exists() { | |
local device_id="${1}" | |
colord_device_get_by_id "${device_id}" &>/dev/null | |
} | |
colord_device_find_by_metadata() { | |
local meta_key="${1}" | |
local meta_value="${2}" | |
colormgr 'find-device-by-property' \ | |
"${meta_key}" "${meta_value}" | |
} | |
colord_device_with_metadata_exists() { | |
local meta_key="${1}" | |
local meta_value="${2}" | |
colord_device_find_by_metadata \ | |
"${meta_key}" "${meta_value}" &>/dev/null | |
} | |
colord_device_get_property() { | |
local device="${1}" | |
local prop_key="${2}" | |
colord_object_get_property "${device}" "${prop_key}" | |
} | |
colord_device_get_id() { | |
local device="${1}" | |
local prop_key='Device ID' | |
colord_object_get_property "${device}" "${prop_key}" | |
} | |
colord_device_get_default_profile() { | |
local device="${1}" | |
local device_id=$(colord_device_get_id "${device}") | |
colormgr 'device-get-default-profile' "${device_id}" | |
} | |
colord_device_has_default_profile() { | |
local device="${1}" | |
colord_device_get_default_profile "${device}" &>/dev/null | |
} | |
colord_device_get_metadata() { | |
local device="${1}" | |
local meta_key="${2}" | |
colord_object_get_metadata "${device}" "${meta_key}" | |
} | |
colord_device_find_by_xrandr_name() { | |
local xrandr_name="${1}" | |
local meta_key='XRANDR_name' | |
local meta_value="${xrandr_name}" | |
colormgr 'find-device-by-property' \ | |
"${meta_key}" "${meta_value}" | |
} | |
colord_device_with_xrandr_name_exists() { | |
local xrandr_name="${1}" | |
local meta_key='XRANDR_name' | |
local meta_value="${xrandr_name}" | |
colord_device_with_metadata_exists \ | |
"${meta_key}" "${meta_value}" | |
} | |
colord_profile_get_by_id() { | |
local profile_id="${1}" | |
colormgr 'find-profile' "${profile_id}" | |
} | |
colord_profile_exists() { | |
local profile_id="${1}" | |
colord_profile_get_by_id "${profile_id}" &>/dev/null | |
} | |
colord_profile_get_property() { | |
local PROFILE="${1}" | |
local PROP_KEY="${2}" | |
colord_object_get_property "${PROFILE}" "${PROP_KEY}" | |
} | |
colord_profile_get_id() { | |
local profile="${1}" | |
local prop_key='Profile ID' | |
colord_object_get_property "${profile}" "${prop_key}" | |
} | |
colord_profile_get_filename() { | |
local profile="${1}" | |
local prop_key='Filename' | |
colord_object_get_property "${profile}" "${prop_key}" | |
} | |
colord_profile_get_title() { | |
local profile="${1}" | |
local prop_key='Title' | |
colord_object_get_property "${profile}" "${prop_key}" | |
} | |
colord_profile_get_metadata() { | |
local profile="${1}" | |
local meta_key="${2}" | |
colord_object_get_metadata "${profile}" "${meta_key}" | |
} | |
xrandr_get_outputs() { | |
xrandr --listactivemonitors \ | |
| awk -F'\\s+' ' | |
{ gsub(/^\s+|\s+$/, "") } | |
/^\s*[0-9]+:/ { gsub(/:$/, "", $1); | |
print $4, $1 + 1 }' | |
} | |
dispwin_load_default_profile() { | |
local dispwin_id="${1:-1}" | |
2>/dev/null dispwin -d"${dispwin_id}" -c -L | |
} | |
dispwin_verify_loaded_profile() { | |
local profile_filename="${1}" | |
local dispwin_id="${2:-1}" | |
[[ $(dispwin \ | |
-d"${dispwin_id}" -V "${profile_filename}") \ | |
=~ 'IS loaded' ]] | |
} | |
format_device_name_brief() { | |
local device_name="${1:+" ${1}"}" | |
local connected_to="${2:+" on ${2}"}" | |
printf 'display%s%s\n' "${device_name}" "${connected_to}" | |
} | |
format_device_name_long() { | |
local device_name="${1:+" ${1}"}" | |
local connected_to="${2:+" on video output ${2}"}" | |
printf 'display%s%s\n' "${device_name}" "${connected_to}" | |
} | |
load_default_profile() { | |
local xrandr_name="${1}" | |
local dispwin_id="${2:-1}" | |
local device=$(colord_device_find_by_xrandr_name \ | |
"${xrandr_name}") | |
local device_model=$(colord_device_get_property \ | |
"${device}" 'Model') | |
local target_brief=$(format_device_name_brief \ | |
'' "${xrandr_name}") | |
local target_long=$(format_device_name_long \ | |
"${device_model}" "${xrandr_name}") | |
local summary_fail="${MESSAGE_FAIL_FOR}${target_brief}" | |
if ! colord_device_has_default_profile "${device}" ; then | |
local body_warning="No profile assigned" | |
body_warning+=" for ${target_long}." | |
log_warning "${summary_fail}" "${body_warning}" | |
return 0 | |
fi | |
local profile=$(colord_device_get_default_profile \ | |
"${device}") | |
local profile_filename=$(colord_profile_get_filename \ | |
"${profile}") | |
local profile_title=$(colord_profile_get_title "${profile}") | |
local summary_target=" for ${target_brief}" | |
local summary_verify_success="Color profile verified" | |
local summary_load_success="Color profile loaded" | |
local body_details="Device:\t${target_long}" | |
body_details+="\nProfile:\t${profile_title}" | |
if dispwin_verify_loaded_profile \ | |
"${profile_filename}" "${dispwin_id}" ; then | |
summary_verify_success+="${summary_target}" | |
log_info "${summary_verify_success}" "${body_details}" | |
return 0 | |
elif dispwin_load_default_profile "${dispwin_id}" ; then | |
summary_load_success+="${summary_target}" | |
log_info "${summary_load_success}" \ | |
"${body_details}" | |
return 0 | |
else | |
log_error "${summary_fail}" \ | |
"${body_details}" | |
return 1 | |
fi | |
} | |
load_default_profiles() { | |
local xrandr_outputs=$(xrandr_get_outputs) | |
if [[ -z "${xrandr_outputs}" ]] ; then | |
log_warning "${MESSAGE_FAIL_ANY}" \ | |
"No active video outputs detected." | |
return | |
fi | |
while IFS=' ' read -a 'fields' -r ; do | |
xrandr_name=${fields[0]} | |
dispwin_id=${fields[1]} | |
if colord_device_with_xrandr_name_exists \ | |
"${xrandr_name}" ; then | |
load_default_profile \ | |
"${xrandr_name}" \ | |
"${dispwin_id}" | |
else | |
local target=$(format_device_name_brief \ | |
'' "${xrandr_name}") | |
log_error "${MESSAGE_FAIL_FOR}${target}" \ | |
"Display on video output" \ | |
"${xrandr_name}" \ | |
"not registered" \ | |
"in profile database." | |
fi | |
done <<< "${xrandr_outputs}" | |
} | |
help_requirements() { | |
printf '%b' "${MESSAGE_SCRIPT} requires" \ | |
" a desktop environment with colord and xiccd" \ | |
" daemons running and Argyll CMS installed." | |
} | |
help_usage() { | |
printf '%b\n' "${APP_TITLE}\n\nUsage: ${PROGNAME} [options]" \ | |
"Options:" \ | |
"\t-h\tshow this help message and exit" \ | |
"\t-n\tuse desktop notifications when run in a terminal" \ | |
"\n$(help_requirements)" | |
} | |
set_signal_handlers() { | |
for signal in INT QUIT TERM ; do | |
trap 'log_error "${MESSAGE_FAIL_ANY}" \ | |
"${MESSAGE_SCRIPT}" \ | |
"caught '${signal}' signal, exiting." ; \ | |
exit 1' ${signal} | |
done | |
} | |
parse_option_arguments() { | |
while getopts "hn" OPT; do | |
case "${OPT}" in | |
h) | |
help_usage | |
exit 0 | |
;; | |
n) | |
USE_NOTIFY=1 | |
;; | |
\?) | |
echo | |
>&2 help_usage | |
exit 1 | |
;; | |
esac | |
done | |
shift $((${OPTIND} - 1)) | |
} | |
main() { | |
parse_option_arguments "${@}" | |
set_signal_handlers | |
tty --silent || USE_NOTIFY=1 | |
load_default_profiles | |
exit 0 | |
} | |
main "${@}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment