1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2000 The LyX Team.
9 * ====================================================== */
17 #pragma implementation
21 #include "kbsequence.h"
24 // The only modifiers that we handle. We want to throw away things
26 enum { ModsMask = ShiftMask | ControlMask | Mod1Mask };
29 // === static functions ===================================================
32 /* ---F+------------------------------------------------------------------ *\
33 Function : printKeysym
34 Called by : kb_sequence::print and printKeyMap. RVDK_PATCH_5
35 Purpose : prints a keysym, including modifiers.
36 Parameters: key - keysym
38 buf - string where the result goes
39 maxlen - length of string (including '\0')
40 Returns : length of printed string if ok, 0 otherwise.
41 \* ---F------------------------------------------------------------------- */
42 void printKeysym(unsigned int key, unsigned int mod, string & buf)
46 char * s = XKeysymToString(key);
48 if (mod & ShiftMask) buf += "S-";
49 if (mod & ControlMask) buf += "C-";
50 if (mod & Mod1Mask) buf += "M-";
55 /* ---F+------------------------------------------------------------------ *\
56 Function : printKeyTab
57 Called by : kb_keymap::print
58 Purpose : print the keysyms found in the given key table. RVDK_PATCH_5
59 Parameters: tabPt - keytable pointer
60 buf - string where the result goes
61 maxLen - length of string (including '\0')
62 Returns : length of printed string.
63 \* ---F------------------------------------------------------------------- */
65 void kb_keymap::printKey(kb_key const & key, string & buf)
67 printKeysym(key.code, key.mod & 0xffff, buf);
71 // This binds a key to an action
72 int kb_keymap::bind(char const * seq, int action)
76 int res = k.parse(seq);
80 lyxerr[Debug::KBMAP] << "Parse error at position " << res
81 << " in key sequence '" << seq << "'."
87 /* ---F+------------------------------------------------------------------ *\
88 Function : kb_keymap::lookup
89 Called by : [user], kb_sequence::add()
90 Purpose : look up a key press in a given keymap
91 Parameters: key - the keysym of the key press
92 mod - the modifier mask of the keypress
93 seq - the key-sequence retrieved so far
94 Returns : user defined action; 0 for prefix key, -1 if key not found
95 \* ---F------------------------------------------------------------------- */
97 int kb_keymap::lookup(unsigned int key,
98 unsigned int mod, kb_sequence * seq) const
101 seq->curmap = seq->stdmap;
106 unsigned int msk1, msk0;
107 //suppress modifier bits we do not handle
110 for (Table::const_iterator cit = table.begin();
111 cit != table.end(); ++cit) {
112 msk1 = (*cit).mod & 0xffff;
113 msk0 = ((*cit).mod >> 16) & 0xffff;
114 if ((*cit).code == key && (mod & ~msk0) == msk1) {
117 // this is a prefix key - set new map
118 seq->curmap = (*cit).table;
121 // final key - reset map
122 seq->curmap = seq->stdmap;
124 return (*cit).action;
129 // error - key not found:
130 seq->curmap = seq->stdmap;
136 /* ---F+------------------------------------------------------------------ *\
137 Function : kb_keymap::print
139 Purpose : Prints all the available keysyms. RVDK_PATCH_5
140 Parameters: buf - string where output goes.
141 maxLen - available length in string, including `\0'.
142 Returns : updated maxLen.
143 \* ---F------------------------------------------------------------------- */
145 void kb_keymap::print(string & buf) const
147 for (Table::const_iterator cit = table.begin();
148 cit != table.end(); ++cit) {
149 printKey((*cit), buf);
155 /* ---F+------------------------------------------------------------------ *\
156 Function : kb_keymap::defkey
158 Purpose : define an action for a key sequence
159 Parameters: seq - the key sequence
160 action - the action to be defined
161 idx - recursion depth
163 \* ---F------------------------------------------------------------------- */
165 int kb_keymap::defkey(kb_sequence * seq, int action, int idx /*= 0*/)
167 unsigned int code = seq->sequence[idx];
168 if(code == NoSymbol) return -1;
170 unsigned int modmsk = seq->modifiers[idx];
172 // --- check if key is already there --------------------------------
173 if (table.size() != 0) // without this I get strange crashes
174 for (Table::iterator it = table.begin(); it != table.end(); ++it) {
175 if (code == (*it).code && modmsk == (*it).mod) {
177 if (idx + 1 == seq->length) {
179 seq->print(buf, true);
181 << "Warning: New binding for '"
183 << "' is overriding old binding..."
189 (*it).action = action;
191 } else if (!(*it).table) {
193 seq->print(buf, true);
194 lyxerr << "Error: New binding for '" << buf
195 << "' is overriding old binding..."
199 return (*it).table->defkey(seq, action,
205 Table::iterator newone = table.insert(table.end(), kb_key());
206 (*newone).code = code;
207 (*newone).mod = modmsk;
208 if (idx + 1 == seq->length) {
209 (*newone).action = action;
213 (*newone).table = new kb_keymap;
214 return (*newone).table->defkey(seq, action, idx + 1);
219 /* ---F+------------------------------------------------------------------ *\
220 Function : kb_keymap::~kb_keymap
221 Called by : [destructor]
222 Purpose : free keymap and its descendents
225 \* ---F------------------------------------------------------------------- */
227 kb_keymap::~kb_keymap()
229 // This could be done by a destructor in kb_key.
230 for(Table::iterator it = table.begin(); it != table.end(); ++it) {
236 string kb_keymap::keyname(kb_key const & k)
239 printKeysym(k.code, k.mod, buf);
244 // Finds a key for a keyaction, if possible
245 string kb_keymap::findbinding(int act) const
248 if (table.empty()) return res;
250 for(Table::const_iterator cit = table.begin();
251 cit != table.end(); ++cit) {
253 string suffix = (*cit).table->findbinding(act);
254 suffix = strip(suffix, ' ');
255 suffix = strip(suffix, ']');
256 suffix = frontStrip(suffix, '[');
257 if (!suffix.empty()) {
258 res += "[" + keyname((*cit)) + " "
261 } else if ((*cit).action == act) {
262 res += "[" + keyname((*cit)) + "] ";
268 /* === End of File: kbmap.C ============================================== */