Skip to content

Commit

Permalink
[FEATURE] Improved parallels support for keypresses
Browse files Browse the repository at this point in the history
  • Loading branch information
Ron van der Molen committed Sep 9, 2012
1 parent ea6c693 commit 8787277
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 76 deletions.
76 changes: 76 additions & 0 deletions lib/python/parallels_send_string.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import sys
import prlsdkapi
import string

if len(sys.argv) != 3:
print "Usage: parallels_send_string '<VM_NAME>' '<string>'"
exit()

# Parse arguments
vm_name=sys.argv[1]
# String to use
keynames = sys.argv[2].split(' ');

prlsdk = prlsdkapi.prlsdk
consts = prlsdkapi.prlsdk.consts

# Initialize the Parallels API Library
prlsdk.InitializeSDK(consts.PAM_DESKTOP_MAC)

# Obtain a server object identifying the Parallels Service.
server = prlsdkapi.Server()

# Log in. (local as we do Parallels Desktop
login_job=server.login_local()
login_job.wait()

# Get a list of virtual machines.
# Find the specified virtual machine and
# obtain an object identifying it.
vm_list = server.get_vm_list()
result= vm_list.wait()

print prlsdkapi.prlsdk.consts.ScanCodesList

# Look for the VM with the name speficied on the CLI
found = False
for i in range(result.get_params_count()):
VM = result.get_param_by_index(i)
print VM.get_name()
if VM.get_name() == vm_name:
found = True
break

press = consts.PKE_PRESS
release = consts.PKE_RELEASE

# Access the Remote Desktop Access session
vm_io = prlsdkapi.VmIO()
try:
vm_io.connect_to_vm(VM).wait()
except prlsdkapi.PrlSDKError, e:
print "Error: %s" % e
exit()

for keyname in keynames:
if(keyname != ''):
# Keys can also contain special keys like shift, that has to be pressed before and release after
# eg. SHIFT-C (Press shift, then press C)
keys = keyname.split('#');

for keypress in keys:
scan_code = consts.ScanCodesList[keypress]
vm_io.send_key_event(VM,scan_code,press,50)

# And now the reversed order
# eg. Now release C then SHIFT
for keypress in reversed(keys):
scan_code = consts.ScanCodesList[keypress]
vm_io.send_key_event(VM,scan_code,release,50)

# End the Remote Deskop Access session
vm_io.disconnect_from_vm(VM)

# Logoff and deinitialize the library
server.logoff()
prlsdkapi.deinit_sdk
130 changes: 54 additions & 76 deletions lib/veewee/provider/parallels/box/helper/console_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,11 @@ def send_sequence(sequence)

ui.info "Typing:[#{counter}]: "+s

keycodes=self.string_to_parallels_keycode(s)
# No need to send the state, we always PRESS then RELEASE.
# So we send the whole string at once and press/release every string item
keystring=self.string_to_parallels_keycode_string(s)

# A keycode is a hash {'code' => 'U' , 'state' => 'pressed'}
keycodes.each do |keycode|
unless keycode['code']=="wait"
send_keycode(keycode)
sleep 0.01
else
sleep 1
end
end
#sleep after each sequence (needs to be param)
send_string(keystring);
}

ui.info "Done typing."
Expand All @@ -39,95 +32,76 @@ def send_sequence(sequence)

end

def send_keycode(keycode)
python_script=File.join(File.dirname(__FILE__),'..','..','..','..','..','python','parallels_send_key.py')
command="python #{python_script} '#{self.name}' '#{keycode['code']}' '#{keycode['state']}'"
def send_string(keystring)
python_script=File.join(File.dirname(__FILE__),'..','..','..','..','..','python','parallels_send_string.py')
command="python #{python_script} '#{self.name}' '#{keystring}'"
shell_results=shell_exec("#{command}")
end

# Returns hash
def k2h(key,state)
return { 'code' => key, 'state' => state}
end

# Returns hash
def press2h(key)
k2h(key,'press')
end

# Returns hash
def release2h(key)
k2h(key,'release')
end

# Returns array
def press_release(key)
seq=Array.new
seq << press2h(key)
seq << release2h(key)
return seq
def press_key(key)
return key
end

# Returns array
def shift(sequence)
seq=Array.new
seq << press2h('SHIFT_LEFT')
seq << press_key('SHIFT_LEFT')
sequence.each do |s|
seq << s
end
seq << release2h('SHIFT_LEFT')
return seq
end

def string_to_parallels_keycode(thestring)
def string_to_parallels_keycode_string(thestring)


