ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/keyboard.C
(Generate patch)

Comparing rxvt-unicode/src/keyboard.C (file contents):
Revision 1.12 by root, Sat Feb 12 18:55:04 2005 UTC vs.
Revision 1.21 by root, Fri Jan 6 20:50:58 2006 UTC

3 3
4#ifdef KEYSYM_RESOURCE 4#ifdef KEYSYM_RESOURCE
5 5
6#include <cstring> 6#include <cstring>
7 7
8#include "rxvtperl.h"
8#include "keyboard.h" 9#include "keyboard.h"
9#include "command.h" 10#include "command.h"
11
12/* an intro to the data structure:
13 *
14 * vector keymap[] is grouped.
15 *
16 * inside each group, elements are sorted by the criteria given by compare_priority().
17 * the lookup of keysym is done in two steps:
18 * 1) locate the group corresponds to the keysym;
19 * 2) do a linear search inside the group.
20 *
21 * array hash[] effectively defines a map from a keysym to a group in keymap[].
22 *
23 * each group has its address(the index of first group element in keymap[]),
24 * which is computed and stored in hash[].
25 * hash[] stores the addresses in the form of:
26 * index: 0 I1 I2 I3 In
27 * value: 0...0, A1...A1, A2...A2, A3...A3, ..., An...An
28 * where
29 * A1 = 0;
30 * Ai+1 = N1 + N2 + ... + Ni.
31 * it is computed from hash_budget_size[]:
32 * index: 0 I1 I2 I3 In
33 * value: 0...0, N1, 0...0, N2, 0...0, N3, ..., Nn, 0...0
34 * 0...0, 0.......0, N1.....N1, N1+N2...N1+N2, ... (the compution of hash[])
35 * or we can say
36 * hash_budget_size[Ii] = Ni; hash_budget_size[elsewhere] = 0,
37 * where
38 * set {I1, I2, ..., In} = { hashkey of keymap[0]->keysym, ..., keymap[keymap.size-1]->keysym }
39 * where hashkey of keymap[i]->keysym = keymap[i]->keysym & KEYSYM_HASH_MASK
40 * n(the number of groups) = the number of non-zero member of hash_budget_size[];
41 * Ni(the size of group i) = hash_budget_size[Ii].
42 */
10 43
11#if STOCK_KEYMAP 44#if STOCK_KEYMAP
12//////////////////////////////////////////////////////////////////////////////// 45////////////////////////////////////////////////////////////////////////////////
13// default keycode translation map and keyevent handlers 46// default keycode translation map and keyevent handlers
14 47
39 72
40static void 73static void
41output_string (rxvt_term *rt, const char *str) 74output_string (rxvt_term *rt, const char *str)
42{ 75{
43 if (strncmp (str, "command:", 8) == 0) 76 if (strncmp (str, "command:", 8) == 0)
44 rt->cmd_write ((unsigned char *)str + 8, strlen (str) - 8); 77 rt->cmd_write (str + 8, strlen (str) - 8);
78 else if (strncmp (str, "perl:", 5) == 0)
79 HOOK_INVOKE((rt, HOOK_KEYBOARD_COMMAND, DT_STR, str + 5, DT_END));
45 else 80 else
46 rt->tt_write ((unsigned char *)str, strlen (str)); 81 rt->tt_write (str, strlen (str));
47} 82}
48 83
49static void 84static void
50output_string_meta8 (rxvt_term *rt, unsigned int state, char *buf, int buflen) 85output_string_meta8 (rxvt_term *rt, unsigned int state, char *buf, int buflen)
51{ 86{
58 *ch |= 0x80; 93 *ch |= 0x80;
59 } 94 }
60 else if (rt->meta_char == C0_ESC) /* escape prefix */ 95 else if (rt->meta_char == C0_ESC) /* escape prefix */
61#endif 96#endif
62 { 97 {
63 const unsigned char ch = C0_ESC; 98 const char ch = C0_ESC;
64 rt->tt_write (&ch, 1); 99 rt->tt_write (&ch, 1);
65 } 100 }
66 } 101 }
67 102
68 rt->tt_write ((unsigned char *) buf, buflen); 103 rt->tt_write (buf, buflen);
69} 104}
70 105
71static int 106static int
72format_keyrange_string (const char *str, int keysym_offset, char *buf, int bufsize) 107format_keyrange_string (const char *str, int keysym_offset, char *buf, int bufsize)
73{ 108{
83} 118}
84 119
85//////////////////////////////////////////////////////////////////////////////// 120////////////////////////////////////////////////////////////////////////////////
86// return: #bits of '1' 121// return: #bits of '1'
87#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) 122#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
88# define bitcount(n) (__extension__ ({ uint32_t n__ = (n); __builtin_popcount (n); })) 123# define bitcount(n) (__extension__ ({ uint32_t n__ = (n); __builtin_popcount (n__); }))
89#else 124#else
90static int 125static int
91bitcount (uint16_t n) 126bitcount (uint16_t n)
92{ 127{
93 int i; 128 int i;
157void 192void
158keyboard_manager::register_user_translation (KeySym keysym, unsigned int state, const char *trans) 193keyboard_manager::register_user_translation (KeySym keysym, unsigned int state, const char *trans)
159{ 194{
160 keysym_t *key = new keysym_t; 195 keysym_t *key = new keysym_t;
161 wchar_t *wc = rxvt_mbstowcs (trans); 196 wchar_t *wc = rxvt_mbstowcs (trans);
162 const char *translation = rxvt_wcstoutf8 (wc); 197 char *translation = rxvt_wcstoutf8 (wc);
163 free (wc); 198 free (wc);
164 199
165 if (key && translation) 200 if (key && translation)
166 { 201 {
167 key->keysym = keysym; 202 key->keysym = keysym;
183 strcpy (translation, translation + 4); 218 strcpy (translation, translation + 4);
184 } 219 }
185 else 220 else
186 rxvt_warn ("cannot parse list-type keysym '%s', treating as normal keysym.\n", translation); 221 rxvt_warn ("cannot parse list-type keysym '%s', treating as normal keysym.\n", translation);
187 } 222 }
223 else if (strncmp (translation, "builtin:", 8) == 0)
224 key->type = keysym_t::BUILTIN;
188 225
189 user_keymap.push_back (key); 226 user_keymap.push_back (key);
190 user_translations.push_back (translation); 227 user_translations.push_back (translation);
191 register_keymap (key); 228 register_keymap (key);
192 } 229 }
228bool 265bool
229keyboard_manager::dispatch (rxvt_term *term, KeySym keysym, unsigned int state) 266keyboard_manager::dispatch (rxvt_term *term, KeySym keysym, unsigned int state)
230{ 267{
231 assert (hash[0] == 0 && "register_done() need to be called"); 268 assert (hash[0] == 0 && "register_done() need to be called");
232 269
270 state &= OtherModMask; // mask out uninteresting modifiers
271
233 if (state & term->ModMetaMask) state |= MetaMask; 272 if (state & term->ModMetaMask) state |= MetaMask;
234 if (state & term->ModNumLockMask) state |= NumLockMask; 273 if (state & term->ModNumLockMask) state |= NumLockMask;
235 if (state & term->ModLevel3Mask) state |= Level3Mask; 274 if (state & term->ModLevel3Mask) state |= Level3Mask;
236 275
237 if (!!(term->priv_modes & PrivMode_aplKP) != !!(state & ShiftMask)) 276 if (!!(term->priv_modes & PrivMode_aplKP) != !!(state & ShiftMask))
241 280
242 if (index >= 0) 281 if (index >= 0)
243 { 282 {
244 const keysym_t &key = *keymap [index]; 283 const keysym_t &key = *keymap [index];
245 284
285 if (key.type != keysym_t::BUILTIN)
286 {
246 int keysym_offset = keysym - key.keysym; 287 int keysym_offset = keysym - key.keysym;
247 288
248 wchar_t *wc = rxvt_utf8towcs (key.str); 289 wchar_t *wc = rxvt_utf8towcs (key.str);
249 char *str = rxvt_wcstombs (wc); 290 char *str = rxvt_wcstombs (wc);
250 // TODO: do (some) translations, unescaping etc, here (allow \u escape etc.) 291 // TODO: do (some) translations, unescaping etc, here (allow \u escape etc.)
251 free (wc); 292 free (wc);
252 293
253 switch (key.type) 294 switch (key.type)
254 {
255 case keysym_t::NORMAL:
256 output_string (term, str);
257 break;
258
259 case keysym_t::RANGE:
260 { 295 {
296 case keysym_t::NORMAL:
297 output_string (term, str);
298 break;
299
300 case keysym_t::RANGE:
301 {
261 char buf[STRING_MAX]; 302 char buf[STRING_MAX];
262 303
263 if (format_keyrange_string (str, keysym_offset, buf, sizeof (buf)) > 0) 304 if (format_keyrange_string (str, keysym_offset, buf, sizeof (buf)) > 0)
305 output_string (term, buf);
306 }
307 break;
308
309 case keysym_t::RANGE_META8:
310 {
311 int len;
312 char buf[STRING_MAX];
313
314 len = format_keyrange_string (str, keysym_offset, buf, sizeof (buf));
315 if (len > 0)
316 output_string_meta8 (term, state, buf, len);
317 }
318 break;
319
320 case keysym_t::LIST:
321 {
322 char buf[STRING_MAX];
323
324 char *prefix, *middle, *suffix;
325
326 prefix = str;
327 middle = strchr (prefix + 1, *prefix);
328 suffix = strrchr (middle + 1, *prefix);
329
330 memcpy (buf, prefix + 1, middle - prefix - 1);
331 buf [middle - prefix - 1] = middle [keysym_offset + 1];
332 strcpy (buf + (middle - prefix), suffix + 1);
333
264 output_string (term, buf); 334 output_string (term, buf);
335 }
336 break;
265 } 337 }
266 break;
267 338
268 case keysym_t::RANGE_META8:
269 {
270 int len;
271 char buf[STRING_MAX];
272
273 len = format_keyrange_string (str, keysym_offset, buf, sizeof (buf));
274 if (len > 0)
275 output_string_meta8 (term, state, buf, len);
276 }
277 break;
278
279 case keysym_t::LIST:
280 {
281 char buf[STRING_MAX];
282
283 char *prefix, *middle, *suffix;
284
285 prefix = str;
286 middle = strchr (prefix + 1, *prefix);
287 suffix = strrchr (middle + 1, *prefix);
288
289 memcpy (buf, prefix + 1, middle - prefix - 1);
290 buf [middle - prefix - 1] = middle [keysym_offset + 1];
291 strcpy (buf + (middle - prefix), suffix + 1);
292
293 output_string (term, buf);
294 }
295 break;
296 }
297
298 free (str); 339 free (str);
299 340
300 return true; 341 return true;
342 }
301 } 343 }
302 else 344
303 return false; 345 return false;
304} 346}
305 347
306// purge duplicate keymap entries 348// purge duplicate keymap entries
307void keyboard_manager::purge_duplicate_keymap () 349void keyboard_manager::purge_duplicate_keymap ()
308{ 350{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines