From 1a2c00e1f3c977d075f2f3aa4955362f52470117 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 22 Sep 2019 13:41:39 -0400 Subject: get-dpi, fix-dpi: Add EDID overriding and CSS3-based Z-scaling --- .config/systemd/user/fix-dpi@.service | 2 +- .local/bin/fix-dpi | 28 ++++------- .local/bin/get-dpi | 90 +++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 20 deletions(-) diff --git a/.config/systemd/user/fix-dpi@.service b/.config/systemd/user/fix-dpi@.service index d248cf2..e5dec6c 100644 --- a/.config/systemd/user/fix-dpi@.service +++ b/.config/systemd/user/fix-dpi@.service @@ -8,7 +8,7 @@ Requisite=X11@%i.target Environment=DISPLAY=%I Type=oneshot -ExecStart=/usr/bin/env flock %t/x11-xrdb@%I -c fix-dpi +ExecStart=/usr/bin/env flock %t/x11-xrdb@%I fix-dpi --render-dpi=192x192 SyslogIdentifier=fix-dpi [Install] diff --git a/.local/bin/fix-dpi b/.local/bin/fix-dpi index afcb4a1..0bc5c67 100755 --- a/.local/bin/fix-dpi +++ b/.local/bin/fix-dpi @@ -45,18 +45,19 @@ usage() { printf ' --render-dpi=\n' printf ' Specify what DPI applications should render\n' printf ' at (default: auto)\n' - printf ' --device-dpi=OUTPUT=\n' - printf ' Override the hardware-reported DPI for' - printf ' the X11 output OUTPUT\n' + printf ' --device-geometry=OUTPUT=x[x]\n' + printf ' Override the hardware-reported physical\n' + printf ' dimensions for the X11 output OUTPUT; see\n' + printf ' `get-dpi --help`\n' } set -euE -o pipefail -args=$(getopt -n "${0##*/}" -o 'hn' -l 'help,dry-run,render-dpi:,device-dpi:' -- "$@") || errusage +args=$(getopt -n "${0##*/}" -o 'hn' -l 'help,dry-run,render-dpi:,device-geometry:' -- "$@") || errusage eval "set -- $args" arg_dry_run=false arg_render_dpi=auto -declare -A arg_device_dpi +get_dpi_args=() while (( $# > 0 )); do case "$1" in -h|--help) @@ -81,15 +82,8 @@ while (( $# > 0 )); do esac shift 2 ;; - --device-dpi) - if [[ "$2" != *=* ]]; then - errusage 'Invalid --device-dpi=%q' "$2" - fi - device=${2%=*} - dpi=${2##*=} - if ! arg_device_dpi["$device"]="$(sanitize "${dpi%%x*}" 2>/dev/null)x$(sanitize "${dpi#*x}" 2>/dev/null)"; then - errusage 'Invalid --device-dpi=%q' "$2" - fi + --device-geometry) + get_dpi_args+=("$1=$2") shift 2 ;; --) @@ -102,7 +96,7 @@ if (( $# > 0 )); then errusage fi -dpis="$(get-dpi)" +dpis="$(get-dpi "${get_dpi_args[@]}")" if [[ $arg_render_dpi == auto ]] || [[ $arg_render_dpi == auto-hwonly ]]; then arg_render_xdpi=96 @@ -111,9 +105,6 @@ if [[ $arg_render_dpi == auto ]] || [[ $arg_render_dpi == auto-hwonly ]]; then if [[ $arg_render_dpi == auto-hwonly ]] && [[ $source != X11-RandR-hw ]]; then continue fi - if [[ $source == X11-RandR-hw ]]; then - dpi=${arg_device_dpi["$item"]:-"$dpi"} - fi arg_render_xdpi=$(max "$(round "${dpi%%x*}")" "$arg_render_xdpi") arg_render_ydpi=$(max "$(round "${dpi#*x}")" "$arg_render_ydpi") done <<<"$dpis" @@ -134,7 +125,6 @@ fi if [[ $source != X11-RandR-hw ]]; then continue fi - dpi=${arg_device_dpi["$item"]:-"$dpi"} hw_xdpi="$(sanitize "${dpi%%x*}")" hw_ydpi="$(sanitize "${dpi#*x}")" diff --git a/.local/bin/get-dpi b/.local/bin/get-dpi index 3c9252a..3fba920 100755 --- a/.local/bin/get-dpi +++ b/.local/bin/get-dpi @@ -2,13 +2,76 @@ # Copyright 2019 Luke Shumaker sanitize() { + [[ $? == 0 ]] || return $? printf '%g\n' "$@" } calc() { + [[ $? == 0 ]] || return $? sanitize "$(bc <<<"scale=6; $1")" } +errusage() { + if (( $# > 0 )); then + printf '%s: %s\n' "${0##*/}" "$(printf "$@")" >&2 + fi + printf "Try '%s --help' for more information.\n" "${0##*/}" >&2 + exit 2 +} + +usage() { + printf 'Usage: %s [OPTIONS]\n' "${0##*/}" + printf "Report DPI settings\n" + echo + printf 'OPTIONS:\n': + printf ' -h, --help Show this message\n' + printf ' --device-geometry=OUTPUT=x[x]\n' + printf ' Override the hardware-reported physical\n' + printf ' dimensions for the X11 output OUTPUT; X, Y,\n' + printf ' and Z must either have a suffix of "in" or\n' + printf ' "mm", or be "auto"; providing Z causes the\n' + printf ' the dimensions to be scaled to a reference\n' + printf ' viewing distance of 28in (as described in\n' + printf ' [CSS3-values])\n' + echo + printf '[CSS3-values]: https://www.w3.org/TR/css3-values/#reference-pixel\n' +} + +set -euE -o pipefail +args=$(getopt -n "${0##*/}" -o 'hn' -l 'help,device-geometry:' -- "$@") || errusage +eval "set -- $args" + +declare -A arg_device_geometry +while (( $# > 0 )); do + case "$1" in + -h|--help) + usage + exit 0 + ;; + --device-geometry) + if [[ "$2" != *=* ]]; then + errusage 'Invalid --device-geometry=%q' "$2" + fi + device=${2%=*} + geometry=${2##*=} + re_dim='([0-9]+(.[0-9]+)?(in|mm)|auto)' + re_geo="^${re_dim}x${re_dim}(x${re_dim})?\$" + if ! [[ "$geometry" =~ $re_geo ]]; then + errusage 'Invalid --device-geometry=%q' "$2" + fi + arg_device_geometry["$device"]=$geometry + shift 2 + ;; + --) + shift + break + ;; + esac +done +if (( $# > 0 )); then + errusage +fi + # Xft dpi=$(xrdb -query|sed -n 's/^Xft\.dpi:\s*//p') [[ -n "$dpi" ]] || dpi=96x96 @@ -33,6 +96,33 @@ echo environment+X11-resources GDK-text ${dpi}x${dpi} # `-outputName | `-fb_xpx `-fb_ypx `-fb_xoff `-fb_yoff `- hw_xmm `- hw_ymm | `-hw_xpx `-hw_ypx # `-discard `- discard `- discard ) | while read -r output fb_xpx fb_ypx hw_xmm hw_ymm hw_xpx hw_ypx; do + if [[ -n "${arg_device_geometry["$output"]:-}" ]]; then + IFS=x read override_x override_y override_z <<<"${arg_device_geometry["$output"]}" + case "$override_x" in + *mm) override_xmm="$(sanitize "${override_x%mm}")";; + *in) override_xmm="$(calc "$(sanitize "${override_x%in}")*25.4")";; + auto) override_xmm="$hw_xmm";; + esac + case "$override_y" in + *mm) override_ymm="$(sanitize "${override_y%mm}")";; + *in) override_ymm="$(calc "$(sanitize "${override_y%in}")*25.4")";; + auto) override_ymm="$hw_ymm";; + esac + if [[ "$override_z" == '' || "$override_z" == 'auto' ]]; then + hw_xmm=$override_xmm + hw_ymm=$override_ymm + else + # algorithm from https://www.w3.org/TR/css3-values/#reference-pixel + ref_zmm=711.2 # 28in + case "$override_z" in + *mm) override_zmm="$(sanitize "${override_z%mm}")";; + *in) override_zmm="$(calc "$(sanitize "${override_z%in}")*25.4")";; + esac + hw_xmm=$(calc "(${override_xmm}*${ref_zmm})/${override_zmm}") + hw_ymm=$(calc "(${override_ymm}*${ref_zmm})/${override_zmm}") + fi + fi + hw_xdpi=$(calc "($hw_xpx*25.4)/$hw_xmm") hw_ydpi=$(calc "($hw_ypx*25.4)/$hw_ymm") -- cgit v1.1-4-g5e80