--- a/tuikit/driver_curses.py Sun Jan 20 00:49:19 2013 +0100
+++ b/tuikit/driver_curses.py Wed Jan 23 00:50:23 2013 +0100
@@ -9,41 +9,47 @@
class DriverCurses(Driver):
- xterm_codes = (
+ key_codes = (
(0x09, 'tab' ),
(0x0a, 'enter' ),
(0x7f, 'backspace' ),
(0x1b, 'escape' ),
- (0x1b,0x4f,0x50, 'f1' ),
- (0x1b,0x4f,0x51, 'f2' ),
- (0x1b,0x4f,0x52, 'f3' ),
- (0x1b,0x4f,0x53, 'f4' ),
- (0x1b,0x5b,0x31,0x35,0x7e, 'f5' ),
- (0x1b,0x5b,0x31,0x37,0x7e, 'f6' ),
- (0x1b,0x5b,0x31,0x38,0x7e, 'f7' ),
- (0x1b,0x5b,0x31,0x39,0x7e, 'f8' ),
- (0x1b,0x5b,0x31,0x7e, 'home' ), # linux
- (0x1b,0x5b,0x32,0x30,0x7e, 'f9' ),
- (0x1b,0x5b,0x32,0x31,0x7e, 'f10' ),
- (0x1b,0x5b,0x32,0x33,0x7e, 'f11' ),
- (0x1b,0x5b,0x32,0x34,0x7e, 'f12' ),
- (0x1b,0x5b,0x32,0x7e, 'insert' ),
- (0x1b,0x5b,0x33,0x7e, 'delete' ),
- (0x1b,0x5b,0x34,0x7e, 'end' ), # linux
- (0x1b,0x5b,0x35,0x7e, 'pageup' ),
- (0x1b,0x5b,0x36,0x7e, 'pagedown' ),
- (0x1b,0x5b,0x41, 'up' ),
- (0x1b,0x5b,0x42, 'down' ),
- (0x1b,0x5b,0x43, 'right' ),
- (0x1b,0x5b,0x44, 'left' ),
- (0x1b,0x5b,0x46, 'end' ),
- (0x1b,0x5b,0x48, 'home' ),
- (0x1b,0x5b,0x4d, 'mouse' ),
- (0x1b,0x5b,0x5b,0x41, 'f1' ), # linux
- (0x1b,0x5b,0x5b,0x42, 'f2' ), # linux
- (0x1b,0x5b,0x5b,0x43, 'f3' ), # linux
- (0x1b,0x5b,0x5b,0x44, 'f4' ), # linux
- (0x1b,0x5b,0x5b,0x45, 'f5' ), # linux
+ (0x1b,0x4f,0x50, 'f1' ), # xterm
+ (0x1b,0x4f,0x51, 'f2' ), # xterm
+ (0x1b,0x4f,0x52, 'f3' ), # xterm
+ (0x1b,0x4f,0x53, 'f4' ), # xterm
+ (0x1b,0x5b, 'CSI' ), # see csi_codes
+ )
+
+ # http://en.wikipedia.org/wiki/ANSI_escape_code
+ csi_codes = (
+ # code param key name
+ (0x7e, 1, 'home' ), # linux
+ (0x7e, 2, 'insert' ),
+ (0x7e, 3, 'delete' ),
+ (0x7e, 4, 'end' ), # linux
+ (0x7e, 5, 'pageup' ),
+ (0x7e, 6, 'pagedown' ),
+ (0x7e, 15, 'f5' ),
+ (0x7e, 17, 'f6' ),
+ (0x7e, 18, 'f7' ),
+ (0x7e, 19, 'f8' ),
+ (0x7e, 20, 'f9' ),
+ (0x7e, 21, 'f10' ),
+ (0x7e, 23, 'f11' ),
+ (0x7e, 24, 'f12' ),
+ (0x41, 1, 'up' ),
+ (0x42, 1, 'down' ),
+ (0x43, 1, 'right' ),
+ (0x44, 1, 'left' ),
+ (0x46, 1, 'end' ), # xterm
+ (0x48, 1, 'home' ), # xterm
+ (0x4d, None, 'mouse' ),
+ (0x5b,0x41, 1, 'f1' ), # linux
+ (0x5b,0x42, 1, 'f2' ), # linux
+ (0x5b,0x43, 1, 'f3' ), # linux
+ (0x5b,0x44, 1, 'f4' ), # linux
+ (0x5b,0x45, 1, 'f5' ), # linux
)
color_map = {
@@ -280,7 +286,6 @@
res += [('keypress', None, str(chr(c)))]
else:
- #self.top.keypress(None, unicode(chr(c)))
self.inputqueue_unget(c)
res += self.process_control_chars()
@@ -328,7 +333,7 @@
def process_control_chars(self):
- codes = self.xterm_codes
+ codes = self.key_codes
matchingcodes = []
match = None
consumed = []
@@ -379,8 +384,8 @@
','.join(['0x%x'%x for x in consumed]))
return [('keypress', 'Unknown', None)]
- if keyname == 'mouse':
- return self.process_xterm_mouse()
+ if keyname == 'CSI':
+ return self.process_control_sequence()
return [('keypress', keyname, None)]
@@ -413,6 +418,81 @@
return out
+ def process_control_sequence(self):
+ codes = self.csi_codes
+ debug_seq = [0x1b, 0x5b]
+ c = self.inputqueue_get_wait()
+ debug_seq.append(c)
+
+ # numeric parameters?
+ params = []
+ if chr(c).isdigit():
+ params.append(chr(c))
+ while True:
+ c = self.inputqueue_get_wait()
+ debug_seq.append(c)
+ if chr(c).isdigit():
+ params[-1] += chr(c)
+ elif chr(c) == ';':
+ params.append('')
+ else:
+ break
+ params = [int(x) for x in params]
+ if len(params) == 0:
+ params = [1]
+
+ # filter codes using
+ while True:
+ matching_codes = []
+ for code in codes:
+ if len(code) > 2 and code[0] == c:
+ matching_codes.append(code[1:])
+ codes = matching_codes
+
+ if len(codes) == 0:
+ # no match -> unknown code
+ seq = ','.join(['0x%x' % x for x in debug_seq])
+ self.log.debug('Unknown control sequence: %s', seq)
+ return [('keypress', 'Unknown:' + seq, None)]
+ elif len(codes) == 1:
+ # one match -> we got the winner
+ break
+ elif len(codes[0]) == 2:
+ # more than one matching, but no more chars to check
+ # will be sorted out using parameters
+ break
+ else:
+ # more than one matching -> continue loop
+ c = self.inputqueue_get_wait()
+ debug_seq.append(c)
+
+ # filter codes using first parameter
+ matching_codes = []
+ for code in codes:
+ if params[0] == code[0] or params[0] is None:
+ matching_codes.append(code)
+
+ if len(matching_codes) == 0:
+ # no match -> unknown code
+ seq = ','.join(['0x%x' % x for x in debug_seq])
+ self.log.debug('Unknown control sequence: %s', seq)
+ return [('keypress', 'Unknown:' + seq, None)]
+
+ if len(matching_codes) > 1:
+ raise Exception('Internal error: invalid csi_codes, more than one matching')
+
+ keyname = matching_codes[0][1]
+
+ if keyname == 'mouse':
+ return self.process_xterm_mouse()
+
+ # modifiers
+ mod = 0
+ if len(params) > 1:
+ mod = params[1] - 1
+
+ return [('keypress', keyname, None, mod)]
+
driverclass = DriverCurses