aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/KeyUtil.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/KeyUtil.cc')
-rw-r--r--src/FbTk/KeyUtil.cc200
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
29namespace FbTk { 29namespace FbTk {
30 30
31int KeyUtil::s_capslock_mod = 0; 31KeyUtil *KeyUtil::s_keyutil = 0;
32int KeyUtil::s_numlock_mod = 0; 32
33int KeyUtil::s_scrolllock_mod = 0; 33KeyUtil *KeyUtil::instance() {
34bool KeyUtil::s_init = false; 34 if (s_keyutil == 0)
35 s_keyutil = new KeyUtil();
36 return s_keyutil;
37}
38
39
40KeyUtil::KeyUtil()
41 : m_modmap(0)
42{
43 init();
44}
35 45
36void KeyUtil::init() { 46void KeyUtil::init() {
37 Display *disp = FbTk::App::instance()->display(); 47 loadModmap();
38 48}
39 XModifierKeymap *modmap = XGetModifierMapping(disp); 49
40 50KeyUtil::~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, 55void 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*/
68void 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*/
124unsigned 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*/
134unsigned 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); 164void 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
172unsigned 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