summaryrefslogtreecommitdiff
path: root/keys.c
diff options
context:
space:
mode:
authorPhilippe Brochard <pbrochard@common-lisp.net>2009-05-18 15:28:11 +0200
committerPhilippe Brochard <pbrochard@common-lisp.net>2009-05-18 15:28:11 +0200
commit0d5a90f36acc602d993075bbccaebb44e671dca6 (patch)
tree71f73266ef446b8f030f7182544ef21593318fb1 /keys.c
parentbe5b5354a2af10580bde41d3cbf6d2c9db72bb9b (diff)
downloadxbindkeys-0d5a90f36acc602d993075bbccaebb44e671dca6.tar.gz
Initial import
Diffstat (limited to 'keys.c')
-rw-r--r--keys.c457
1 files changed, 457 insertions, 0 deletions
diff --git a/keys.c b/keys.c
new file mode 100644
index 0000000..79900e7
--- /dev/null
+++ b/keys.c
@@ -0,0 +1,457 @@
+/***************************************************************************
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <X11/keysym.h>
+#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: unkown 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);
+
+ /* 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];
+
+ 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
+ (XKeycodeToKeysym (d, key->key.code, 0)) !=
+ NULL) ? XKeysymToString (XKeycodeToKeysym (d,
+ key->key.
+ code,
+ 0)) :
+ "NoSymbol");
+ }
+ }
+ }
+}
+
+
+void
+set_keysym (Keys_t * key, EventType_t event_type, KeySym keysym,
+ unsigned int modifier, char *command, SCM function)
+{
+ key->type = SYM;
+ key->event_type = event_type;
+ key->key.sym = keysym;
+ key->modifier = modifier;
+
+ if (command != NULL)
+ {
+ key->command = (char *) malloc ((strlen (command) + 1) * sizeof (char));
+
+ if (key->command != NULL)
+ strncpy (key->command, command, strlen (command) + 1);
+ }
+ 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)
+{
+ key->type = CODE;
+ key->event_type = event_type;
+ key->key.code = keycode;
+ key->modifier = modifier;
+
+ if (command != NULL)
+ {
+ key->command = (char *) malloc ((strlen (command) + 1) * sizeof (char));
+
+ if (key->command != NULL)
+ strncpy (key->command, command, strlen (command) + 1);
+ }
+ 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)
+{
+ key->type = BUTTON;
+ key->event_type = event_type;
+ key->key.button = button;
+ key->modifier = modifier;
+
+ if (command != NULL)
+ {
+ key->command = (char *) malloc ((strlen (command) + 1) * sizeof (char));
+
+ if (key->command != NULL)
+ strncpy (key->command, command, strlen (command) + 1);
+ }
+ 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);
+
+ 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)
+{
+ pid_t pid;
+
+#ifdef FORK_FLAG
+ 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);
+}