- Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathkeycode.py
More file actions
Latest commit
executable file
·99 lines (90 loc) · 4 KB
/
Copy pathkeycode.py
File metadata and controls
executable file
·99 lines (90 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/env python
# http://stackoverflow.com/questions/1918841/how-to-convert-ascii-character-to-cgkeycode */
importctypes
importctypes.util
importCoreFoundation
importFoundation
importobjc
try:
unichr
exceptNameError:
unichr=chr
carbon_path=ctypes.util.find_library('Carbon')
carbon=ctypes.cdll.LoadLibrary(carbon_path)
# We could rely on the fact that kTISPropertyUnicodeKeyLayoutData has
# been the string @"TISPropertyUnicodeKeyLayoutData" since even the
# Classic Mac days. Or we could load it from the framework.
# Unfortunately, the framework doesn't have PyObjC wrappers, and there's
# no easy way to force PyObjC to wrap a CF/ObjC object that it doesn't
# know about. So:
_objc=ctypes.PyDLL(objc._objc.__file__)
_objc.PyObjCObject_New.restype=ctypes.py_object
_objc.PyObjCObject_New.argtypes= [ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
defobjcify(ptr):
return_objc.PyObjCObject_New(ptr, 0, 1)
kTISPropertyUnicodeKeyLayoutData_p=ctypes.c_void_p.in_dll(
carbon, 'kTISPropertyUnicodeKeyLayoutData')
kTISPropertyUnicodeKeyLayoutData=objcify(kTISPropertyUnicodeKeyLayoutData_p)
carbon.TISCopyCurrentKeyboardInputSource.argtypes= []
carbon.TISCopyCurrentKeyboardInputSource.restype=ctypes.c_void_p
carbon.TISGetInputSourceProperty.argtypes= [ctypes.c_void_p, ctypes.c_void_p]
carbon.TISGetInputSourceProperty.restype=ctypes.c_void_p
carbon.LMGetKbdType.argtypes= []
carbon.LMGetKbdType.restype=ctypes.c_uint32
OptionBits=ctypes.c_uint32
UniCharCount=ctypes.c_uint8
UniChar=ctypes.c_uint16
UniChar4=UniChar*4
carbon.UCKeyTranslate.argtypes= [ctypes.c_void_p, # keyLayoutPtr
ctypes.c_uint16, # virtualKeyCode
ctypes.c_uint16, # keyAction
ctypes.c_uint32, # modifierKeyState
ctypes.c_uint32, # keyboardType
OptionBits, # keyTranslateOptions
ctypes.POINTER(ctypes.c_uint32), # deadKeyState
UniCharCount, # maxStringLength
ctypes.POINTER(UniCharCount), # actualStringLength
UniChar4]
carbon.UCKeyTranslate.restype=ctypes.c_uint32# OSStatus
kUCKeyActionDisplay=3
kUCKeyTranslateNoDeadKeysBit=0
kTISPropertyUnicodeKeyLayoutData=ctypes.c_void_p.in_dll(
carbon, 'kTISPropertyUnicodeKeyLayoutData')
defcreateStringForKey(keycode):
keyboard_p=carbon.TISCopyCurrentKeyboardInputSource()
keyboard=objcify(keyboard_p)
layout_p=carbon.TISGetInputSourceProperty(keyboard_p,
kTISPropertyUnicodeKeyLayoutData)
layout=objcify(layout_p)
layoutbytes=layout.bytes()
keysdown=ctypes.c_uint32()
length=UniCharCount()
chars=UniChar4()
retval=carbon.UCKeyTranslate(layoutbytes.tobytes(),
keycode,
kUCKeyActionDisplay,
0,
carbon.LMGetKbdType(),
kUCKeyTranslateNoDeadKeysBit,
ctypes.byref(keysdown),
4,
ctypes.byref(length),
chars)
s=u''.join(unichr(chars[i]) foriinrange(length.value))
CoreFoundation.CFRelease(keyboard)
returns
codedict= {createStringForKey(code): codeforcodeinrange(128)}
defkeyCodeForChar(c):
returncodedict[c]
if__name__=='__main__':
importsys
forarginsys.argv[1:]:
try:
keycode=int(arg)
exceptValueError:
print(u'{}: {}'.format(arg, keyCodeForChar(arg)))
else:
print('{}: {!r}'.format(keycode, createStringForKey(keycode)))
iflen(sys.argv) <2:
forkeycodeinrange(128):
print('{}: {!r}'.format(keycode, createStringForKey(keycode)))