100 lines
No EOL
2.1 KiB
Ruby
Executable file
100 lines
No EOL
2.1 KiB
Ruby
Executable file
#!/usr/bin/env ruby
|
|
require 'socket'
|
|
|
|
# Path to QEMU monitor socket
|
|
sock_path = "/tmp/qemu-monitor.sock"
|
|
|
|
# Connect to UNIX socket
|
|
sock = UNIXSocket.new(sock_path)
|
|
|
|
# Read greeting from QEMU (optional)
|
|
puts sock.readline rescue nil
|
|
|
|
# Function to send a single keystroke
|
|
def send_key(sock, key)
|
|
cmd = "sendkey #{key}\n"
|
|
puts ">>> #{cmd.strip}"
|
|
sock.write(cmd)
|
|
end
|
|
|
|
def char_to_key(ch)
|
|
case ch
|
|
# Control characters
|
|
when "\n" then "ret"
|
|
when "\t" then "tab"
|
|
when " " then "spc"
|
|
when "\e" then "esc"
|
|
when "\b" then "backspace"
|
|
|
|
# Lowercase letters
|
|
when "a".."z" then ch
|
|
|
|
# Uppercase letters (shift + letter)
|
|
when "A".."Z" then "shift-#{ch.downcase}"
|
|
|
|
# Digits
|
|
when "0".."9" then ch
|
|
|
|
# Shifted number row
|
|
when "!" then "shift-1"
|
|
when "@" then "shift-2"
|
|
when "#" then "shift-3"
|
|
when "$" then "shift-4"
|
|
when "%" then "shift-5"
|
|
when "^" then "shift-6"
|
|
when "&" then "shift-7"
|
|
when "*" then "shift-8"
|
|
when "(" then "shift-9"
|
|
when ")" then "shift-0"
|
|
|
|
when "-" then "minus"
|
|
when "_" then "shift-minus"
|
|
when "=" then "equal"
|
|
when "+" then "shift-equal"
|
|
when "[" then "bracket_left"
|
|
when "{" then "shift-bracket_left"
|
|
when "]" then "bracket_right"
|
|
when "}" then "shift-bracket_right"
|
|
when "\\" then "backslash"
|
|
when "|" then "shift-backslash"
|
|
when ";" then "semicolon"
|
|
when ":" then "shift-semicolon"
|
|
when "'" then "apostrophe"
|
|
when "\"" then "shift-apostrophe"
|
|
when "," then "comma"
|
|
when "<" then "shift-comma"
|
|
when "." then "dot"
|
|
when ">" then "shift-dot"
|
|
when "/" then "slash"
|
|
when "?" then "shift-slash"
|
|
when "`" then "grave_accent"
|
|
when "~" then "shift-grave_accent"
|
|
|
|
else
|
|
raise "Unsupported character: #{ch.inspect}"
|
|
end
|
|
end
|
|
|
|
if ARGV[0]
|
|
puts ARGV[0]
|
|
input = ARGV[0]
|
|
puts "Typing: #{input.inspect}"
|
|
|
|
input.chars.each do |ch|
|
|
send_key(sock, char_to_key(ch))
|
|
sleep 0.1
|
|
end
|
|
|
|
else
|
|
# Example: type "hello<Enter>"
|
|
%w[p a s s ret].each do |k|
|
|
send_key(sock, k)
|
|
sleep 0.1
|
|
end
|
|
end
|
|
|
|
sock.close
|
|
|
|
|
|
# (qemu) screendump /Volumes/Cache/homes/debian/guaset.ppm
|
|
# ffmpeg -y -i guaset.ppm guest.png |