Last active
March 26, 2025 14:27
-
-
Save mvidner/8939289 to your computer and use it in GitHub Desktop.
Translate a string to "sendkey" commands for QEMU.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Translate a string to "sendkey" commands for QEMU. | |
# Martin Vidner, MIT License | |
# https://en.wikibooks.org/wiki/QEMU/Monitor#sendkey_keys | |
# sendkey keys | |
# | |
# You can emulate keyboard events through sendkey command. The syntax is: sendkey keys. To get a list of keys, type sendkey [tab]. Examples: | |
# | |
# sendkey a | |
# sendkey shift-a | |
# sendkey ctrl-u | |
# sendkey ctrl-alt-f1 | |
# | |
# As of QEMU 0.12.5 there are: | |
# shift shift_r alt alt_r altgr altgr_r | |
# ctrl ctrl_r menu esc 1 2 | |
# 3 4 5 6 7 8 | |
# 9 0 minus equal backspace tab | |
# q w e r t y | |
# u i o p ret a | |
# s d f g h j | |
# k l z x c v | |
# b n m comma dot slash | |
# asterisk spc caps_lock f1 f2 f3 | |
# f4 f5 f6 f7 f8 f9 | |
# f10 num_lock scroll_lock kp_divide kp_multiply kp_subtract | |
# kp_add kp_enter kp_decimal sysrq kp_0 kp_1 | |
# kp_2 kp_3 kp_4 kp_5 kp_6 kp_7 | |
# kp_8 kp_9 < f11 f12 print | |
# home pgup pgdn end left up | |
# down right insert delete | |
require "optparse" | |
# incomplete! only what I need now. | |
KEYS = { | |
"%" => "shift-5", | |
"/" => "slash", | |
":" => "shift-semicolon", | |
"=" => "equal", | |
"." => "dot", | |
" " => "spc" | |
} | |
class Main | |
attr_accessor :command | |
attr_accessor :delay_s | |
attr_accessor :keystring | |
def initialize | |
self.command = nil | |
self.delay_s = 0.1 | |
OptionParser.new do |opts| | |
opts.banner = "Usage: sendkeys [-c command_to_pipe_to] STRING\n" + | |
"Where STRING can be 'ls<enter>ls<gt>/dev/null<enter>'" | |
opts.on("-c", "--command COMMAND", | |
"Pipe sendkeys to this commands, individually") do |v| | |
self.command = v | |
end | |
opts.on("-d", "--delay SECONDS", Float, | |
"Delay SECONDS after each key (default: 0.1)") do |v| | |
self.delay_s = v | |
end | |
end.parse! | |
self.keystring = ARGV[0] | |
end | |
def sendkey(qemu_key_name) | |
qemu_cmd = "sendkey #{qemu_key_name}" | |
if command | |
system "echo '#{qemu_cmd}' | #{command}" | |
else | |
puts qemu_cmd | |
$stdout.flush # important when we are piped | |
end | |
sleep delay_s | |
end | |
PATTERN = / | |
\G # where last match ended | |
< [^>]+ > | |
| | |
\G | |
. | |
/x | |
def run | |
keystring.scan(PATTERN) do |match| | |
if match[0] == "<" | |
key_name = match.slice(1..-2) | |
sendkey case key_name | |
when "lt" then "shift-comma" | |
when "gt" then "shift-dot" | |
else key_name | |
end | |
else | |
sendkey KEYS.fetch(match, match) | |
end | |
end | |
end | |
end | |
Main.new.run |
RTFS (qapi/ui.json in qemu 3.1 sources) gives bracket_left and bracket_right for these keys.
@vbwagner oops, sorry, I should have linked to a version which can do all the ASCII characters: https://github.com/mvidner/sendkeys
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Documentation you've based your code upon doesn't mention several key names,. which are really supported
by qemu:
There should also be names for right bracket and left bracket keys, but I haven't be able to just guess them. Probably I should resort
to RTFS.