diff options
Diffstat (limited to 'src/FbTk')
-rw-r--r-- | src/FbTk/KeyUtil.cc | 200 | ||||
-rw-r--r-- | src/FbTk/KeyUtil.hh | 56 | ||||
-rw-r--r-- | src/FbTk/TextBox.cc | 5 |
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 | ||
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 |
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 | |||
27 | namespace FbTk { | 30 | namespace FbTk { |
28 | 31 | ||
29 | class KeyUtil { | 32 | class KeyUtil { |
30 | public: | 33 | public: |
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 | |||
47 | private: | 77 | private: |
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 | ||
186 | void TextBox::keyPressEvent(XKeyEvent &event) { | 186 | void 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]; |