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