├── LICENSE ├── README.md ├── morse_code_acpi.sh ├── morse_code_close.sh └── morse_code_open.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jesse Li 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Open and Shut 2 | 3 | Type in Morse code by repeatedly slamming your laptop shut 4 | 5 | [![output](https://user-images.githubusercontent.com/8890878/78181506-882c1a80-7432-11ea-89c0-bee00e9d183f.gif)](https://youtu.be/UAQ60P61vYw) 6 | 7 | ## Features 8 | * Use a battle-tested encoding trusted by pilots, submariners, and amateur radio nerds 9 | * Type at 100+ words per ~~minute~~ hour 10 | * Innovative [SIGTERM-based concurrency control](https://github.com/veggiedefender/open-and-shut/blob/master/morse_code_close.sh#L8). Semaphores *who??* 11 | * Closing your laptop now types the letter E instead of locking 12 | 13 | ## Setup 14 | 15 | Note: For wayland support, check out the [`wayland` branch](https://github.com/veggiedefender/open-and-shut/tree/wayland). 16 | ### Dependencies 17 | * [xdotool](http://manpages.ubuntu.com/manpages/trusty/man1/xdotool.1.html) 18 | * [acpid](https://wiki.archlinux.org/index.php/Acpid) 19 | 20 | ### Installation 21 | Clone this repository and copy files into `/etc/acpi` 22 | ``` 23 | git clone git@github.com:veggiedefender/open-and-shut.git 24 | sudo cp morse_code_close.sh morse_code_open.sh morse_code_acpi.sh /etc/acpi/ 25 | ``` 26 | 27 | ### Configure acpid 28 | Acpid needs to know how and when to run our scripts. Create a file `/etc/acpi/events/lm_lid` with the following contents: 29 | ``` 30 | event=button/lid.* 31 | action=/etc/acpi/morse_code_acpi.sh 32 | ``` 33 | 34 | ### Disable screen lock 35 | **Temporarily:** Run `systemd-inhibit --what=handle-lid-switch cat` and press Ctrl+C when you're done. 36 | 37 | **Permanently:** Add `HandleLidSwitch=ignore` to `/etc/systemd/logind.conf` and either run `sudo systemctl restart systemd-logind.service` (this will log you out), or reboot your computer. 38 | -------------------------------------------------------------------------------- /morse_code_acpi.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | grep -q close /proc/acpi/button/lid/*/state 4 | if [ $? = 0 ]; then 5 | /etc/acpi/morse_code_close.sh & disown 6 | fi 7 | grep -q open /proc/acpi/button/lid/*/state 8 | if [ $? = 0 ]; then 9 | /etc/acpi/morse_code_open.sh & disown 10 | fi 11 | -------------------------------------------------------------------------------- /morse_code_close.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # If the user closes the lid without opening it again for this duration, then 4 | # suspend the system 5 | suspend_pause=15 6 | 7 | closed_at=$(date +%s%3N) 8 | pkill -f morse_code_open.sh 9 | 10 | echo "$closed_at" > /tmp/morse_code_close.timestamp 11 | 12 | sleep "$suspend_pause" 13 | systemctl suspend 14 | -------------------------------------------------------------------------------- /morse_code_open.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | opened_at=$(date +%s%3N) 4 | pkill -f morse_code_close.sh 5 | 6 | # Max duration of a dot and dash, in milliseconds 7 | dot_length=250 8 | dash_length=3000 9 | 10 | # Duration to pause before typing a letter or space, in seconds 11 | letter_pause=2 12 | space_pause=2 13 | 14 | declare -A morse_letters=( 15 | [.-]=A 16 | [-...]=B 17 | [-.-.]=C 18 | [-..]=D 19 | [.]=E 20 | [..-.]=F 21 | [--.]=G 22 | [....]=H 23 | [..]=I 24 | [.---]=J 25 | [-.-]=K 26 | [.-..]=L 27 | [--]=M 28 | [-.]=N 29 | [---]=O 30 | [.--.]=P 31 | [--.-]=Q 32 | [.-.]=R 33 | [...]=S 34 | [-]=T 35 | [..-]=U 36 | [...-]=V 37 | [.--]=W 38 | [-..-]=X 39 | [-.--]=Y 40 | [--..]=Z 41 | [-----]=0 42 | [.----]=1 43 | [..---]=2 44 | [...--]=3 45 | [....-]=4 46 | [.....]=5 47 | [-....]=6 48 | [--...]=7 49 | [---..]=8 50 | [----.]=9 51 | [.-.-.-]=. 52 | [--..--]=, 53 | [---...]=: 54 | [..--..]=? 55 | [.----.]="'" 56 | [-....-]=- 57 | [-..-.]=/ 58 | [-.--.]='(' 59 | [-.--.-]=')' 60 | [.-..-.]='"' 61 | [-...-]== 62 | [.-.-.]=+ 63 | [.--.-.]=@ 64 | ) 65 | 66 | # Grab environment variables to interact with X 67 | # From https://gist.github.com/AladW/de1c5676d93d05a5a0e1/ 68 | pid=$(pgrep -t tty$(fgconsole) xinit) 69 | pid=$(pgrep -P $pid -n) 70 | import_environment() { 71 | (( pid )) && for var; do 72 | IFS='=' read key val < <(egrep -z "$var" /proc/$pid/environ) 73 | 74 | printf -v "$key" %s "$val" 75 | [[ ${!key} ]] && export "$key" 76 | done 77 | } 78 | import_environment XAUTHORITY USER DISPLAY 79 | 80 | echo "$opened_at" > /tmp/morse_code_open.timestamp 81 | 82 | if [ ! -f /tmp/morse_code_close.timestamp ]; then 83 | exit 0 84 | fi 85 | closed_at=$(cat /tmp/morse_code_close.timestamp) 86 | elapsed="$((opened_at - closed_at))" 87 | 88 | if [ "$elapsed" -lt "$dot_length" ]; then 89 | printf "%s" "." >> /tmp/morse_code_letter 90 | elif [ "$elapsed" -lt "$dash_length" ]; then 91 | printf "%s" "-" >> /tmp/morse_code_letter 92 | else 93 | exit 0 94 | fi 95 | 96 | sleep "$letter_pause" 97 | sequence=$(cat /tmp/morse_code_letter) 98 | if [[ ! -v "morse_letters[$sequence]" ]] ; then 99 | exit 0 100 | fi 101 | xdotool type "${morse_letters[$sequence]}" 102 | rm /tmp/morse_code_letter 103 | 104 | sleep "$space_pause" 105 | xdotool type " " 106 | --------------------------------------------------------------------------------