summaryrefslogtreecommitdiff
path: root/.local/bin/xrotate
blob: c7d9f0dbd1e21e000c8ad9c63b67410054dd449d (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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env bash

# xrandr (graphical output) ############################################
type xrandr &>/dev/null && modules+=(xrandr)

xrandr.get() {
	# FIXME: I don't think simple column counting is reliable.
	# I'll have to study the exact output format.
	xrandr --query --verbose|awk -v OFS=$'\t' '/ connected /{print "xrandr", $1, $6}'
}

xrandr.set() {
	xrandr --orientation "$1"
}

# xsetwacom (touchscreen input) ########################################
type xsetwacom &>/dev/null && modules+=(xsetwacom)

xsetwacom.get() {
	local device
	xsetwacom --list devices|cut -d $'\t' -f1|while read -r device; do
		printf 'xsetwacom\t%s\t%s\n' "$device" "$(xsetwacom --get "$device" Rotate)"
	done | sed -e $'s/\tnone$/\tnormal/' \
		   -e $'s/\tcw$/\tright/' \
		   -e $'s/\tccw$/\tleft/' \
		   -e $'s/\thalf$/\tinverted/'
}

xsetwacom.set() {
	declare -A xrandr2wacom
	xrandr2wacom[normal]=none
	xrandr2wacom[left]=ccw
	xrandr2wacom[right]=cw
	xrandr2wacom[inverted]=half

	local device
	local r=0
	xsetwacom --list devices|cut -d $'\t' -f1|while read -r device; do
		xsetwacom --set "$device" Rotate ${xrandr2wacom[$1]} || r=$?
	done
	return $r
}

# xmodmap (D-pad input) ################################################
type xmodmap &>/dev/null && modules+=(xmodmap)

declare -A xrandr2xmodmap
xrandr2xmodmap[keycode]=' 111   113   114   116  '
xrandr2xmodmap[normal]='  Up    Left  Right Down '
xrandr2xmodmap[left]='    Right Up    Down  Left '
xrandr2xmodmap[right]='   Left  Down  Up    Right'
xrandr2xmodmap[inverted]='Down  Right Left  Up   '

xmodmap.get() {
	local cur=malformed

	local keys=($(xmodmap -pke | grep -f <(printf '^keycode %s =\n' ${xrandr2xmodmap[keycode]})|awk '{print $4}'))
	local k
	for k in normal left right inverted; do
		if [[ "$(echo ${xrandr2xmodmap[$k]})" = "${keys[*]}" ]]; then
			cur=$k
		fi
	done
	printf 'xmodmap\t-\t%s\n' "$cur"
}

xmodmap.set() {
	paste \
	    <(printf '%s\n' ${xrandr2xmodmap[keycode]}) \
	    <(printf '%s\n' ${xrandr2xmodmap[$1]}) \
	| awk '{print "keycode", $1, "=", $2}' | xmodmap -
}

# main #################################################################

usage() {
	. libremessages
	print 'Usage: %q [-h|--help|normal|left|right|inverted]' "${0##*/}"
	print 'Get or set screen rotation.'
	echo
	prose 'Without any arguments, return the screen rotation as
	       reported by supported subsystems.  The output format is:'
	echo
	print '    SUBSYSTEM <tab> DEVICE <tab> STATE <newline>'
}

xget() {
	local r=0
	local module
	for module in "${modules[@]}"; do
		"${module}.get" || r=$?
	done
	return $r
}

xset() {
	local r=0
	local module
	for module in "${modules[@]}"; do
		"${module}.set" "$1" || r=$?
	done
	return $r
}

main() {
	case $# in
		0) xget;;
		1)
			case "$1" in
				normal|left|right|inverted) xset "$1";;
				-h|--help) usage;;
				*) usage >&2; exit 1;;
			esac
			;;
		*) usage >&2; exit 1;;
	esac
}

main "$@"