1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2001 The LyX Team.
9 * ====================================================== */
17 #pragma implementation
21 #include "kbsequence.h"
26 // The only modifiers that we handle. We want to throw away things
28 enum { ModsMask = ShiftMask | ControlMask | Mod1Mask };
31 // === static functions ===================================================
34 /* ---F+------------------------------------------------------------------ *\
35 Function : printKeysym
36 Called by : kb_sequence::print and printKeyMap. RVDK_PATCH_5
37 Purpose : prints a keysym, including modifiers.
38 Parameters: key - keysym
40 buf - string where the result goes
41 maxlen - length of string (including '\0')
42 Returns : length of printed string if ok, 0 otherwise.
43 \* ---F------------------------------------------------------------------- */
44 void printKeysym(unsigned int key, unsigned int mod, string & buf)
48 char const * const s = XKeysymToString(key);
50 if (mod & ShiftMask) buf += "S-";
51 if (mod & ControlMask) buf += "C-";
52 if (mod & Mod1Mask) buf += "M-";
57 /* ---F+------------------------------------------------------------------ *\
58 Function : printKeyTab
59 Called by : kb_keymap::print
60 Purpose : print the keysyms found in the given key table. RVDK_PATCH_5
61 Parameters: tabPt - keytable pointer
62 buf - string where the result goes
63 maxLen - length of string (including '\0')
64 Returns : length of printed string.
65 \* ---F------------------------------------------------------------------- */
67 void kb_keymap::printKey(kb_key const & key, string & buf)
69 printKeysym(key.code, key.mod & 0xffff, buf);
73 // This binds a key to an action
74 int kb_keymap::bind(string const & seq, int action)
76 if (lyxerr.debugging(Debug::KBMAP)) {
77 lyxerr << "BIND: Sequence `"
78 << seq << "' Action `"
79 << action << "'" << endl;
84 int const res = k.parse(seq);
88 lyxerr[Debug::KBMAP] << "Parse error at position " << res
89 << " in key sequence '" << seq << "'."
95 /* ---F+------------------------------------------------------------------ *\
96 Function : kb_keymap::lookup
97 Called by : [user], kb_sequence::add()
98 Purpose : look up a key press in a given keymap
99 Parameters: key - the keysym of the key press
100 mod - the modifier mask of the keypress
101 seq - the key-sequence retrieved so far
102 Returns : user defined action; 0 for prefix key, -1 if key not found
103 \* ---F------------------------------------------------------------------- */
105 int kb_keymap::lookup(unsigned int key,
106 unsigned int mod, kb_sequence * seq) const
109 seq->curmap = seq->stdmap;
114 //unsigned int msk1, msk0;
115 //suppress modifier bits we do not handle
118 for (Table::const_iterator cit = table.begin();
119 cit != table.end(); ++cit) {
120 unsigned int const msk1 = cit->mod & 0xffff;
121 unsigned int const msk0 = (cit->mod >> 16) & 0xffff;
122 if (cit->code == key && (mod & ~msk0) == msk1) {
124 if (cit->table.get()) {
125 // this is a prefix key - set new map
126 seq->curmap = cit->table.get();
129 // final key - reset map
130 seq->curmap = seq->stdmap;
137 // error - key not found:
138 seq->curmap = seq->stdmap;
144 /* ---F+------------------------------------------------------------------ *\
145 Function : kb_keymap::print
147 Purpose : Prints all the available keysyms. RVDK_PATCH_5
148 Parameters: buf - string where output goes.
149 maxLen - available length in string, including `\0'.
150 Returns : updated maxLen.
151 \* ---F------------------------------------------------------------------- */
153 void kb_keymap::print(string & buf) const
155 for (Table::const_iterator cit = table.begin();
156 cit != table.end(); ++cit) {
157 printKey((*cit), buf);
163 /* ---F+------------------------------------------------------------------ *\
164 Function : kb_keymap::defkey
166 Purpose : define an action for a key sequence
167 Parameters: seq - the key sequence
168 action - the action to be defined
169 idx - recursion depth
171 \* ---F------------------------------------------------------------------- */
173 int kb_keymap::defkey(kb_sequence * seq, int action, int idx /*= 0*/)
175 unsigned int const code = seq->sequence[idx];
176 if (code == NoSymbol) return -1;
178 unsigned int const modmsk = seq->modifiers[idx];
180 // --- check if key is already there --------------------------------
181 if (table.size() != 0) { // without this I get strange crashes
182 Table::iterator end = table.end();
183 for (Table::iterator it = table.begin(); it != end; ++it) {
184 if (code == it->code && modmsk == it->mod) {
186 if (idx + 1 == seq->length) {
188 seq->print(buf, true);
190 << "Warning: New binding for '"
192 << "' is overriding old binding..."
194 if (it->table.get()) {
199 } else if (!it->table.get()) {
201 seq->print(buf, true);
202 lyxerr << "Error: New binding for '" << buf
203 << "' is overriding old binding..."
207 return it->table->defkey(seq, action,
214 Table::iterator newone = table.insert(table.end(), kb_key());
216 newone->mod = modmsk;
217 if (idx + 1 == seq->length) {
218 newone->action = action;
219 newone->table.reset(0);
222 newone->table.reset(new kb_keymap);
223 return newone->table->defkey(seq, action, idx + 1);
228 string const kb_keymap::keyname(kb_key const & k)
231 printKeysym(k.code, k.mod, buf);
236 // Finds a key for a keyaction, if possible
237 string const kb_keymap::findbinding(int act, string const & prefix) const
240 if (table.empty()) return res;
242 Table::const_iterator end = table.end();
243 for (Table::const_iterator cit = table.begin();
245 if (cit->table.get()) {
246 res += cit->table->findbinding(act,
250 } else if (cit->action == act) {
252 res += prefix + keyname((*cit));
259 /* === End of File: kbmap.C ============================================== */