]> git.lyx.org Git - lyx.git/blob - src/kbsequence.C
bug 183
[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-2001 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 "commandtags.h"
24 #include "debug.h"
25
26 using std::endl;
27
28 // The only modifiers that we handle. We want to throw away things
29 // like NumLock.
30 enum { ModsMask = ShiftMask | ControlMask | Mod1Mask };
31
32
33 int kb_sequence::addkey(unsigned int key, unsigned int mod, unsigned int nmod)
34 {
35         // adding a key to a deleted sequence
36         // starts a new sequence
37         if (deleted_) {
38                 deleted_ = false;
39                 length_ = 0;
40                 sequence.clear();
41                 modifiers.clear();
42         }
43
44         modifiers.push_back(mod + (nmod << 16));
45         sequence.push_back(key);
46         ++length_;
47
48         if (curmap) {
49                 return curmap->lookup(key, mod, this);
50         }
51         
52         return LFUN_UNKNOWN_ACTION;
53 }
54
55
56 string::size_type kb_sequence::parse(string const & s)
57 {
58         if (s.empty()) return 1;
59
60         string::size_type i = 0;
61         unsigned int mod = 0;
62         unsigned int nmod = 0;
63         while (i < s.length()) {
64                 if (s[i] == ' ')
65                         ++i;
66                 if (i >= s.length())
67                         break;
68                 
69                 if (i + 1 < s.length() && s[i + 1] == '-') {
70                         switch (s[i]) {
71                         case 's': case 'S':
72                                 mod |= ShiftMask;
73                                 i += 2;
74                                 continue;
75                         case 'c': case 'C':
76                                 mod |= ControlMask;
77                                 i += 2;
78                                 continue;
79                         case 'm': case 'M':
80                                 mod |= Mod1Mask;
81                                 i += 2;
82                                 continue;
83                         default:
84                                 return i + 1;
85                         }
86                 } else if (i + 2 < s.length() && s[i] == '~'
87                            && s[i + 2] == '-') {
88                         switch (s[i + 1]) {
89                         case 's': case 'S':
90                                 nmod |= ShiftMask;
91                                 i += 3;
92                                 continue;
93                         case 'c': case 'C':
94                                 nmod |= ControlMask;
95                                 i += 3;
96                                 continue;
97                         case 'm': case 'M':
98                                 nmod |= Mod1Mask;
99                                 i += 3;
100                                 continue;
101                         default:
102                                 return i + 2;
103                         }
104                 } else {
105                         string tbuf;
106                         string::size_type j = i;
107                         for (; j < s.length() && s[j] != ' '; ++j)
108                                 tbuf += s[j];    // (!!!check bounds :-)
109                         
110                         KeySym key = XStringToKeysym(tbuf.c_str());
111                         if (key == NoSymbol) {
112                                 lyxerr[Debug::KBMAP]
113                                         << "kbmap.C: No such keysym: "
114                                         << tbuf << endl;
115                                 return j;
116                         }
117                         i = j;
118                         
119                         addkey(key, mod, nmod);
120                         mod = 0;
121                 }
122         }
123         
124         // empty sequence?
125         if (!length_)
126                 return 0;
127
128         // everything is fine
129         return string::npos;
130 }
131
132
133 string const kb_sequence::print() const
134 {
135         string buf;
136
137         if (deleted_)
138                 return buf;
139         
140         for (std::vector<unsigned int>::size_type i = 0; i < length_; ++i) {
141                 buf += kb_keymap::printKeysym(sequence[i], modifiers[i] & 0xffff);
142
143                 // append a blank
144                 if (i + 1 < length_) {
145                         buf += ' ';
146                 }
147         }
148         return buf;
149 }
150
151
152 string const kb_sequence::printOptions() const
153 {
154         string buf;
155
156         buf += print();
157
158         if (!curmap)
159                 return buf;
160
161         buf += _("   options: ");
162         buf += curmap->print();
163         return buf;
164 }
165
166
167 void kb_sequence::mark_deleted()
168 {
169         deleted_ = true;
170 }
171
172
173 unsigned int kb_sequence::getsym() const
174 {
175         if (length_ == 0) return NoSymbol;
176         return sequence[length_ - 1];
177 }
178
179
180 char kb_sequence::getiso() const
181 {
182         unsigned int const c = getsym();
183
184         lyxerr[Debug::KBMAP] << "Raw keysym: "
185                              << std::hex << c << std::dec << endl;
186         lyxerr[Debug::KBMAP] << "byte 3: "
187                              << std::hex << (c & 0xff00) << std::dec
188                              << endl;
189         return kb_keymap::getiso(c);
190 }
191
192
193 void kb_sequence::reset()
194 {
195         mark_deleted();
196         curmap = stdmap;
197 }
198
199 void kb_sequence::clear()
200 {
201         length_ = 0;
202         reset();
203 }