#!/bin/sh # # dpmsmouse -- Disable mouse devices when monitors are off # # Copyright (C) 2018 Patrick "P. J." McDermott # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. set -eu DEFAULT_POLL_TIME=5 debug=0 err() { local fmt="${1}" shift 1 printf "Error: ${fmt}\n" "${@}" 1>&2 return 0 } dbg() { local fmt="${1}" shift 1 case "${debug}" in '1') printf "DEBUG: ${fmt}\n" "${@}" 1>&2 esac return 0 } enable_devices() { local device= dbg 'Enabling devices:' for device in "${@}"; do dbg ' %s' "${device}" xinput --enable "${device}" || : done } disable_devices() { local device= dbg 'Disabling devices:' for device in "${@}"; do dbg ' %s' "${device}" xinput --disable "${device}" || : done } poll() { local poll_time=${1} shift 1 local displays= local prev_state= local displays_on= local displays_off= local display= local status= local dpms= local state= displays="$(printf '%s ' \ /sys/devices/pci????:??/????:??:??.?/drm/card*/card*-*/ \ /sys/devices/pci????:??/????:??:??.?/????:??:??.?/drm/card*/card*-*/)" prev_state='' while :; do displays_on=0 displays_off=0 for display in ${displays}; do [ -f "${display}/status" ] || continue read status 0<"${display}/status" case "${status}" in 'disconnected') continue esac read dpms 0<"${display}/dpms" case "${dpms}" in 'On') displays_on=1;; 'Off') displays_off=1;; esac done state='enable_devices' case ${displays_on} in 0) case ${displays_off} in 1) state='disable_devices' esac esac case "${state}" in "${prev_state}");; *) "${state}" "${@}" prev_state="${state}" ;; esac sleep ${poll_time} done } usage() { printf 'Usage: %s [] [ ...]\n' "${0}" printf '\n' printf 'Options:\n' printf ' -p Poll at least every seconds\n' printf ' -d Enable debugging output\n' } main() { local move_win= local opt= local dir= local dx= local dy= local cur_dt= local new_dt= poll_time=${DEFAULT_POLL_TIME} while getopts 'p:d' opt "${@}"; do case "${opt}" in 'p') case "${OPTARG}" in *[!0-9]* | '') usage 1>&2 return 1 esac poll_time="${OPTARG}" ;; 'd') debug=1;; '?') usage 1>&2 return 1 ;; esac done shift $((${OPTIND} - 1)) if [ ${#} -lt 1 ]; then usage 1>&2 return 1 fi poll ${poll_time} "${@}" return 0 } main "${@}"