1 /***************************************************************************
2 xbindkeys : a program to bind keys to commands under X11.
3 -------------------
4 begin : Sat Oct 13 14:11:34 CEST 2001
5 copyright : (C) 2001 by Philippe Brochard
6 email : hocwp@free.fr
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "keys.h"
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/wait.h>
25 #include <X11/keysym.h>
26 #include "xbindkeys.h"
27 #include "keys.h"
28 #include "config.h"
29 #include "options.h"
30 #include "grab_key.h"
31
32
33 #define STR_KEY_LEN 1000
34
35 int nb_keys;
36 Keys_t *keys;
37
38 extern char rc_file[512];
39
40 static char *modifier_string[] = { "Control", "Shift", "Alt", "Mod2",
41 "Mod3", "Mod4", "Mod5"
42 };
43
44
45 int
init_keys(void)46 init_keys (void)
47 {
48 nb_keys = 0;
49 keys = NULL;
50
51 return 0;
52 }
53
54 void
close_keys(void)55 close_keys (void)
56 {
57 int i;
58
59 for (i = 0; i < nb_keys; i++)
60 free_key (&keys[i]);
61
62 if (keys != NULL)
63 {
64 free (keys);
65 keys = NULL;
66 }
67
68 nb_keys = 0;
69 }
70
71
72
73 int
add_key(KeyType_t type,EventType_t event_type,KeySym keysym,KeyCode keycode,unsigned int button,unsigned int modifier,char * command,SCM function)74 add_key (KeyType_t type, EventType_t event_type, KeySym keysym, KeyCode keycode,
75 unsigned int button, unsigned int modifier, char *command, SCM function)
76 {
77 Keys_t *keys_bis = NULL;
78 int i;
79
80 if (keysym == 0 && keycode == 0 && button == 0)
81 {
82 fprintf (stderr, "Warning: unkown key in RC file : %s\n", rc_file);
83 return (-1);
84 }
85
86 /* make new array keys_bis */
87 keys_bis = (Keys_t *) malloc ((nb_keys + 1) * sizeof (Keys_t));
88 if (keys_bis == NULL)
89 return (-1);
90
91 if (keys != NULL)
92 {
93 /* copy keys in keys_bis */
94 for (i = 0; i < nb_keys; i++)
95 {
96 keys_bis[i] = keys[i];
97 }
98
99 /* delete old keys array */
100 free (keys);
101 }
102
103 /* make keys_bis as keys */
104 keys = keys_bis;
105
106 modifier &= ~(numlock_mask | capslock_mask | scrolllock_mask);
107
108 /* set key */
109 if (type == SYM)
110 {
111 set_keysym (&keys[nb_keys], event_type, keysym, modifier, command, function);
112 }
113 else if (type == BUTTON)
114 {
115 set_button (&keys[nb_keys], event_type, button, modifier, command, function);
116 }
117 else
118 {
119 set_keycode (&keys[nb_keys], event_type, keycode, modifier, command, function);
120 }
121
122 /* new key */
123 nb_keys += 1;
124
125 return (0);
126 }
127
128
129
130
131
132
133 void
show_key_binding(Display * d)134 show_key_binding (Display * d)
135 {
136 int i;
137 int last_verbose = verbose;
138
139 verbose = 1;
140
141 for (i = 0; i < nb_keys; i++)
142 {
143 print_key (d, &keys[i]);
144 }
145
146 verbose = last_verbose;
147 }
148
149
150
151 void
modifier_to_string(unsigned int modifier,char * str)152 modifier_to_string (unsigned int modifier, char *str)
153 {
154 str[0] = '\0';
155
156 if (modifier & ControlMask)
157 {
158 if (str[0])
159 strncat (str, "+", STR_KEY_LEN);
160 strncat (str, modifier_string[0], STR_KEY_LEN);
161 }
162
163 if (modifier & ShiftMask)
164 {
165 if (str[0])
166 strncat (str, "+", STR_KEY_LEN);
167 strncat (str, modifier_string[1], STR_KEY_LEN);
168 }
169
170
171 if (modifier & Mod1Mask)
172 {
173 if (str[0])
174 strncat (str, "+", STR_KEY_LEN);
175 strncat (str, modifier_string[2], STR_KEY_LEN);
176 }
177
178 if (modifier & Mod2Mask)
179 {
180 if (str[0])
181 strncat (str, "+", STR_KEY_LEN);
182 strncat (str, modifier_string[3], STR_KEY_LEN);
183 }
184
185 if (modifier & Mod3Mask)
186 {
187 if (str[0])
188 strncat (str, "+", STR_KEY_LEN);
189 strncat (str, modifier_string[4], STR_KEY_LEN);
190 }
191
192 if (modifier & Mod4Mask)
193 {
194 if (str[0])
195 strncat (str, "+", STR_KEY_LEN);
196 strncat (str, modifier_string[5], STR_KEY_LEN);
197 }
198
199 if (modifier & Mod5Mask)
200 {
201 if (str[0])
202 strncat (str, "+", STR_KEY_LEN);
203 strncat (str, modifier_string[6], STR_KEY_LEN);
204 }
205 }
206
207
208 void
print_key(Display * d,Keys_t * key)209 print_key (Display * d, Keys_t * key)
210 {
211 char str[STR_KEY_LEN];
212 int keysyms_per_keycode_return;
213
214 if (verbose)
215 {
216 if (key->type == SYM)
217 {
218 modifier_to_string (key->modifier, str);
219
220 printf ("\"%s\"\n %s%s%s%s\n",
221 key->command != NULL ? key->command : ( key->function != 0 ? "(Scheme function)" : "NoCommand" ),
222 key->event_type == PRESS ? "" : "Release + ",
223 str, str[0] ? " + " : "", XKeysymToString (key->key.sym));
224 }
225 else if (key->type == BUTTON)
226 {
227 printf ("\"%s\"\n %sm:0x%x + b:%d (mouse)\n",
228 key->command != NULL ? key->command : ( key->function != 0 ? "(Scheme function)" : "NoCommand" ),
229 key->event_type == PRESS ? "" : "Release + ",
230 key->modifier, key->key.button);
231 }
232 else
233 {
234 printf ("\"%s\"\n %sm:0x%x + c:%d\n",
235 key->command != NULL ? key->command : ( key->function != 0 ? "(Scheme function)" : "NoCommand" ),
236 key->event_type == PRESS ? "" : "Release + ",
237 key->modifier, key->key.code);
238 if (d != NULL)
239 {
240 modifier_to_string (key->modifier, str);
241 printf (" %s%s%s%s\n",
242 str,
243 str[0] ? " + " : "",
244 key->event_type == PRESS ? "" : "Release + ",
245 (XKeysymToString (*XGetKeyboardMapping(d, key->key.code, 1, &keysyms_per_keycode_return)) != NULL) ?
246 XKeysymToString (*XGetKeyboardMapping(d, key->key.code, 1, &keysyms_per_keycode_return)) : "NoSymbol");
247 }
248 }
249 }
250 }
251
252
253 void
set_keysym(Keys_t * key,EventType_t event_type,KeySym keysym,unsigned int modifier,char * command,SCM function)254 set_keysym (Keys_t * key, EventType_t event_type, KeySym keysym,
255 unsigned int modifier, char *command, SCM function)
256 {
257 key->type = SYM;
258 key->event_type = event_type;
259 key->key.sym = keysym;
260 key->modifier = modifier;
261
262 if (command != NULL)
263 {
264 key->command = (char *) malloc ((strlen (command) + 1) * sizeof (char));
265
266 if (key->command != NULL)
267 strncpy (key->command, command, strlen (command) + 1);
268 }
269 else
270 {
271 key->command = NULL;
272 }
273
274 key->function = function;
275
276 // printf("******************* ICICICICICI *********************\n");
277 //#ifdef GUILE_FLAG
278 // printf(" name=%d\n", SCM_IMP (key->function));
279 //#endif
280
281 // scm_permanent_object (key->function);
282 }
283
284 void
set_keycode(Keys_t * key,EventType_t event_type,KeyCode keycode,unsigned int modifier,char * command,SCM function)285 set_keycode (Keys_t * key, EventType_t event_type, KeyCode keycode,
286 unsigned int modifier, char *command, SCM function)
287 {
288 key->type = CODE;
289 key->event_type = event_type;
290 key->key.code = keycode;
291 key->modifier = modifier;
292
293 if (command != NULL)
294 {
295 key->command = (char *) malloc ((strlen (command) + 1) * sizeof (char));
296
297 if (key->command != NULL)
298 strncpy (key->command, command, strlen (command) + 1);
299 }
300 else
301 {
302 key->command = NULL;
303 }
304
305 key->function = function;
306 }
307
308
309 void
set_button(Keys_t * key,EventType_t event_type,unsigned int button,unsigned int modifier,char * command,SCM function)310 set_button (Keys_t * key, EventType_t event_type, unsigned int button,
311 unsigned int modifier, char *command, SCM function)
312 {
313 key->type = BUTTON;
314 key->event_type = event_type;
315 key->key.button = button;
316 key->modifier = modifier;
317
318 if (command != NULL)
319 {
320 key->command = (char *) malloc ((strlen (command) + 1) * sizeof (char));
321
322 if (key->command != NULL)
323 strncpy (key->command, command, strlen (command) + 1);
324 }
325 else
326 {
327 key->command = NULL;
328 }
329
330 key->function = function;
331 }
332
333
334
335
336 void
free_key(Keys_t * key)337 free_key (Keys_t * key)
338 {
339 key->type = SYM;
340 key->event_type = PRESS;
341 key->key.sym = 0;
342 key->modifier = 0;
343
344 if (key->command != NULL)
345 free (key->command);
346
347 key->function = 0;
348 }
349
350
351
352
353 int
remove_key(KeyType_t type,EventType_t event_type,KeySym keysym,KeyCode keycode,unsigned int button,unsigned int modifier)354 remove_key (KeyType_t type, EventType_t event_type, KeySym keysym, KeyCode keycode,
355 unsigned int button, unsigned int modifier)
356 {
357 int i, found_index = -1;
358 Keys_t *keys_bis = NULL;
359
360 if (keys == NULL)
361 {
362 return (-1);
363 }
364
365 modifier &= ~(numlock_mask | capslock_mask | scrolllock_mask);
366
367 for (i = 0; i < nb_keys; i++)
368 {
369 if (keys[i].type == type &&
370 keys[i].event_type == event_type &&
371 keys[i].modifier == modifier &&
372 ((type == SYM && keys[i].key.sym == keysym) ||
373 (type == CODE && keys[i].key.code == keycode) ||
374 (type == BUTTON && keys[i].key.button == button)))
375 found_index = i;
376 }
377
378 if (found_index != -1)
379 {
380 if (verbose)
381 printf ("Removing key index %d\n", found_index);
382
383 /* make new array keys_bis */
384 keys_bis = (Keys_t *) malloc ((nb_keys - 1) * sizeof (Keys_t));
385 if (keys_bis == NULL)
386 return (-1);
387
388 for (i = 0; i < found_index; i++)
389 keys_bis[i] = keys[i];
390
391 for (i = found_index + 1; i < nb_keys; i++)
392 keys_bis[i - 1] = keys[i];
393
394 free_key (&keys[found_index]);
395 free (keys);
396
397 /* make keys_bis as keys */
398 keys = keys_bis;
399
400 nb_keys -= 1;
401 }
402
403 return (0);
404 }
405
406
407
408
409
410
411
412 void
run_command(char * command)413 run_command (char *command)
414 {
415 #ifdef FORK_FLAG
416 pid_t pid;
417
418 if (verbose)
419 printf ("Start program with fork+exec call\n");
420
421 // if (fork() == 0)
422 // execlp ("sh", "sh", "-c", key->command, NULL);
423 if (!(pid = fork()))
424 {
425 setsid();
426 switch (fork())
427 {
428 case 0: execlp ("sh", "sh", "-c", command, (char *) NULL);
429 break;
430 default: _exit(0);
431 break;
432 }
433 }
434 if (pid > 0)
435 wait(NULL);
436 #else
437 if (verbose)
438 printf ("Start program with system call\n");
439
440 system (command);
441 #endif
442 }
443
444
445 void
start_command_key(Keys_t * key)446 start_command_key (Keys_t * key)
447 {
448 if (key->command == NULL)
449 {
450 #ifdef GUILE_FLAG
451 if (key->function != 0)
452 {
453 scm_call_0 (key->function);
454 }
455 #endif
456 return;
457 }
458
459 run_command (key->command);
460 }
461