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.cc228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/FbTk/KeyUtil.cc b/src/FbTk/KeyUtil.cc
new file mode 100644
index 0000000..34f2e4d
--- /dev/null
+++ b/src/FbTk/KeyUtil.cc
@@ -0,0 +1,228 @@
1// KeyUtil.cc for FbTk
2// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: KeyUtil.cc,v 1.6 2003/12/31 11:57:47 fluxgen Exp $
23
24#include "KeyUtil.hh"
25#include "App.hh"
26
27#include <string>
28
29namespace FbTk {
30
31std::auto_ptr<KeyUtil> KeyUtil::s_keyutil;
32
33KeyUtil &KeyUtil::instance() {
34 if (s_keyutil.get() == 0)
35 s_keyutil.reset(new KeyUtil());
36 return *s_keyutil.get();
37}
38
39
40KeyUtil::KeyUtil()
41 : m_modmap(0)
42{
43 init();
44}
45
46void KeyUtil::init() {
47 loadModmap();
48}
49
50KeyUtil::~KeyUtil() {
51 if (m_modmap)
52 XFreeModifiermap(m_modmap);
53}
54
55void KeyUtil::loadModmap() {
56 if (m_modmap)
57 XFreeModifiermap(m_modmap);
58
59 m_modmap = XGetModifierMapping(App::instance()->display());
60 // mask to use for modifier
61 int mods[] = {
62 ShiftMask,
63 LockMask,
64 ControlMask,
65 Mod1Mask,
66 Mod2Mask,
67 Mod3Mask,
68 Mod4Mask,
69 Mod5Mask,
70 0
71 };
72
73 // find modifiers and set them
74 for (int i=0, realkey=0; i<8; ++i) {
75 for (int key=0; key<m_modmap->max_keypermod; ++key, ++realkey) {
76
77 if (m_modmap->modifiermap[realkey] == 0)
78 continue;
79
80 KeySym ks = XKeycodeToKeysym(App::instance()->display(), m_modmap->modifiermap[realkey], 0);
81
82 switch (ks) {
83 case XK_Caps_Lock:
84 m_capslock = mods[i];
85 break;
86 case XK_Scroll_Lock:
87 m_scrolllock = mods[i];
88 break;
89 case XK_Num_Lock:
90 m_numlock = mods[i];
91 break;
92 }
93 }
94 }
95}
96
97
98
99/**
100 Grabs a key with the modifier
101 and with numlock,capslock and scrollock
102*/
103void KeyUtil::grabKey(unsigned int key, unsigned int mod) {
104 Display *display = App::instance()->display();
105 const unsigned int capsmod = instance().capslock();
106 const unsigned int nummod = instance().numlock();
107 const unsigned int scrollmod = instance().scrolllock();
108
109 for (int screen=0; screen<ScreenCount(display); screen++) {
110
111 Window root = RootWindow(display, screen);
112
113 XGrabKey(display, key, mod,
114 root, True,
115 GrabModeAsync, GrabModeAsync);
116
117 // Grab with numlock, capslock and scrlock
118
119 //numlock
120 XGrabKey(display, key, mod|nummod,
121 root, True,
122 GrabModeAsync, GrabModeAsync);
123 //scrolllock
124 XGrabKey(display, key, mod|scrollmod,
125 root, True,
126 GrabModeAsync, GrabModeAsync);
127 //capslock
128 XGrabKey(display, key, mod|capsmod,
129 root, True,
130 GrabModeAsync, GrabModeAsync);
131
132 //capslock+numlock
133 XGrabKey(display, key, mod|capsmod|nummod,
134 root, True,
135 GrabModeAsync, GrabModeAsync);
136
137 //capslock+scrolllock
138 XGrabKey(display, key, mod|capsmod|scrollmod,
139 root, True,
140 GrabModeAsync, GrabModeAsync);
141
142 //capslock+numlock+scrolllock
143 XGrabKey(display, key, mod|capsmod|scrollmod|nummod,
144 root, True,
145 GrabModeAsync, GrabModeAsync);
146
147 //numlock+scrollLock
148 XGrabKey(display, key, mod|nummod|scrollmod,
149 root, True,
150 GrabModeAsync, GrabModeAsync);
151
152 }
153
154}
155
156/**
157 @return keycode of keystr on success else 0
158*/
159unsigned int KeyUtil::getKey(const char *keystr) {
160 if (!keystr)
161 return 0;
162 return XKeysymToKeycode(App::instance()->display(),
163 XStringToKeysym(keystr));
164}
165
166/**
167 @return the modifier for the modstr else zero on failure.
168*/
169unsigned int KeyUtil::getModifier(const char *modstr) {
170 if (!modstr)
171 return 0;
172 struct t_modlist{
173 char *str;
174 unsigned int mask;
175 bool operator == (const char *modstr) {
176 return (strcasecmp(str, modstr) == 0 && mask !=0);
177 }
178 } modlist[] = {
179 {"SHIFT", ShiftMask},
180 {"CONTROL", ControlMask},
181 {"MOD1", Mod1Mask},
182 {"MOD2", Mod2Mask},
183 {"MOD3", Mod3Mask},
184 {"MOD4", Mod4Mask},
185 {"MOD5", Mod5Mask},
186 {0, 0}
187 };
188
189 // find mod mask string
190 for (unsigned int i=0; modlist[i].str !=0; i++) {
191 if (modlist[i] == modstr)
192 return modlist[i].mask;
193 }
194
195 return 0;
196}
197
198/// Ungrabs the keys
199void KeyUtil::ungrabKeys() {
200 Display * display = App::instance()->display();
201 for (int screen=0; screen<ScreenCount(display); screen++) {
202 XUngrabKey(display, AnyKey, AnyModifier,
203 RootWindow(display, screen));
204 }
205}
206
207unsigned int KeyUtil::keycodeToModmask(unsigned int keycode) {
208 XModifierKeymap *modmap = instance().m_modmap;
209
210 if (!modmap) return 0;
211
212 // search through modmap for this keycode
213 for (int mod=0; mod < 8; mod++) {
214 for (int key=0; key < modmap->max_keypermod; ++key) {
215 // modifiermap is an array with 8 sets of keycodes
216 // each max_keypermod long, but in a linear array.
217 if (modmap->modifiermap[modmap->max_keypermod*mod + key] == keycode) {
218 return (1<<mod);
219 }
220 }
221 }
222 // no luck
223 return 0;
224}
225
226
227
228} // end namespace FbTk