# Setup one key presses
k=Hash.new
for key in 'A'..'Z'
k[key] = shift(press_release(key))
k[key] = shift(press_key(key))
end

for key in 'a'..'z'
k[key] = press_release(key.upcase)
k[key] = press_key(key.upcase)
end

for key in '0'..'9'
k[key] = press_release(key.upcase)
k[key] = press_key(key.upcase)
end

k['>'] = shift(press_release('GREATER'))
k['.'] = press_release('GREATER')
k['<'] = shift(press_release('LESS'))
k[':'] = shift(press_release('COLON'))
k[';'] = press_release('COLON')
k['/'] = press_release('SLASH')
k[' '] = press_release('SPACE')
k['-'] = press_release('MINUS')
k['\''] = press_release('QUOTE')
k['{'] = press_release('CBRACE_LEFT')
k['}'] = press_release('CBRACE_RIGHT')
k['`'] = press_release('TILDA')
k['~'] = shift(press_release('TILDA'))

k['_'] = shift(press_release('MINUS'))
k['?'] = shift(press_release('SLASH'))
k['"'] = shift(press_release('QUOTE'))
k[')'] = shift(press_release('0'))
k['!'] = shift(press_release('1'))
k['@'] = shift(press_release('2'))
k['#'] = shift(press_release('3'))
k['$'] = shift(press_release('4'))
k['%'] = shift(press_release('5'))
k['^'] = shift(press_release('6'))
k['&'] = shift(press_release('7'))
k['*'] = shift(press_release('8'))
k['('] = shift(press_release('9'))
k['|'] = shift(press_release('BACKSLASH'))
k[','] = press_release('LESS')
k['\\'] = press_release('BACKSLASH')
k['+'] = shift(press_release('PLUS'))
k['='] = press_release('PLUS')
k['>'] = shift(press_key('GREATER'))
k['.'] = press_key('GREATER')
k['<'] = shift(press_key('LESS'))
k[':'] = shift(press_key('COLON'))
k[';'] = press_key('COLON')
k['/'] = press_key('SLASH')
k[' '] = press_key('SPACE')
k['-'] = press_key('MINUS')
k['\''] = press_key('QUOTE')
k['{'] = press_key('CBRACE_LEFT')
k['}'] = press_key('CBRACE_RIGHT')
k['`'] = press_key('TILDA')
k['~'] = shift(press_key('TILDA'))

k['_'] = shift(press_key('MINUS'))
k['?'] = shift(press_key('SLASH'))
k['"'] = shift(press_key('QUOTE'))
k[')'] = shift(press_key('0'))
k['!'] = shift(press_key('1'))
k['@'] = shift(press_key('2'))
k['#'] = shift(press_key('3'))
k['$'] = shift(press_key('4'))
k['%'] = shift(press_key('5'))
k['^'] = shift(press_key('6'))
k['&'] = shift(press_key('7'))
k['*'] = shift(press_key('8'))
k['('] = shift(press_key('9'))
k['|'] = shift(press_key('BACKSLASH'))
k[','] = press_key('LESS')
k['\\'] = press_key('BACKSLASH')
k['+'] = shift(press_key('PLUS'))
k['='] = press_key('PLUS')

# Setup special keys
special=Hash.new;
Expand All @@ -153,10 +127,10 @@ def string_to_parallels_keycode(thestring)
special['<Home>'] = [{ 'code' => 'HOME', 'state' => 'press' }]

for i in 1..12 do
special["<F#{i}>"] = press_release("F#{i}")
special["<F#{i}>"] = press_key("F#{i}")
end

keycodes=Array.new
keycodes= ""

until thestring.length == 0
nospecial=true;
Expand All @@ -165,7 +139,7 @@ def string_to_parallels_keycode(thestring)
#take thestring
#check if it starts with a special key + pop special string
special[key].each do |c|
keycodes << c
keycodes.concat("#{c['code']} ")
end
thestring=thestring.slice(key.length,thestring.length-key.length)
nospecial=false;
Expand All @@ -176,7 +150,11 @@ def string_to_parallels_keycode(thestring)
code=k[thestring.slice(0,1)]
if !code.nil?
code.each do |c|
keycodes << c
if(c == 'SHIFT_LEFT'):
keycodes.concat("#{c}\#")
else
keycodes.concat("#{c} ")
end
end
else
ui.info "no scan code for #{thestring.slice(0,1)}"
Expand Down

0 comments on commit 8787277

Please sign in to comment.