|
1 # |
|
2 # Slightly modified unix_eventqueue.py. |
|
3 # |
|
4 # Portions Copyright (c) 2005 Nokia Corporation |
|
5 # |
|
6 # Copyright 2000-2004 Michael Hudson mwh@python.net |
|
7 # |
|
8 # All Rights Reserved |
|
9 # |
|
10 # |
|
11 # Permission to use, copy, modify, and distribute this software and |
|
12 # its documentation for any purpose is hereby granted without fee, |
|
13 # provided that the above copyright notice appear in all copies and |
|
14 # that both that copyright notice and this permission notice appear in |
|
15 # supporting documentation. |
|
16 # |
|
17 # THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO |
|
18 # THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
19 # AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, |
|
20 # INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER |
|
21 # RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF |
|
22 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|
23 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
24 |
|
25 # Bah, this would be easier to test if curses/terminfo didn't have so |
|
26 # much non-introspectable global state. |
|
27 |
|
28 from pyrepl import keymap |
|
29 from pyrepl.console import Event |
|
30 import dumbcurses as curses |
|
31 import sys |
|
32 |
|
33 _keynames = { |
|
34 "delete" : "kdch1", |
|
35 "down" : "kcud1", |
|
36 "end" : "kend", |
|
37 "enter" : "kent", |
|
38 "f1" : "kf1", "f2" : "kf2", "f3" : "kf3", "f4" : "kf4", |
|
39 "f5" : "kf5", "f6" : "kf6", "f7" : "kf7", "f8" : "kf8", |
|
40 "f9" : "kf9", "f10" : "kf10", "f11" : "kf11", "f12" : "kf12", |
|
41 "f13" : "kf13", "f14" : "kf14", "f15" : "kf15", "f16" : "kf16", |
|
42 "f17" : "kf17", "f18" : "kf18", "f19" : "kf19", "f20" : "kf20", |
|
43 "home" : "khome", |
|
44 "insert" : "kich1", |
|
45 "left" : "kcub1", |
|
46 "page down" : "knp", |
|
47 "page up" : "kpp", |
|
48 "right" : "kcuf1", |
|
49 "up" : "kcuu1", |
|
50 } |
|
51 |
|
52 class EventQueue(object): |
|
53 def __init__(self): |
|
54 our_keycodes = {} |
|
55 for key, tiname in _keynames.items(): |
|
56 keycode = curses.tigetstr(tiname) |
|
57 if keycode: |
|
58 our_keycodes[keycode] = unicode(key) |
|
59 our_keycodes['\177'] = u'backspace' |
|
60 # our_keycodes[tcgetattr(fd)[6][VERASE]] = u'backspace' |
|
61 self.k = self.ck = keymap.compile_keymap(our_keycodes) |
|
62 self.events = [] |
|
63 self.buf = [] |
|
64 def get(self): |
|
65 if self.events: |
|
66 return self.events.pop(0) |
|
67 else: |
|
68 return None |
|
69 def empty(self): |
|
70 return not self.events |
|
71 def insert(self, event): |
|
72 self.events.append(event) |
|
73 def push(self, char): |
|
74 # print "Handling char %r"%char |
|
75 # print >>sys.stderr,"Handling char %r"%char |
|
76 if char in self.k: |
|
77 k = self.k[char] |
|
78 if isinstance(k, dict): |
|
79 # print >>sys.stderr,"In multi-key sequence chr "+char+" dict "+str(k) |
|
80 self.buf.append(char) |
|
81 self.k = k |
|
82 else: |
|
83 # print >>sys.stderr,"Finished multi-key sequence:"+str(self.buf) |
|
84 self.events.append(Event('key', k, ''.join(self.buf) + char)) |
|
85 self.buf = [] |
|
86 self.k = self.ck |
|
87 elif self.buf: |
|
88 # print >>sys.stderr,"Aborted multi-key sequence %r chr %r dict %r"%(self.buf,char,self.k) |
|
89 # print >>sys.stderr,"%r %r %r %r %r %r %r %r %r"%(char,'0',char=='0',self.k.has_key('0'),self.k.has_key(char),len(char),char[0],ord(char),ord('0')) |
|
90 |
|
91 self.events.extend([Event('key', c, c) for c in self.buf]) |
|
92 self.buf = [] |
|
93 self.k = self.ck |
|
94 self.push(char) |
|
95 else: |
|
96 self.events.append(Event('key', char, char)) |