1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 * Copyright (C) 2006-2016 XNeur Team
17 *
18 */
19
20 #include <X11/XKBlib.h>
21 //#include <X11/Xlib.h>
22 //#include <X11/extensions/XTest.h>
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <unistd.h>
28
29 #include "xnconfig.h"
30
31 #include "switchlang.h"
32 #include "buffer.h"
33 #include "window.h"
34 #include "utils.h"
35 #include "defines.h"
36
37 #include "types.h"
38 #include "log.h"
39 #include "conversion.h"
40 #include "list_char.h"
41
42 #include "event.h"
43
44 extern struct _xneur_config *xconfig;
45 extern struct _window *main_window;
46
get_key_state(int key)47 int get_key_state(int key)
48 {
49 if (main_window->display == NULL)
50 return 0;
51
52 KeyCode key_code = XKeysymToKeycode(main_window->display, key);
53 if (key_code == NoSymbol)
54 return 0;
55
56 XModifierKeymap *map = XGetModifierMapping(main_window->display);
57
58 int key_mask = 0;
59 for (int i = 0; i < 8; i++)
60 {
61 if (map->modifiermap[map->max_keypermod * i] == key_code)
62 key_mask = (1 << i);
63 }
64
65 XFreeModifiermap(map);
66
67 if (key_mask == 0)
68 return 0;
69
70 Window wDummy;
71 int iDummy;
72 unsigned int mask;
73 XQueryPointer(main_window->display, DefaultRootWindow(main_window->display), &wDummy, &wDummy, &iDummy, &iDummy, &iDummy, &iDummy, &mask);
74
75 return ((mask & key_mask) != 0);
76 }
77
event_send_xkey(struct _event * p,KeyCode kc,int modifiers)78 void event_send_xkey(struct _event *p, KeyCode kc, int modifiers)
79 {
80 //XTestGrabControl (main_window->display, True);
81
82 char *app_name = NULL;
83 app_name = get_wm_class_name(p->owner_window);
84
85 int is_delay = xconfig->delay_send_key_apps->exist(xconfig->delay_send_key_apps, app_name, BY_PLAIN);
86 if (is_delay)
87 {
88 usleep(xconfig->send_delay * 1000);
89 }
90
91 p->event.type = KeyPress;
92 p->event.xkey.type = KeyPress;
93 p->event.xkey.window = p->owner_window;
94 p->event.xkey.root = RootWindow(main_window->display, DefaultScreen(main_window->display));
95 p->event.xkey.subwindow = None;
96 p->event.xkey.same_screen = True;
97 p->event.xkey.display = main_window->display;
98 p->event.xkey.state = modifiers;
99 p->event.xkey.keycode = kc;
100 p->event.xkey.time = CurrentTime;
101
102 if (xconfig->dont_send_key_release_apps->exist(xconfig->dont_send_key_release_apps, app_name, BY_PLAIN))
103 {
104 XSendEvent(main_window->display, p->owner_window, TRUE, NoEventMask, &p->event);
105 XFlush(main_window->display);
106 log_message(TRACE, _("The event KeyRelease is not sent to the window (ID %d) with name '%s'"), p->owner_window, app_name);
107 if (app_name != NULL)
108 free(app_name);
109 return;
110 }
111
112 XSendEvent(main_window->display, p->owner_window, TRUE, NoEventMask, &p->event);
113 XFlush(main_window->display);
114
115 if (is_delay)
116 {
117 usleep(xconfig->send_delay * 1000);
118 }
119
120 p->event.type = KeyRelease;
121 p->event.xkey.type = KeyRelease;
122 p->event.xkey.time = CurrentTime;
123
124 XSendEvent(main_window->display, p->owner_window, TRUE, NoEventMask, &p->event);
125 XFlush(main_window->display);
126 //XTestGrabControl (main_window->display, False);
127 if (app_name != NULL)
128 free(app_name);
129 }
130
event_send_backspaces(struct _event * p,int count)131 static void event_send_backspaces(struct _event *p, int count)
132 {
133 for (int i = 0; i < count; i++)
134 {
135 p->send_xkey(p, p->backspace, None);
136 }
137 }
138
event_send_spaces(struct _event * p,int count)139 static void event_send_spaces(struct _event *p, int count)
140 {
141 for (int i = 0; i < count; i++)
142 {
143 p->send_xkey(p, p->space, None);
144 }
145 }
146
event_send_selection(struct _event * p,int count)147 static void event_send_selection(struct _event *p, int count)
148 {
149 for (int i = 0; i < count; i++)
150 p->send_xkey(p, p->left, None);
151
152 for (int i = 0; i < count; i++)
153 p->send_xkey(p, p->right, ShiftMask);
154 }
155
event_send_string(struct _event * p,struct _buffer * str)156 static void event_send_string(struct _event *p, struct _buffer *str)
157 {
158 for (int i = 0; i < str->cur_pos; i++)
159 p->send_xkey(p, str->keycode[i], str->keycode_modifiers[i]);
160 }
161
event_set_owner_window(struct _event * p,Window window)162 static void event_set_owner_window(struct _event *p, Window window)
163 {
164 p->owner_window = window;
165 }
166
event_get_cur_keysym(struct _event * p)167 static KeySym event_get_cur_keysym(struct _event *p)
168 {
169 //return XLookupKeysym(&p->event.xkey, 0);
170
171 KeySym ks;
172
173 /*int nbytes = 0;
174 char str[256+1];
175 XKeyEvent *e = (XKeyEvent *) &p->event;
176 nbytes = XLookupString (e, str, 256, &ks, NULL);
177 if (nbytes) {};
178 return ks;*/
179
180 XKeyEvent *e = (XKeyEvent *) &p->event;
181 ks = XkbKeycodeToKeysym(main_window->display, e->keycode, main_window->keymap->latin_group, 0);
182 if (ks == NoSymbol)
183 ks = XkbKeycodeToKeysym(main_window->display, e->keycode, 0, 0);
184 return ks;
185 }
186
event_get_cur_modifiers(struct _event * p)187 static int event_get_cur_modifiers(struct _event *p)
188 {
189 /*
190 Window wDummy;
191 int iDummy;
192 int mask = 0;
193 unsigned int query_mask;
194 XQueryPointer(main_window->display,
195 (Window)p->event.xkey.window,
196 &wDummy, &wDummy, &iDummy, &iDummy, &iDummy, &iDummy,
197 &query_mask);
198 mask = query_mask & (~get_languages_mask ());
199 */
200
201 int mask = 0;
202
203 if (p->event.xkey.state & ShiftMask) // Shift
204 mask += (1 << 0); // 1
205 if (p->event.xkey.state & LockMask) // CapsLock
206 mask += (1 << 1); // 2
207 if (p->event.xkey.state & ControlMask)// Control
208 mask += (1 << 2); // 4
209 if (p->event.xkey.state & Mod1Mask) // Alt
210 mask += (1 << 3); // 8
211 if (p->event.xkey.state & Mod2Mask) // NumLock
212 mask += (1 << 4); // 16
213 if (p->event.xkey.state & Mod3Mask)
214 mask += (1 << 5); // 32
215 if (p->event.xkey.state & Mod4Mask) // Super (Win)
216 mask += (1 << 6); // 64
217 if (p->event.xkey.state & Mod5Mask) // ISO_Level3_Shift
218 mask += (1 << 7); // 128
219
220 return mask;
221 }
222
event_get_cur_modifiers_by_keysym(struct _event * p)223 static int event_get_cur_modifiers_by_keysym(struct _event *p)
224 {
225 unsigned int mask = 0;
226 int key_sym = p->get_cur_keysym(p);
227
228 if (key_sym == XK_Shift_L || key_sym == XK_Shift_R)
229 mask += (1 << 0);
230 if (key_sym == XK_Caps_Lock)
231 mask += (1 << 1);
232 if (key_sym == XK_Control_L || key_sym == XK_Control_R)
233 mask += (1 << 2);
234 if (key_sym == XK_Alt_L || key_sym == XK_Alt_R)
235 mask += (1 << 3);
236 if (key_sym == XK_Meta_L || key_sym == XK_Meta_R)
237 mask += (1 << 4);
238 if (key_sym == XK_Num_Lock)
239 mask += (1 << 5);
240 if (key_sym == XK_Super_L || key_sym == XK_Super_R)
241 mask += (1 << 6);
242 if (key_sym == XK_Hyper_L || key_sym == XK_Hyper_R || key_sym == XK_ISO_Level3_Shift)
243 mask += (1 << 7);
244
245 return mask;
246 }
247
event_get_next_event(struct _event * p)248 static int event_get_next_event(struct _event *p)
249 {
250 XNextEvent(main_window->display, &(p->event));
251 return p->event.type;
252 }
253
event_send_next_event(struct _event * p)254 static void event_send_next_event(struct _event *p)
255 {
256 p->event.xkey.state = p->get_cur_modifiers(p) | groups[get_curr_keyboard_group()];
257 XSendEvent(main_window->display, p->event.xany.window,FALSE, NoEventMask, &p->event);
258 }
259
event_uninit(struct _event * p)260 static void event_uninit(struct _event *p)
261 {
262 if (p != NULL)
263 free(p);
264
265 log_message(DEBUG, _("Event is freed"));
266 }
267
event_init(void)268 struct _event* event_init(void)
269 {
270 struct _event *p = (struct _event *) malloc(sizeof(struct _event));
271 bzero(p, sizeof(struct _event));
272
273 p->backspace = XKeysymToKeycode(main_window->display, XK_BackSpace);
274 p->left = XKeysymToKeycode(main_window->display, XK_Left);
275 p->right = XKeysymToKeycode(main_window->display, XK_Right);
276 p->space = XKeysymToKeycode(main_window->display, XK_space);
277
278 // Functions mapping
279 p->get_next_event = event_get_next_event;
280 p->send_next_event = event_send_next_event;
281 p->set_owner_window = event_set_owner_window;
282 p->send_xkey = event_send_xkey;
283 p->send_string = event_send_string;
284 p->get_cur_keysym = event_get_cur_keysym;
285 p->get_cur_modifiers = event_get_cur_modifiers;
286 p->get_cur_modifiers_by_keysym = event_get_cur_modifiers_by_keysym;
287 p->send_backspaces = event_send_backspaces;
288 p->send_selection = event_send_selection;
289 p->send_spaces = event_send_spaces;
290 p->uninit = event_uninit;
291
292 return p;
293 }
294