/*************************************************************************** xbindkeys : a program to bind keys to commands under X11. ------------------- begin : Sat Oct 13 14:11:34 CEST 2001 copyright : (C) 2001 by Philippe Brochard email : hocwp@free.fr ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "keys.h" #include #include #include #include #include #include #include #include "xbindkeys.h" #include "keys.h" #include "config.h" #include "options.h" #include "grab_key.h" #define STR_KEY_LEN 1000 int nb_keys; Keys_t *keys; extern char rc_file[512]; static char *modifier_string[] = { "Control", "Shift", "Alt", "Mod2", "Mod3", "Mod4", "Mod5" }; int init_keys (void) { nb_keys = 0; keys = NULL; return 0; } void close_keys (void) { int i; for (i = 0; i < nb_keys; i++) free_key (&keys[i]); if (keys != NULL) { free (keys); keys = NULL; } nb_keys = 0; } int add_key (KeyType_t type, EventType_t event_type, KeySym keysym, KeyCode keycode, unsigned int button, unsigned int modifier, char *command, SCM function) { Keys_t *keys_bis = NULL; int i; if (keysym == 0 && keycode == 0 && button == 0) { fprintf (stderr, "Warning: unknown key in RC file : %s\n", rc_file); return (-1); } /* make new array keys_bis */ keys_bis = (Keys_t *) malloc ((nb_keys + 1) * sizeof (Keys_t)); if (keys_bis == NULL) return (-1); if (keys != NULL) { /* copy keys in keys_bis */ for (i = 0; i < nb_keys; i++) { keys_bis[i] = keys[i]; } /* delete old keys array */ free (keys); } /* make keys_bis as keys */ keys = keys_bis; modifier &= ~(numlock_mask | capslock_mask | scrolllock_mask); #ifdef GUILE_FLAG if(function) scm_gc_protect_object(function); #endif /* set key */ if (type == SYM) { set_keysym (&keys[nb_keys], event_type, keysym, modifier, command, function); } else if (type == BUTTON) { set_button (&keys[nb_keys], event_type, button, modifier, command, function); } else { set_keycode (&keys[nb_keys], event_type, keycode, modifier, command, function); } /* new key */ nb_keys += 1; return (0); } void show_key_binding (Display * d) { int i; int last_verbose = verbose; verbose = 1; for (i = 0; i < nb_keys; i++) { print_key (d, &keys[i]); } verbose = last_verbose; } void modifier_to_string (unsigned int modifier, char *str) { str[0] = '\0'; if (modifier & ControlMask) { if (str[0]) strncat (str, "+", STR_KEY_LEN); strncat (str, modifier_string[0], STR_KEY_LEN); } if (modifier & ShiftMask) { if (str[0]) strncat (str, "+", STR_KEY_LEN); strncat (str, modifier_string[1], STR_KEY_LEN); } if (modifier & Mod1Mask) { if (str[0]) strncat (str, "+", STR_KEY_LEN); strncat (str, modifier_string[2], STR_KEY_LEN); } if (modifier & Mod2Mask) { if (str[0]) strncat (str, "+", STR_KEY_LEN); strncat (str, modifier_string[3], STR_KEY_LEN); } if (modifier & Mod3Mask) { if (str[0]) strncat (str, "+", STR_KEY_LEN); strncat (str, modifier_string[4], STR_KEY_LEN); } if (modifier & Mod4Mask) { if (str[0]) strncat (str, "+", STR_KEY_LEN); strncat (str, modifier_string[5], STR_KEY_LEN); } if (modifier & Mod5Mask) { if (str[0]) strncat (str, "+", STR_KEY_LEN); strncat (str, modifier_string[6], STR_KEY_LEN); } } void print_key (Display * d, Keys_t * key) { char str[STR_KEY_LEN]; int keysyms_per_keycode_return; if (verbose) { if (key->type == SYM) { modifier_to_string (key->modifier, str); printf ("\"%s\"\n %s%s%s%s\n", key->command != NULL ? key->command : ( key->function != 0 ? "(Scheme function)" : "NoCommand" ), key->event_type == PRESS ? "" : "Release + ", str, str[0] ? " + " : "", XKeysymToString (key->key.sym)); } else if (key->type == BUTTON) { printf ("\"%s\"\n %sm:0x%x + b:%d (mouse)\n", key->command != NULL ? key->command : ( key->function != 0 ? "(Scheme function)" : "NoCommand" ), key->event_type == PRESS ? "" : "Release + ", key->modifier, key->key.button); } else { printf ("\"%s\"\n %sm:0x%x + c:%d\n", key->command != NULL ? key->command : ( key->function != 0 ? "(Scheme function)" : "NoCommand" ), key->event_type == PRESS ? "" : "Release + ", key->modifier, key->key.code); if (d != NULL) { modifier_to_string (key->modifier, str); printf (" %s%s%s%s\n", str, str[0] ? " + " : "", key->event_type == PRESS ? "" : "Release + ", (XKeysymToString (*XGetKeyboardMapping(d, key->key.code, 1, &keysyms_per_keycode_return)) != NULL) ? XKeysymToString (*XGetKeyboardMapping(d, key->key.code, 1, &keysyms_per_keycode_return)) : "NoSymbol"); } } } } void set_keysym (Keys_t * key, EventType_t event_type, KeySym keysym, unsigned int modifier, char *command, SCM function) { int size; key->type = SYM; key->event_type = event_type; key->key.sym = keysym; key->modifier = modifier; if (command != NULL) { size = (strlen (command) + 1) * sizeof (char); key->command = (char *) malloc (size); if (key->command != NULL) strncpy (key->command, command, size); } else { key->command = NULL; } key->function = function; } void set_keycode (Keys_t * key, EventType_t event_type, KeyCode keycode, unsigned int modifier, char *command, SCM function) { int size; key->type = CODE; key->event_type = event_type; key->key.code = keycode; key->modifier = modifier; if (command != NULL) { size = (strlen (command) + 1) * sizeof (char); key->command = (char *) malloc (size); if (key->command != NULL) strncpy (key->command, command, size); } else { key->command = NULL; } key->function = function; } void set_button (Keys_t * key, EventType_t event_type, unsigned int button, unsigned int modifier, char *command, SCM function) { int size; key->type = BUTTON; key->event_type = event_type; key->key.button = button; key->modifier = modifier; if (command != NULL) { size = (strlen (command) + 1) * sizeof (char); key->command = (char *) malloc (size); if (key->command != NULL) strncpy (key->command, command, size); } else { key->command = NULL; } key->function = function; } void free_key (Keys_t * key) { key->type = SYM; key->event_type = PRESS; key->key.sym = 0; key->modifier = 0; if (key->command != NULL) free (key->command); #ifdef GUILE_FLAG if(key->function) scm_gc_unprotect_object(key->function); #endif key->function = 0; } int remove_key (KeyType_t type, EventType_t event_type, KeySym keysym, KeyCode keycode, unsigned int button, unsigned int modifier) { int i, found_index = -1; Keys_t *keys_bis = NULL; if (keys == NULL) { return (-1); } modifier &= ~(numlock_mask | capslock_mask | scrolllock_mask); for (i = 0; i < nb_keys; i++) { if (keys[i].type == type && keys[i].event_type == event_type && keys[i].modifier == modifier && ((type == SYM && keys[i].key.sym == keysym) || (type == CODE && keys[i].key.code == keycode) || (type == BUTTON && keys[i].key.button == button))) found_index = i; } if (found_index != -1) { if (verbose) printf ("Removing key index %d\n", found_index); /* make new array keys_bis */ keys_bis = (Keys_t *) malloc ((nb_keys - 1) * sizeof (Keys_t)); if (keys_bis == NULL) return (-1); for (i = 0; i < found_index; i++) keys_bis[i] = keys[i]; for (i = found_index + 1; i < nb_keys; i++) keys_bis[i - 1] = keys[i]; free_key (&keys[found_index]); free (keys); /* make keys_bis as keys */ keys = keys_bis; nb_keys -= 1; } return (0); } void run_command (char *command) { #ifdef FORK_FLAG pid_t pid; if (verbose) printf ("Start program with fork+exec call\n"); // if (fork() == 0) // execlp ("sh", "sh", "-c", key->command, NULL); if (!(pid = fork())) { setsid(); switch (fork()) { case 0: execlp ("sh", "sh", "-c", command, (char *) NULL); break; default: _exit(0); break; } } if (pid > 0) wait(NULL); #else if (verbose) printf ("Start program with system call\n"); system (command); #endif } void start_command_key (Keys_t * key) { if (key->command == NULL) { #ifdef GUILE_FLAG if (key->function != 0) { scm_call_0 (key->function); } #endif return; } run_command (key->command); }