Skip to content

Instantly share code, notes, and snippets.

@gesquive
Last active October 29, 2022 09:02
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save gesquive/88d1e56293e1f6ca2330 to your computer and use it in GitHub Desktop.
Get keypress for different platforms
#!/usr/bin/env python3
# get_keypress.py
import sys
import os
def main():
try:
print("press ctrl+c to exit")
seq = ''
get_keypress = linux_getch
if sys.platform in ('linux', 'linux2'):
get_keypress = linux_getch
elif sys.platform == "darwin":
get_keypress = mac_getch
elif sys.platform == "win32":
get_keypress = win_getch
keep_running = True
while keep_running:
seq = get_keypress()
hex_str = str_to_hex(seq)
print('{} '.format(hex_str), end='', flush=True)
if seq == '\x03' or seq == '\x04': # ctrl+c or ctrl+d
keep_running = False
print('\n\r')
except KeyboardInterrupt:
print("\b\b ")
# Here are the various escape sequences we can capture
# '\x0d': 'return'
# '\x7f': 'backspace'
# '\x1b': 'escape'
# '\x01': 'ctrl+a'
# '\x02': 'ctrl+b'
# '\x03': 'ctrl+c'
# '\x04': 'ctrl+d'
# '\x05': 'ctrl+e'
# '\x06': 'ctrl+f'
# '\x1a': 'ctrl+z'
# '\x1b\x4f\x50': 'f1'
# '\x1b\x4f\x51': 'f2'
# '\x1b\x4f\x52': 'f3'
# '\x1b\x4f\x53': 'f4'
# '\x1b\x4f\x31\x35\x7e': 'f5'
# '\x1b\x4f\x31\x37\x7e': 'f6'
# '\x1b\x4f\x31\x38\x7e': 'f7'
# '\x1b\x4f\x31\x39\x7e': 'f8'
# '\x1b\x4f\x31\x30\x7e': 'f9'
# '\x1b\x4f\x31\x31\x7e': 'f10'
# '\x1b\x4f\x31\x33\x7e': 'f11'
# '\x1b\x4f\x31\x34\x7e': 'f12'
# '\x1b\x5b\x41': 'up'
# '\x1b\x5b\x42': 'down'
# '\x1b\x5b\x43': 'right'
# '\x1b\x5b\x44': 'left'
# '\x1b\x4f\x46': 'end'
# '\x1b\x4f\x48': 'home'
# '\x1b\x5b\x32\x7e': 'insert'
# '\x1b\x5b\x33\x7e': 'delete'
# '\x1b\x5b\x35\x7e': 'pageup'
# '\x1b\x5b\x36\x7e': 'pagedown'
def linux_getch():
import sys, tty, termios, fcntl
stdin_fd = sys.stdin.fileno()
old_attr = termios.tcgetattr(stdin_fd)
new_attr = termios.tcgetattr(stdin_fd)
new_attr[3] = new_attr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(stdin_fd, termios.TCSANOW, new_attr)
old_flags = fcntl.fcntl(stdin_fd, fcntl.F_GETFL)
fcntl.fcntl(stdin_fd, fcntl.F_SETFL, old_flags | os.O_NONBLOCK)
seq = ''
try:
tty.setraw(stdin_fd)
keep_running = True
while keep_running:
try:
key = sys.stdin.read(1)
if len(key) > 0:
seq += key
elif len(seq) > 0:
# this is the first empty read since getting a key
return seq
except IOError:
pass
print('\n\r')
except KeyboardInterrupt:
print("\b\b ")
finally:
termios.tcsetattr(stdin_fd, termios.TCSAFLUSH, old_attr)
fcntl.fcntl(stdin_fd, fcntl.F_SETFL, old_flags)
def mac_getch():
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
start_pos = sys.stdin.buffer.tell()
seq = sys.stdin.read(1)
end_pos = sys.stdin.buffer.tell()
seq_length = end_pos - start_pos
if seq_length < 1:
return ''
seq += sys.stdin.read(seq_length-1)
return seq
except KeyboardInterrupt:
print("\b\b ")
pass
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
def win_getch():
import msvcrt
return msvcrt.getch()
def str_to_hex(seq):
hex_str = "\\x"
hex_str += "\\x".join("{:02x}".format(ord(c)) for c in seq)
return hex_str
if __name__ == '__main__':
main()