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
|
class KeyboardDetector:
UNKNOWN, PRESS_KEY, KEY_PRESENT, KEY_PRESENT_P, RESULT = list(range(5))
def __init__(self):
self.current_step = -1
f = '/usr/share/console-setup/pc105.tree'
self.fp = open(f)
# Dictionary of keycode -> step.
self.keycodes = {}
self.symbols = []
self.present = -1
self.not_present = -1
self.result = ''
def __del__(self):
if self.fp:
self.fp.close()
def read_step(self, step):
if self.current_step != -1:
valid_steps = (
list(self.keycodes.values()) +
[self.present] + [self.not_present])
if step not in valid_steps:
raise KeyError('invalid argument')
if self.result:
raise Exception('already done')
step_type = KeyboardDetector.UNKNOWN
self.keycodes = {}
self.symbols = []
self.present = -1
self.not_present = -1
self.result = ''
for line in self.fp:
if line.startswith('STEP '):
# This line starts a new step.
if self.current_step == step:
self.current_step = int(line[5:])
return step_type
else:
self.current_step = int(line[5:])
elif self.current_step != step:
continue
elif line.startswith('PRESS '):
# Ask the user to press a character on the keyboard.
if step_type == KeyboardDetector.UNKNOWN:
step_type = KeyboardDetector.PRESS_KEY
if step_type != KeyboardDetector.PRESS_KEY:
raise Exception
self.symbols.append(line[6:].strip())
elif line.startswith('CODE '):
# Direct the evaluating code to process step ## next if the
# user has pressed a key which returned that keycode.
if step_type != KeyboardDetector.PRESS_KEY:
raise Exception
keycode = int(line[5:line.find(' ', 5)])
s = int(line[line.find(' ', 5) + 1:])
self.keycodes[keycode] = s
elif line.startswith('FIND '):
# Ask the user whether that character is present on their
# keyboard.
if step_type == KeyboardDetector.UNKNOWN:
step_type = KeyboardDetector.KEY_PRESENT
else:
raise Exception
self.symbols = [line[5:].strip()]
elif line.startswith('FINDP '):
# Equivalent to FIND, except that the user is asked to consider
# only the primary symbols (i.e. Plain and Shift).
if step_type == KeyboardDetector.UNKNOWN:
step_type = KeyboardDetector.KEY_PRESENT_P
else:
raise Exception
self.symbols = [line[6:].strip()]
elif line.startswith('YES '):
# Direct the evaluating code to process step ## next if the
# user does have this key.
if (step_type != KeyboardDetector.KEY_PRESENT_P and
step_type != KeyboardDetector.KEY_PRESENT):
raise Exception
self.present = int(line[4:].strip())
elif line.startswith('NO '):
# Direct the evaluating code to process step ## next if the
# user does not have this key.
if (step_type != KeyboardDetector.KEY_PRESENT_P and
step_type != KeyboardDetector.KEY_PRESENT):
raise Exception
self.not_present = int(line[3:].strip())
elif line.startswith('MAP '):
# This step uniquely identifies a keymap.
if step_type == KeyboardDetector.UNKNOWN:
step_type = KeyboardDetector.RESULT
self.result = line[4:].strip()
return step_type
else:
raise Exception
|