ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/dclient/src/backend/ndk/keymap.cpp
Revision: 1.4
Committed: Mon Oct 18 16:38:03 2010 UTC (16 years ago) by sf-pippijn
Branch: MAIN
Changes since 1.3: +0 -2 lines
Log Message:
support msg colours

File Contents

# User Rev Content
1 sf-pippijn 1.1 #include "ndk++/keymap.hh"
2     #include "ndk++/events.hh"
3    
4     #include "adt/string.h"
5    
6     #include <map>
7     #include <stdexcept>
8    
9     using ndk::key;
10    
11     typedef std::map<std::string, key> escape_map;
12    
13     static escape_map const urxvt_keymap = {
14     { "\033[A", key::up },
15     { "\033[B", key::down },
16     { "\033[C", key::right },
17     { "\033[D", key::left },
18    
19     { "\033[a", key::shift_up },
20     { "\033[b", key::shift_down },
21     { "\033[c", key::shift_right },
22     { "\033[d", key::shift_left },
23    
24     { "\033Oa", key::ctrl_up },
25     { "\033Ob", key::ctrl_down },
26     { "\033Oc", key::ctrl_right },
27     { "\033Od", key::ctrl_left },
28    
29     { "\033[3~", key::dc },
30    
31     { "\033[5~", key::pg_up },
32     { "\033[6~", key::pg_dn },
33     { "\033[7~", key::home },
34     { "\033[8~", key::end },
35    
36     { "\033[11~", key::F1 },
37     { "\033[12~", key::F2 },
38     { "\033[13~", key::F3 },
39     { "\033[14~", key::F4 },
40     { "\033[15~", key::F5 },
41     { "\033[17~", key::F6 },
42     { "\033[18~", key::F7 },
43     { "\033[19~", key::F8 },
44     { "\033[20~", key::F9 },
45     { "\033[21~", key::F10 },
46     { "\033[23~", key::F11 },
47     { "\033[24~", key::F12 },
48    
49     { "\033Oq", key::shift_end },
50     { "\033Or", key::shift_down },
51     { "\033Os", key::shift_pg_dn },
52     { "\033Ot", key::shift_left },
53     { "\033Ov", key::shift_right },
54     { "\033Ow", key::shift_home },
55     { "\033Ox", key::shift_up },
56     { "\033Oy", key::shift_pg_up },
57    
58     { "\033[5$", key::shift_pg_up },
59     { "\033[6$", key::shift_pg_dn },
60     { "\033[7$", key::shift_home },
61     { "\033[8$", key::shift_end },
62    
63     { "\033[5^", key::ctrl_pg_up },
64     { "\033[6^", key::ctrl_pg_dn },
65     { "\033[7^", key::ctrl_home },
66     { "\033[8^", key::ctrl_end },
67     };
68    
69     static escape_map const xterm_keymap = {
70     { "\033[A", key::up },
71     { "\033[B", key::down },
72     { "\033[C", key::right },
73     { "\033[D", key::left },
74    
75     { "\033OA", key::up },
76     { "\033OB", key::down },
77     { "\033OC", key::right },
78     { "\033OD", key::left },
79    
80     { "\033[1;2A", key::shift_up },
81     { "\033[1;2B", key::shift_down },
82     { "\033[1;2C", key::shift_right },
83     { "\033[1;2D", key::shift_left },
84    
85     { "\033[1;5A", key::ctrl_up },
86     { "\033[1;5B", key::ctrl_down },
87     { "\033[1;5C", key::ctrl_right },
88     { "\033[1;5D", key::ctrl_left },
89    
90     { "\033[3~", key::dc },
91    
92     { "\033[5~", key::pg_up },
93     { "\033[6~", key::pg_dn },
94     { "\033[H", key::home },
95     { "\033[F", key::end },
96    
97     { "\033OE", key::numpad_center },
98    
99     { "\033OP", key::F1 },
100     { "\033OQ", key::F2 },
101     { "\033OR", key::F3 },
102     { "\033OS", key::F4 },
103     { "\033[15~", key::F5 },
104     { "\033[17~", key::F6 },
105     { "\033[18~", key::F7 },
106     { "\033[19~", key::F8 },
107     { "\033[20~", key::F9 },
108     { "\033[21~", key::F10 },
109     { "\033[23~", key::F11 },
110     { "\033[24~", key::F12 },
111    
112     { "\033Oq", key::shift_end },
113     { "\033Or", key::shift_down },
114     { "\033Os", key::shift_pg_dn },
115     { "\033Ot", key::shift_left },
116     { "\033Ov", key::shift_right },
117     { "\033Ow", key::shift_home },
118     { "\033Ox", key::shift_up },
119     { "\033Oy", key::shift_pg_up },
120    
121     { "\033[5;2~", key::shift_pg_up },
122     { "\033[6;2~", key::shift_pg_dn },
123     { "\033[1;2H", key::shift_home },
124     { "\033[1;2F", key::shift_end },
125    
126     { "\033[5;5~", key::ctrl_pg_up },
127     { "\033[6;5~", key::ctrl_pg_dn },
128     { "\033[1;5H", key::ctrl_home },
129     { "\033[1;5F", key::ctrl_end },
130     };
131    
132     static escape_map const fallback_keymap = xterm_keymap;
133    
134 sf-pippijn 1.3 #include <fstream>
135     #include <iomanip>
136     static std::ofstream logs ("curses.log");
137    
138 sf-pippijn 1.1 static escape_map const &
139     select_keymap ()
140     {
141     if (char const *const term = getenv ("TERM"))
142     {
143 sf-pippijn 1.3 logs << "TERM=" << term << std::endl;
144 sf-pippijn 1.1 if (!strncmp (term, "rxvt"))
145     return urxvt_keymap;
146    
147     if (!strncmp (term, "xterm"))
148     return xterm_keymap;
149     }
150 sf-pippijn 1.3 else
151     logs << "TERM unknown" << std::endl;
152 sf-pippijn 1.1
153     return fallback_keymap;
154     }
155    
156     static escape_map const &keymap = select_keymap ();
157    
158    
159     static bool
160     is_terminator (int const ch)
161     {
162     switch (ch)
163     {
164     case '^':
165     case '~':
166     case '$':
167     case 'a' ... 'z':
168     case 'A' ... 'Z':
169     return true;
170     default:
171     return false;
172     }
173     }
174    
175     static std::string
176     escape (std::string const &s)
177     {
178     std::string res;
179     res.reserve (s.size () + 2 * 4);
180    
181 sf-pippijn 1.2 foreach (char ch, s)
182 sf-pippijn 1.1 #if 0
183     if (isprint (ch))
184     res += s;
185     else
186     #endif
187     {
188     char buf[5];
189     snprintf (buf, sizeof buf, "\\%03o", ch);
190     res += buf;
191     }
192    
193     return res;
194     }
195    
196     bool
197     ndk::has_keymap ()
198     {
199     return &keymap != &fallback_keymap;
200     }
201    
202     ndk::key
203     ndk::parsekey (std::string &esc, int const ch)
204     {
205     key code = key::unknown;
206    
207     logs << "chr: \\" << std::oct << std::setfill ('0') << std::setw (3) << ch << std::dec;
208 sf-pippijn 1.3 #if 0
209     logs << "\nERR: \\" << std::oct << std::setfill ('0') << std::setw (3) << ERR << std::dec;
210     logs << "\nchr == ERR: " << std::boolalpha << (ch == ERR);
211     logs.flush ();
212     #endif
213 sf-pippijn 1.1
214     if (ch == '\033' || !esc.empty ())
215     {
216     code = key::intermediate;
217     esc += ch;
218     logs << ", esc: " << escape (esc);
219     if (!strncmp (esc, "\033[M"))
220     {
221     if (esc.length () == 6)
222     code = key::mouse;
223     }
224     else if (ch != '[' && ch != 'O' && is_terminator (ch))
225     {
226     escape_map::const_iterator found = keymap.find (esc);
227     if (found != keymap.end ())
228     {
229     code = found->second;
230     logs << "\ngot: " << std::oct << std::setfill ('0') << std::setw (3) << int (code) << std::dec;
231     }
232     else
233     {
234     code = key::unknown;
235     logs << "\nunknown escape sequence: " << escape (esc);
236     //throw std::runtime_error ("unknown escape sequence: " + escape (esc));
237     }
238     // finished
239     esc.clear ();
240     }
241     }
242     else if (ch == ERR)
243     code = key::error;
244     else if (ch == '\177') // XXX: special case: are there more?
245     code = key::backspace;
246     else
247     code = key (ch);
248    
249     logs << std::endl;
250    
251     return code;
252     }
253    
254     ndk::mouse
255     ndk::getmouse (std::string &esc)
256     {
257     MEVENT mev { };
258     if (is_keypad (stdscr))
259     {
260 sf-pippijn 1.3 return_val_unless (getmouse (&mev) == OK, { mev });
261 sf-pippijn 1.1 }
262     else
263     {
264     unsigned char const button = esc[3];
265     unsigned char const x = esc[4];
266     unsigned char const y = esc[5];
267    
268     mev.x = x - 33;
269     mev.y = y - 33;
270    
271     mev.bstate |= (button == 32) * BUTTON1_CLICKED;
272     mev.bstate |= (button == 33) * BUTTON2_CLICKED;
273     mev.bstate |= (button == 34) * BUTTON3_CLICKED;
274    
275     esc.clear ();
276     }
277    
278     return { mev };
279     }