]> git.lyx.org Git - lyx.git/blob - src/kbsequence.C
several small and larger changes, read the Changelog
[lyx.git] / src / kbsequence.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *           Copyright 1995 Matthias Ettrich
7  *           Copyright 1995-2000 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12 #include <cstring>
13 #include <X11/Xlib.h>
14
15 #include "gettext.h"
16
17 #ifdef __GNUG__
18 #pragma implementation
19 #endif
20
21 #include "kbsequence.h"
22 #include "kbmap.h"
23 #include "debug.h"
24
25 // The only modifiers that we handle. We want to throw away things
26 // like NumLock. 
27 enum { ModsMask = ShiftMask | ControlMask | Mod1Mask };
28
29
30 // === static functions =================================================== 
31
32
33 /* ---F+------------------------------------------------------------------ *\
34    Function  : printKeysym
35    Called by : kb_sequence::print and printKeyMap. RVDK_PATCH_5
36    Purpose   : prints a keysym, including modifiers.
37    Parameters: key    - keysym
38                mod    - modifiers
39                buf    - string where the result goes
40                maxlen - length of string (including '\0')
41    Returns   : length of printed string if ok, 0 otherwise.
42 \* ---F------------------------------------------------------------------- */
43 extern
44 void printKeysym(unsigned int key, unsigned int mod, string & buf);
45
46
47 // === kb_sequence methods ================================================ 
48
49 /* ---F+------------------------------------------------------------------ *\
50     Function  : kb_sequence::addkey
51     Called by : [user]
52     Purpose   : add a key to the sequence, look up in map and return action
53     Parameters: key  - keysym of key
54                 mod  - modifier mask
55                 nmod - modifier veto mask (unused now)
56     Returns   : action or -1 if error (no map defined or key not found)
57 \* ---F------------------------------------------------------------------- */
58
59 int kb_sequence::addkey(unsigned int key,
60                         unsigned int mod, unsigned int nmod /*= 0*/)
61 {
62         if(length < 0) length = 0;
63
64         if(length + 1 >= size) {
65                 unsigned int * nseq = new unsigned int[size + KB_PREALLOC];
66                 size += KB_PREALLOC;
67                 memcpy(nseq, sequence, length * sizeof(unsigned int));
68                 if(sequence != staticseq) delete sequence;
69                 sequence = nseq;
70                 nseq = new unsigned int[size];
71                 memcpy(nseq, modifiers, length * sizeof(unsigned int));
72                 if(modifiers != staticmod) delete modifiers;
73                 modifiers = nseq;
74         }
75
76         modifiers[length]  = mod + (nmod << 16);
77         sequence[length++] = key;
78    
79         if(curmap)
80                 return curmap->lookup(key, mod, this);
81         
82         return -1;
83 }
84
85
86 /* ---F+------------------------------------------------------------------ *\
87     Function  : kb_sequence::parse
88     Called by : [user]
89     Purpose   : parse a string that holds a key sequence and add the keys
90     Parameters: s - string holding the key sequence
91     Returns   : 0 - if ok, error pos if error
92     Note      : Keys must be separated with whitespace;
93                 Use the keysym names used by XStringToKeysym
94                 Prefixes are S-, C-, M- for shift, control, meta
95 \* ---F------------------------------------------------------------------- */
96
97 int kb_sequence::parse(char const * s)
98 {
99         if(!s[0]) return 1;
100
101         int i = 0;
102         unsigned int mod = 0, nmod = 0;
103         while(s[i]) {
104                 if(s[i] && (s[i]) <= ' ') ++i;
105                 if(!s[i]) break;
106                 
107                 if(s[i + 1] == '-')     { // is implicit that s[i] == true
108                         switch(s[i]) {
109                         case 's': case 'S':
110                                 mod |= ShiftMask;
111                                 i += 2;
112                                 continue;
113                         case 'c': case 'C':
114                                 mod |= ControlMask;
115                                 i += 2;
116                                 continue;
117                         case 'm': case 'M':
118                                 mod |= Mod1Mask;
119                                 i += 2;
120                                 continue;
121                         default:
122                                 return i + 1;
123                         }
124                 } else if(s[i] == '~' && s[i + 1] && s[i + 2] == '-') {
125                         switch(s[i + 1]) {
126                         case 's': case 'S':
127                                 nmod |= ShiftMask;
128                                 i += 3;
129                                 continue;
130                         case 'c': case 'C':
131                                 nmod |= ControlMask;
132                                 i += 3;
133                                 continue;
134                         case 'm': case 'M':
135                                 nmod |= Mod1Mask;
136                                 i += 3;
137                                 continue;
138                         default:
139                                 return i + 2;
140                         }
141                 } else {
142                         string tbuf;
143                         int j = i;
144                         for(; s[j] && s[j] > ' '; ++j)
145                                 tbuf += s[j];    // (!!!check bounds :-)
146                         
147                         KeySym key = XStringToKeysym(tbuf.c_str());
148                         if(key == NoSymbol) {
149                                 lyxerr[Debug::KBMAP]
150                                         << "kbmap.C: No such keysym: "
151                                         << tbuf << endl;
152                                 return j;
153                         }
154                         i = j;
155                         
156                         addkey(key, mod, nmod);
157                         mod = 0;
158                         nmod = 0;
159                 }
160         }
161         return 0;
162 }
163
164
165 /* ---F+------------------------------------------------------------------ *\
166     Function  : kb_sequence::print
167     Called by : [user]
168     Purpose   : print the currently defined sequence into a string
169     Parameters: buf           - string where the result goes
170                 maxlen        - length of string (including '\0')
171                 when_defined  - only  print when sequence is real: length > 0.
172     Returns   : 0, if ok, -1 if string too long
173 \* ---F------------------------------------------------------------------- */
174
175 int kb_sequence::print(string & buf, bool when_defined) const
176 {
177         KeySym key;
178         unsigned int mod;
179         int l = length;
180         if ( l < 0 && !when_defined ) l = -l;
181         
182         for(int i = 0; i < l; ++i) {
183                 key = sequence[i];
184                 mod = modifiers[i] & 0xffff;
185
186                 printKeysym(key, mod, buf);  // RVDK_PATCH_5
187
188                 if(i + 1 < l) {  // append a blank
189                         buf += ' ';
190                 }
191         }
192         return 0;
193 }
194
195
196 /* ---F+------------------------------------------------------------------ *\
197     Function  : kb_sequence::printOptions
198     Called by : [user]
199     Purpose   : print the available key options from the current state in the
200                 sequence. RVDK_PATCH_5
201     Parameters: buf    - string where the result goes
202                 maxlen - length of string (including '\0')
203     Returns   : 0, if ok, -1 if string too long
204 \* ---F------------------------------------------------------------------- */
205
206 int kb_sequence::printOptions(string & buf) const
207 {
208         print(buf, true);
209         
210         if (!curmap) return -1;
211         buf += _("   options: ");
212         curmap->print(buf);
213         return 0;
214 }
215
216
217 /* ---F+------------------------------------------------------------------ *\
218     Function  : kb_sequence::delseq
219     Called by : [user]
220     Purpose   : mark the sequence as deleted
221     Parameters: none
222     Returns   : nothing
223 \* ---F------------------------------------------------------------------- */
224
225 void kb_sequence::delseq()
226 {
227         // negative length marks sequence as deleted, but we can still
228         // print() it or retrieve the last char using getiso()
229         length = -length;
230 }
231
232
233 /* ---F+------------------------------------------------------------------ *\
234    Function  : kb_sequence::getsym
235    Called by : [user], getiso
236    Purpose   : get the keysym of the last key in sequence
237    Parameters: none
238    Returns   : keysym
239 \* ---F------------------------------------------------------------------- */
240
241 unsigned int kb_sequence::getsym() const
242 {
243         int l = length;
244         if(l == 0) return NoSymbol;
245         if(l < 0) l = -l;
246         return sequence[l - 1];
247 }
248
249
250 /* ---F+------------------------------------------------------------------ *\
251     Function  : kb_sequence::getiso
252     Called by : [user]
253     Purpose   : return iso character code of last key, if any
254     Parameters: none
255     Returns   : iso code or 0 if none
256 \* ---F------------------------------------------------------------------- */
257
258 char kb_sequence::getiso() const
259 {
260         int c = getsym();
261         
262         if(c > 0xff)
263                 return '\0';
264         return c;
265 }
266
267
268 /* ---F+------------------------------------------------------------------ *\
269     Function  : kb_sequence::reset
270     Called by : [user]
271     Purpose   : reset sequence to initial state. RVDK_PATCH_5
272     Parameters: none
273     Returns   : void
274 \* ---F------------------------------------------------------------------- */
275
276 void kb_sequence::reset()
277 {
278         delseq();
279         curmap = stdmap;
280         if (length > 0) length = -length;
281 }
282
283 /* === End of File: kbmap.C ============================================== */