Odin/scripts/nightwing-move-state-sources.sh

113 lines
3.1 KiB
Shell

#!/bin/sh
set -eu
controller_id_from_hidraw() {
hidraw="$1"
python3 - "$hidraw" <<'PY'
import fcntl
import os
import sys
path = sys.argv[1]
HIDIOCGFEATURE = lambda length: 0xC0000000 | (length << 16) | (0x48 << 8) | 0x07
try:
fd = os.open(path, os.O_RDWR | os.O_NONBLOCK)
buf = bytearray(16)
buf[0] = 4
fcntl.ioctl(fd, HIDIOCGFEATURE(len(buf)), buf, True)
os.close(fd)
print(''.join(f'{byte:02x}' for byte in reversed(buf[1:7])))
except Exception:
try:
os.close(fd)
except Exception:
pass
sys.exit(1)
PY
}
hidraw_for_js() {
js="$1"
cursor="$(readlink -f "/sys/class/input/$(basename "$js")/device" 2>/dev/null || true)"
while [ -n "$cursor" ] && [ "$cursor" != "/" ]; do
if [ -d "$cursor/hidraw" ]; then
for raw in "$cursor"/hidraw/hidraw*; do
[ -e "$raw" ] || continue
printf '/dev/%s\n' "$(basename "$raw")"
return 0
done
fi
cursor="$(dirname "$cursor")"
done
return 1
}
emit_candidates() {
for js in /dev/input/js*; do
[ -e "$js" ] || continue
props="$(udevadm info -q property -n "$js" 2>/dev/null || true)"
uevent="/sys/class/input/$(basename "$js")/device/device/uevent"
uevent_text="$(cat "$uevent" 2>/dev/null || true)"
is_nav=0
case "$props
$uevent_text" in
*ID_VENDOR_ID=054c*ID_MODEL_ID=03d5*|*ID_MODEL=Motion_Controller*|*HID_ID=0005:0000054C:000003D5*|*HID_ID=0003:0000054C:000003D5*)
;;
*ID_MODEL=Navigation_Controller*|*ID_USB_MODEL=Navigation_Controller*|*ID_MODEL_ID=042f*ID_VENDOR_ID=054c*|*ID_VENDOR_ID=054c*ID_MODEL_ID=042f*|*HID_ID=0005:0000054C:0000042F*|*HID_ID=0003:0000054C:0000042F*|*Sony_Navigation_Controller*|*Sony\ Navigation\ Controller*)
is_nav=1
;;
*)
continue
;;
esac
bus="$(printf '%s\n' "$props" | awk -F= '$1=="ID_BUS"{print $2; exit}')"
uniq="$(printf '%s\n' "$uevent_text" | awk -F= '$1=="HID_UNIQ"{print $2; exit}' | tr -d ':')"
path_tag="$(printf '%s\n' "$props" | awk -F= '$1=="ID_PATH_TAG"{print $2; exit}' | tr -c 'A-Za-z0-9_' '_' | sed 's/_*$//')"
hidraw="$(hidraw_for_js "$js" || true)"
controller_id=""
if [ -n "$hidraw" ]; then
controller_id="$(controller_id_from_hidraw "$hidraw" 2>/dev/null || true)"
fi
if [ "$is_nav" = "1" ] && [ -n "$uniq" ]; then
id="nav-$uniq"
elif [ "$is_nav" = "1" ] && [ -n "$path_tag" ]; then
id="nav-usb-$path_tag"
elif [ "$is_nav" = "1" ]; then
id="nav-$(basename "$js")"
elif [ -n "$controller_id" ]; then
id="move-$controller_id"
elif [ "$bus" = "bluetooth" ] && [ -n "$uniq" ]; then
id="move-$uniq"
elif [ -n "$path_tag" ]; then
id="move-usb-$path_tag"
else
id="move-$(basename "$js")"
fi
score=1
case "$uevent_text" in
*HID_ID=0005:0000054C:000003D5*) score=2 ;;
esac
printf '%s %s %s\n' "$id" "$score" "$js"
done
}
emit_candidates | awk '
{
id = $1
score = $2 + 0
path = $3
if (!(id in best_score) || score >= best_score[id]) {
best_score[id] = score
best_path[id] = path
}
}
END {
for (id in best_path) {
print id "=" best_path[id]
}
}
'