diff options
Diffstat (limited to 'src/FbTk/KeyUtil.cc')
-rw-r--r-- | src/FbTk/KeyUtil.cc | 200 |
1 files changed, 156 insertions, 44 deletions
diff --git a/src/FbTk/KeyUtil.cc b/src/FbTk/KeyUtil.cc index 54d7c35..71dc22a 100644 --- a/src/FbTk/KeyUtil.cc +++ b/src/FbTk/KeyUtil.cc | |||
@@ -19,63 +19,175 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: KeyUtil.cc,v 1.2 2003/09/08 19:18:22 fluxgen Exp $ | 22 | // $Id: KeyUtil.cc,v 1.3 2003/10/05 07:20:16 rathnor Exp $ |
23 | 23 | ||
24 | #include "KeyUtil.hh" | 24 | #include "KeyUtil.hh" |
25 | #include "App.hh" | 25 | #include "App.hh" |
26 | 26 | ||
27 | #include <X11/keysym.h> | 27 | #include <string> |
28 | 28 | ||
29 | namespace FbTk { | 29 | namespace FbTk { |
30 | 30 | ||
31 | int KeyUtil::s_capslock_mod = 0; | 31 | KeyUtil *KeyUtil::s_keyutil = 0; |
32 | int KeyUtil::s_numlock_mod = 0; | 32 | |
33 | int KeyUtil::s_scrolllock_mod = 0; | 33 | KeyUtil *KeyUtil::instance() { |
34 | bool KeyUtil::s_init = false; | 34 | if (s_keyutil == 0) |
35 | s_keyutil = new KeyUtil(); | ||
36 | return s_keyutil; | ||
37 | } | ||
38 | |||
39 | |||
40 | KeyUtil::KeyUtil() | ||
41 | : m_modmap(0) | ||
42 | { | ||
43 | init(); | ||
44 | } | ||
35 | 45 | ||
36 | void KeyUtil::init() { | 46 | void KeyUtil::init() { |
37 | Display *disp = FbTk::App::instance()->display(); | 47 | loadModmap(); |
38 | 48 | } | |
39 | XModifierKeymap *modmap = XGetModifierMapping(disp); | 49 | |
40 | 50 | KeyUtil::~KeyUtil() { | |
41 | // mask to use for modifier | 51 | if (m_modmap) |
42 | int mods[] = { | 52 | XFreeModifiermap(m_modmap); |
43 | ShiftMask, | 53 | } |
44 | LockMask, | 54 | |
45 | ControlMask, | 55 | void KeyUtil::loadModmap() { |
46 | Mod1Mask, | 56 | if (m_modmap) |
47 | Mod2Mask, | 57 | XFreeModifiermap(m_modmap); |
48 | Mod3Mask, | 58 | |
49 | Mod4Mask, | 59 | m_modmap = XGetModifierMapping(App::instance()->display()); |
50 | Mod5Mask, | 60 | } |
51 | 0 | 61 | |
52 | }; | 62 | |
63 | |||
64 | /** | ||
65 | Grabs a key with the modifier | ||
66 | and with numlock,capslock and scrollock | ||
67 | */ | ||
68 | void KeyUtil::grabKey(unsigned int key, unsigned int mod) { | ||
69 | Display *display = App::instance()->display(); | ||
70 | const unsigned int capsmod = LockMask; | ||
71 | const unsigned int nummod = Mod2Mask; | ||
72 | const unsigned int scrollmod = Mod5Mask; | ||
73 | |||
74 | for (int screen=0; screen<ScreenCount(display); screen++) { | ||
75 | |||
76 | Window root = RootWindow(display, screen); | ||
77 | |||
78 | XGrabKey(display, key, mod, | ||
79 | root, True, | ||
80 | GrabModeAsync, GrabModeAsync); | ||
81 | |||
82 | // Grab with numlock, capslock and scrlock | ||
83 | |||
84 | //numlock | ||
85 | XGrabKey(display, key, mod|nummod, | ||
86 | root, True, | ||
87 | GrabModeAsync, GrabModeAsync); | ||
88 | //scrolllock | ||
89 | XGrabKey(display, key, mod|scrollmod, | ||
90 | root, True, | ||
91 | GrabModeAsync, GrabModeAsync); | ||
92 | //capslock | ||
93 | XGrabKey(display, key, mod|capsmod, | ||
94 | root, True, | ||
95 | GrabModeAsync, GrabModeAsync); | ||
53 | 96 | ||
54 | // find modifiers and set them | 97 | //capslock+numlock |
55 | for (int i = 0, realkey = 0; i < 8; ++i) { | 98 | XGrabKey(display, key, mod|capsmod|nummod, |
56 | for (int key = 0; key < modmap->max_keypermod; ++key, ++realkey) { | 99 | root, True, |
57 | 100 | GrabModeAsync, GrabModeAsync); | |
58 | if (modmap->modifiermap[realkey] == 0) | 101 | |
59 | continue; | 102 | //capslock+scrolllock |
60 | 103 | XGrabKey(display, key, mod|capsmod|scrollmod, | |
61 | KeySym ks = XKeycodeToKeysym(disp, modmap->modifiermap[realkey], 0); | 104 | root, True, |
62 | 105 | GrabModeAsync, GrabModeAsync); | |
63 | switch (ks) { | 106 | |
64 | case XK_Caps_Lock: | 107 | //capslock+numlock+scrolllock |
65 | s_capslock_mod = mods[i]; | 108 | XGrabKey(display, key, mod|capsmod|scrollmod|nummod, |
66 | break; | 109 | root, True, |
67 | case XK_Scroll_Lock: | 110 | GrabModeAsync, GrabModeAsync); |
68 | s_scrolllock_mod = mods[i]; | 111 | |
69 | break; | 112 | //numlock+scrollLock |
70 | case XK_Num_Lock: | 113 | XGrabKey(display, key, mod|nummod|scrollmod, |
71 | s_numlock_mod = mods[i]; | 114 | root, True, |
72 | break; | 115 | GrabModeAsync, GrabModeAsync); |
73 | } | 116 | |
117 | } | ||
118 | |||
119 | } | ||
120 | |||
121 | /** | ||
122 | @return keycode of keystr on success else 0 | ||
123 | */ | ||
124 | unsigned int KeyUtil::getKey(const char *keystr) { | ||
125 | if (!keystr) | ||
126 | return 0; | ||
127 | return XKeysymToKeycode(App::instance()->display(), | ||
128 | XStringToKeysym(keystr)); | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | @return the modifier for the modstr else zero on failure. | ||
133 | */ | ||
134 | unsigned int KeyUtil::getModifier(const char *modstr) { | ||
135 | if (!modstr) | ||
136 | return 0; | ||
137 | struct t_modlist{ | ||
138 | char *str; | ||
139 | unsigned int mask; | ||
140 | bool operator == (const char *modstr) { | ||
141 | return (strcasecmp(str, modstr) == 0 && mask !=0); | ||
74 | } | 142 | } |
143 | } modlist[] = { | ||
144 | {"SHIFT", ShiftMask}, | ||
145 | {"CONTROL", ControlMask}, | ||
146 | {"MOD1", Mod1Mask}, | ||
147 | {"MOD2", Mod2Mask}, | ||
148 | {"MOD3", Mod3Mask}, | ||
149 | {"MOD4", Mod4Mask}, | ||
150 | {"MOD5", Mod5Mask}, | ||
151 | {0, 0} | ||
152 | }; | ||
153 | |||
154 | // find mod mask string | ||
155 | for (unsigned int i=0; modlist[i].str !=0; i++) { | ||
156 | if (modlist[i] == modstr) | ||
157 | return modlist[i].mask; | ||
75 | } | 158 | } |
159 | |||
160 | return 0; | ||
161 | } | ||
76 | 162 | ||
77 | s_init = true; | 163 | /// Ungrabs the keys |
78 | XFreeModifiermap(modmap); | 164 | void KeyUtil::ungrabKeys() { |
165 | Display * display = App::instance()->display(); | ||
166 | for (int screen=0; screen<ScreenCount(display); screen++) { | ||
167 | XUngrabKey(display, AnyKey, AnyModifier, | ||
168 | RootWindow(display, screen)); | ||
169 | } | ||
79 | } | 170 | } |
80 | 171 | ||
172 | unsigned int KeyUtil::keycodeToModmask(unsigned int keycode) { | ||
173 | XModifierKeymap *modmap = instance()->m_modmap; | ||
174 | |||
175 | if (!modmap) return 0; | ||
176 | |||
177 | // search through modmap for this keycode | ||
178 | for (int mod=0; mod < 8; mod++) { | ||
179 | for (int key=0; key < modmap->max_keypermod; ++key) { | ||
180 | // modifiermap is an array with 8 sets of keycodes | ||
181 | // each max_keypermod long, but in a linear array. | ||
182 | if (modmap->modifiermap[modmap->max_keypermod*mod + key] == keycode) { | ||
183 | return (1<<mod); | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | // no luck | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | |||
192 | |||
81 | } // end namespace FbTk | 193 | } // end namespace FbTk |