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