aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk')
-rw-r--r--src/FbTk/KeyUtil.cc200
-rw-r--r--src/FbTk/KeyUtil.hh56
-rw-r--r--src/FbTk/TextBox.cc5
3 files changed, 202 insertions, 59 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
diff --git a/src/FbTk/KeyUtil.hh b/src/FbTk/KeyUtil.hh
index 9e872d6..a6051f6 100644
--- a/src/FbTk/KeyUtil.hh
+++ b/src/FbTk/KeyUtil.hh
@@ -19,34 +19,66 @@
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.hh,v 1.1 2003/09/06 15:46:00 fluxgen Exp $ 22// $Id: KeyUtil.hh,v 1.2 2003/10/05 07:20:35 rathnor Exp $
23 23
24#ifndef FBTK_KEYUTIL_HH 24#ifndef FBTK_KEYUTIL_HH
25#define FBTK_KEYUTIL_HH 25#define FBTK_KEYUTIL_HH
26 26
27#include <X11/Xlib.h>
28#include <X11/keysym.h>
29
27namespace FbTk { 30namespace FbTk {
28 31
29class KeyUtil { 32class KeyUtil {
30public: 33public:
34
35 KeyUtil();
36 ~KeyUtil();
37
38 void init();
39 static KeyUtil *instance();
40
41 /**
42 Grab the specified key
43 */
44 static void grabKey(unsigned int key, unsigned int mod);
45
46 /**
47 convert the string to the keysym
48 @return the keysym corresponding to the string, or zero
49 */
50 static unsigned int getKey(const char *keystr);
51
52 /**
53 @return the modifier for the modstr else zero on failure.
54 */
55 static unsigned int KeyUtil::getModifier(const char *modstr);
56
57 /**
58 ungrabs all keys
59 */
60 static void ungrabKeys();
61
31 /** 62 /**
32 Strip out modifiers we want to ignore 63 Strip out modifiers we want to ignore
33 @return the cleaned state number 64 @return the cleaned state number
34 */ 65 */
35 static unsigned int cleanMods(unsigned int mods) { 66 static unsigned int cleanMods(unsigned int mods) {
36 if (!s_init) 67 //remove numlock(Mod2), capslock and scrolllock(Mod5)
37 init(); 68 return mods & ~(LockMask | Mod2Mask | Mod5Mask);
38 //remove numlock, capslock and scrolllock
39 return mods & (~s_capslock_mod & ~s_numlock_mod & ~s_scrolllock_mod);
40 } 69 }
41 70
42 static int capslockMod() { if (!s_init) init(); return s_capslock_mod; } 71 /**
43 static int numlockMod() { if (!s_init) init(); return s_numlock_mod; } 72 Convert the specified key into appropriate modifier mask
44 static int scrolllockMod() { if (!s_init) init(); return s_scrolllock_mod; } 73 @return corresponding modifier mask
45 /// so one can force a reinit of modifiers 74 */
46 static void init(); 75 static unsigned int keycodeToModmask(unsigned int keycode);
76
47private: 77private:
48 static int s_capslock_mod, s_numlock_mod, s_scrolllock_mod; ///< modifiers 78 void loadModmap();
49 static bool s_init; 79
80 XModifierKeymap *m_modmap;
81 static KeyUtil *s_keyutil;
50}; 82};
51 83
52} // end namespace FbTk 84} // end namespace FbTk
diff --git a/src/FbTk/TextBox.cc b/src/FbTk/TextBox.cc
index 01451e4..519b56e 100644
--- a/src/FbTk/TextBox.cc
+++ b/src/FbTk/TextBox.cc
@@ -19,7 +19,7 @@
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: TextBox.cc,v 1.2 2003/09/08 21:26:19 fluxgen Exp $ 22// $Id: TextBox.cc,v 1.3 2003/10/05 07:20:47 rathnor Exp $
23 23
24#include "TextBox.hh" 24#include "TextBox.hh"
25#include "Font.hh" 25#include "Font.hh"
@@ -185,8 +185,7 @@ void TextBox::buttonPressEvent(XButtonEvent &event) {
185 185
186void TextBox::keyPressEvent(XKeyEvent &event) { 186void TextBox::keyPressEvent(XKeyEvent &event) {
187 // strip numlock and scrolllock mask 187 // strip numlock and scrolllock mask
188 event.state &= ~FbTk::KeyUtil::numlockMod(); 188 event.state = KeyUtil::cleanMods(event.state);
189 event.state &= ~FbTk::KeyUtil::scrolllockMod();
190 189
191 KeySym ks; 190 KeySym ks;
192 char keychar[1]; 191 char keychar[1];