summaryrefslogtreecommitdiff
path: root/.local/bin/fix-dpi
blob: 251b0ad5377ae52e27a30bbe357b28d8a4b3ff44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env bash
# Copyright 2019  Luke Shumaker

# env-var: MAX_DPI: integer
# env-var: DRY_RUN: empty/non-empty

( # Phase 1: Probe outputs
	export LC_ALL=C
	xrandr | sed -rn -e 's@(.*) connected( .*)? ([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)( .*)? ([0-9]+)mm x ([0-9]+)mm( .*)?@\1 \3 \4 \8 \9@p' -e 's@^   ([0-9]+)x([0-9]+)i? .*\*.*@ \1 \2@p' | sed '/^\S/{ N; s/\n//; }'
	#                      1             2      3        4         5         6       7      8            9         10                                 1        2
	#                      `-outputName  |      `-fb_xpx `-fb_ypx  `-fb_xoff `-fb_yoff      `- hw_xmm    `- hw_ymm |                                  `-hw_xpx `-hw_ypx
	#                                    `-discard                                  `- discard                     `- discard
) | ( # Phase 2: Translate that to a set of actions to perform
	max_xdpi=${MAX_DPI:-96}
	max_ydpi=${MAX_DPI:-96}

	dpi=$(xrdb -query|sed -n 's/^Xft\.dpi:\s*//p')
	xdpi=${dpi%%x*}
	ydpi=${dpi#*x}
	if (( xdpi > max_xdpi )); then
		max_xdpi=$xdpi
	fi
	if (( ydpi > max_ydpi )); then
		max_ydpi=$ydpi
	fi

	declare -A outputs
	while read -r output fb_xpx fb_ypx hw_xmm hw_ymm hw_xpx hw_ypx; do
		hw_xdpi=$(bc <<<"($hw_xpx*25.4)/$hw_xmm")
		hw_ydpi=$(bc <<<"($hw_ypx*25.4)/$hw_ymm")

		fb_xdpi=$(bc <<<"($fb_xpx*25.4)/$hw_xmm")
		fb_ydpi=$(bc <<<"($fb_ypx*25.4)/$hw_ymm")

		if (( hw_xdpi > max_xdpi )); then
			max_xdpi=$hw_xdpi
		fi
		if (( hw_ydpi > max_ydpi )); then
			max_ydpi=$hw_ydpi
		fi

		if (( fb_xdpi > max_xdpi )); then
			max_xdpi=$fb_xdpi
		fi
		if (( fb_ydpi > max_ydpi )); then
			max_ydpi=$fb_ydpi
		fi

		outputs["$output"]="$hw_xdpi $hw_ydpi"
	done
	echo 'xrandr \'
	printf '  --dpi %q \\\n' "${max_xdpi}x${max_ydpi}"
	for output in "${!outputs[@]}"; do
		read -r xdpi ydpi <<<"${outputs[$output]}"
		printf '  --output %q --scale %q \\\n' "$output" "$(bc <<<"scale=5; $max_xdpi/$xdpi")x$(bc <<<"scale=5; $max_ydpi/$ydpi")"
	done
	echo
	printf "xrdb -merge <<<'Xft.dpi: %s'\n" "${max_xdpi}x${max_ydpi}"
) | ( # Phase 3: Apply those actions
	if [[ -z "$DRY_RUN" ]]; then
		bash -v
	else
		cat
	fi
)