summaryrefslogtreecommitdiff
path: root/options.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 /options.c
parentbe5b5354a2af10580bde41d3cbf6d2c9db72bb9b (diff)
downloadxbindkeys-0d5a90f36acc602d993075bbccaebb44e671dca6.tar.gz
Initial import
Diffstat (limited to 'options.c')
-rw-r--r--options.c1119
1 files changed, 1119 insertions, 0 deletions
diff --git a/options.c b/options.c
new file mode 100644
index 0000000..be678a7
--- /dev/null
+++ b/options.c
@@ -0,0 +1,1119 @@
+/***************************************************************************
+ 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <X11/keysym.h>
+#include <ctype.h>
+#include "options.h"
+#include "xbindkeys.h"
+#include "keys.h"
+#include "grab_key.h"
+#ifdef GUILE_FLAG
+#include <libguile.h>
+#endif
+#include "config.h"
+
+char *display_name = NULL;
+
+char rc_file[512];
+#ifdef GUILE_FLAG
+char rc_guile_file[512];
+#endif
+
+int verbose = 0;
+int have_to_show_binding = 0;
+int have_to_get_binding = 0;
+int have_to_start_as_daemon = 1;
+
+char *geom = NULL;
+
+
+static void show_version (void);
+static void show_help (void);
+static void show_defaults_rc (void);
+#ifdef GUILE_FLAG
+static void show_defaults_guile_rc (void);
+int init_xbk_guile_fns (void);
+SCM set_numlock_wrapper (SCM x);
+SCM set_scrolllock_wrapper (SCM x);
+SCM set_capslock_wrapper (SCM x);
+SCM xbindkey_wrapper(SCM key, SCM cmd);
+SCM xbindkey_function_wrapper(SCM key, SCM fun);
+SCM remove_xbindkey_wrapper(SCM key);
+SCM run_command_wrapper (SCM command);
+SCM grab_all_keys_wrapper (void);
+SCM ungrab_all_keys_wrapper (void);
+SCM remove_all_keys_wrapper (void);
+SCM debug_info_wrapper (void);
+#endif
+
+
+
+void
+get_options (int argc, char **argv)
+{
+ int i;
+ char *home;
+
+ strncpy (rc_file, "", sizeof(rc_file));
+#ifdef GUILE_FLAG
+ strncpy (rc_guile_file, "", sizeof (rc_guile_file));
+#endif
+
+ verbose = 0;
+ have_to_show_binding = 0;
+ have_to_get_binding = 0;
+ have_to_start_as_daemon = 1;
+
+
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "-V") == 0 || strcmp (argv[i], "--version") == 0)
+ {
+ show_version ();
+ exit (1);
+ }
+ else if ((strcmp (argv[i], "-X") == 0
+ || strcmp (argv[i], "--display") == 0) && i + 1 < argc)
+ {
+ display_name = argv[++i];
+ }
+ else if ((strcmp (argv[i], "-f") == 0
+ || strcmp (argv[i], "--file") == 0) && i + 1 < argc)
+ {
+ strncpy (rc_file, argv[++i], sizeof (rc_file) - 1);
+ }
+#ifdef GUILE_FLAG
+ else if ((strcmp (argv[i], "-fg") == 0
+ || strcmp (argv[i], "--guile-file") == 0) && i + 1 < argc)
+ {
+ strncpy (rc_guile_file, argv[++i], sizeof (rc_guile_file) - 1);
+ }
+#endif
+ else if (strcmp (argv[i], "-s") == 0 || strcmp (argv[i], "--show") == 0)
+ {
+ have_to_show_binding = 1;
+ }
+ else if (strcmp (argv[i], "-k") == 0 || strcmp (argv[i], "--key") == 0)
+ {
+ have_to_get_binding = 1;
+ }
+ else if (strcmp (argv[i], "-mk") == 0
+ || strcmp (argv[i], "--multikey") == 0)
+ {
+ have_to_get_binding = 2;
+ }
+ else if (strcmp (argv[i], "-v") == 0
+ || strcmp (argv[i], "--verbose") == 0)
+ {
+ verbose = 1;
+ have_to_start_as_daemon = 0;
+ }
+ else if (strcmp (argv[i], "-d") == 0
+ || strcmp (argv[i], "--defaults") == 0)
+ {
+ show_defaults_rc ();
+ }
+#ifdef GUILE_FLAG
+ else if (strcmp (argv[i], "-dg") == 0
+ || strcmp (argv[i], "--defaults-guile") == 0)
+ {
+ show_defaults_guile_rc ();
+ }
+#endif
+ else if (strcmp (argv[i], "-h") == 0 || strcmp (argv[i], "--help") == 0)
+ {
+ show_help ();
+ exit (1);
+ }
+ else if ((strcmp (argv[i], "-g") == 0
+ || strcmp (argv[i], "--geometry") == 0) && i + 1 < argc)
+ {
+ geom = argv[++i];
+ }
+ else if (strcmp (argv[i], "-n") == 0
+ || strcmp (argv[i], "--nodaemon") == 0)
+ {
+ have_to_start_as_daemon = 0;
+ }
+ else
+ {
+ show_help ();
+ exit (1);
+ }
+ }
+
+ if (strcmp (rc_file, "") == 0)
+ {
+ home = getenv ("HOME");
+
+ if (rc_file)
+ {
+ strncpy (rc_file, home, sizeof (rc_file) - 20);
+ strncat (rc_file, "/.xbindkeysrc", sizeof (rc_file));
+ }
+ }
+
+#ifdef GUILE_FLAG
+ if (strcmp (rc_guile_file, "") == 0)
+ {
+ home = getenv ("HOME");
+
+ if (rc_guile_file)
+ {
+ strncpy (rc_guile_file, home, sizeof (rc_guile_file) - 20);
+ strncat (rc_guile_file, "/.xbindkeysrc.scm", sizeof (rc_guile_file));
+ }
+ }
+#endif
+}
+
+void
+show_options (void)
+{
+ if (verbose)
+ {
+ printf ("displayName = %s\n", display_name);
+ printf ("rc file = %s\n", rc_file);
+#ifdef GUILE_FLAG
+ printf ("rc guile file = %s\n", rc_guile_file);
+#endif
+ }
+}
+
+
+static void
+show_version (void)
+{
+ fprintf (stderr, "xbindkeys %s by Philippe Brochard\n", PACKAGE_VERSION);
+}
+
+static void
+show_help (void)
+{
+ show_version ();
+
+ fprintf (stderr, "usage: xbindkeys [options]\n");
+ fprintf (stderr, " where options are:\n");
+
+ fprintf (stderr, " -V, --version Print version and exit\n");
+ fprintf (stderr, " -d, --defaults Print a default rc file\n");
+#ifdef GUILE_FLAG
+ fprintf (stderr, " -dg, --defaults-guile Print a default guile configuration file\n");
+#endif
+ fprintf (stderr, " -f, --file Use an alternative rc file\n");
+#ifdef GUILE_FLAG
+ fprintf (stderr, " -fg, --file-guile Use an alternative guile configuration file\n");
+#endif
+ fprintf (stderr, " -h, --help This help!\n");
+ fprintf (stderr, " -X, --display Set X display to use\n");
+ fprintf (stderr,
+ " -v, --verbose More information on xbindkeys when it run\n");
+ fprintf (stderr, " -s, --show Show the actual keybinding\n");
+ fprintf (stderr, " -k, --key Identify one key pressed\n");
+ fprintf (stderr, " -mk, --multikey Identify multi key pressed\n");
+ fprintf (stderr,
+ " -g, --geometry size and position of window open with -k|-mk option\n");
+ fprintf (stderr, " -n, --nodaemon don't start as daemon\n");
+}
+
+
+static void
+show_defaults_rc (void)
+{
+ printf ("# For the benefit of emacs users: -*- shell-script -*-\n");
+ printf ("###########################\n");
+ printf ("# xbindkeys configuration #\n");
+ printf ("###########################\n");
+ printf ("#\n");
+ printf ("# Version: %s\n", PACKAGE_VERSION);
+ printf ("#\n");
+ printf ("# If you edit this file, do not forget to uncomment any lines\n");
+ printf ("# that you change.\n");
+ printf ("# The pound(#) symbol may be used anywhere for comments.\n");
+ printf ("#\n");
+
+ printf ("# To specify a key, you can use 'xbindkeys --key' or\n");
+ printf
+ ("# 'xbindkeys --multikey' and put one of the two lines in this file.\n");
+ printf ("#\n");
+ printf ("# The format of a command line is:\n");
+ printf ("# \"command to start\"\n");
+ printf ("# associated key\n");
+ printf ("#\n");
+ printf ("#\n");
+ printf ("# A list of keys is in /usr/include/X11/keysym.h and in\n");
+ printf ("# /usr/include/X11/keysymdef.h\n");
+ printf ("# The XK_ is not needed.\n");
+ printf ("#\n");
+ printf ("# List of modifier:\n");
+ printf ("# Release, Control, Shift, Mod1 (Alt), Mod2 (NumLock),\n");
+ printf ("# Mod3 (CapsLock), Mod4, Mod5 (Scroll).\n");
+ printf ("#\n");
+ printf ("\n");
+ printf ("# The release modifier is not a standard X modifier, but you can\n");
+ printf ("# use it if you want to catch release events instead of press events\n");
+ printf ("\n");
+ printf
+ ("# By defaults, xbindkeys does not pay attention with the modifiers\n");
+ printf ("# NumLock, CapsLock and ScrollLock.\n");
+ printf
+ ("# Uncomment the lines above if you want to pay attention to them.\n");
+ printf ("\n");
+ printf ("#keystate_numlock = enable\n");
+ printf ("#keystate_capslock = enable\n");
+ printf ("#keystate_scrolllock= enable\n");
+ printf ("\n");
+ printf ("# Examples of commands:\n");
+ printf ("\n");
+
+ printf ("\"xbindkeys_show\" \n");
+ printf (" control+shift + q\n");
+ printf ("\n");
+ printf ("# set directly keycode (here control + f with my keyboard)\n");
+ printf ("\"xterm\"\n");
+ printf (" c:41 + m:0x4\n");
+ printf ("\n");
+ printf ("# specify a mouse button\n");
+ printf ("\"xterm\"\n");
+ printf (" control + b:2\n");
+ printf ("\n");
+ printf ("#\"xterm -geom 50x20+20+20\"\n");
+ printf ("# Shift+Mod2+alt + s\n");
+ printf ("#\n");
+ printf
+ ("## set directly keycode (here control+alt+mod2 + f with my keyboard)\n");
+ printf ("#\"xterm\"\n");
+ printf ("# alt + c:0x29 + m:4 + mod2\n");
+ printf ("#\n");
+ printf ("## Control+Shift+a release event starts rxvt\n");
+ printf ("#\"rxvt\"\n");
+ printf ("# release+control+shift + a\n");
+ printf ("#\n");
+ printf ("## Control + mouse button 2 release event starts rxvt\n");
+ printf ("#\"rxvt\"\n");
+ printf ("# Control + b:2 + Release\n");
+
+ printf ("\n");
+ printf ("##################################\n");
+ printf ("# End of xbindkeys configuration #\n");
+ printf ("##################################\n");
+
+ exit (1);
+}
+
+
+#ifdef GUILE_FLAG
+static void
+show_defaults_guile_rc (void)
+{
+ printf (";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
+ printf (";; Start of xbindkeys guile configuration ;;\n");
+ printf (";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
+ printf (";; This configuration is guile based.\n");
+ printf (";; http://www.gnu.org/software/guile/guile.html\n");
+ printf (";; any functions that work in guile will work here.\n");
+ printf (";; see EXTRA FUNCTIONS:\n");
+ printf ("\n");
+ printf (";; Version: %s\n", PACKAGE_VERSION);
+ printf ("\n");
+ printf (";; If you edit this file, do not forget to uncomment any lines\n");
+ printf (";; that you change.\n");
+ printf (";; The semicolon(;) symbol may be used anywhere for comments.\n");
+ printf ("\n");
+ printf (";; To specify a key, you can use 'xbindkeys --key' or\n");
+ printf (";; 'xbindkeys --multikey' and put one of the two lines in this file.\n");
+ printf ("\n");
+ printf (";; A list of keys is in /usr/include/X11/keysym.h and in\n");
+ printf (";; /usr/include/X11/keysymdef.h\n");
+ printf (";; The XK_ is not needed.\n");
+ printf ("\n");
+ printf (";; List of modifier:\n");
+ printf (";; Release, Control, Shift, Mod1 (Alt), Mod2 (NumLock),\n");
+ printf (";; Mod3 (CapsLock), Mod4, Mod5 (Scroll).\n");
+ printf ("\n");
+ printf ("\n");
+ printf (";; The release modifier is not a standard X modifier, but you can\n");
+ printf (";; use it if you want to catch release instead of press events\n");
+ printf ("\n");
+ printf (";; By defaults, xbindkeys does not pay attention to modifiers\n");
+ printf (";; NumLock, CapsLock and ScrollLock.\n");
+ printf (";; Uncomment the lines below if you want to use them.\n");
+ printf (";; To dissable them, call the functions with #f\n");
+ printf ("\n");
+ printf ("\n");
+ printf (";;;;EXTRA FUNCTIONS: Enable numlock, scrolllock or capslock usage\n");
+ printf (";;(set-numlock! #t)\n");
+ printf (";;(set-scrolllock! #t)\n");
+ printf (";;(set-capslock! #t)\n");
+ printf ("\n");
+ printf (";;;;; Scheme API reference\n");
+ printf (";;;;\n");
+ printf (";; Optional modifier state:\n");
+ printf (";; (set-numlock! #f or #t)\n");
+ printf (";; (set-scrolllock! #f or #t)\n");
+ printf (";; (set-capslock! #f or #t)\n");
+ printf (";; \n");
+ printf (";; Shell command key:\n");
+ printf (";; (xbindkey key \"foo-bar-command [args]\")\n");
+ printf (";; (xbindkey '(modifier* key) \"foo-bar-command [args]\")\n");
+ printf (";; \n");
+ printf (";; Scheme function key:\n");
+ printf (";; (xbindkey-function key function-name-or-lambda-function)\n");
+ printf (";; (xbindkey-function '(modifier* key) function-name-or-lambda-function)\n");
+ printf (";; \n");
+ printf (";; Other functions:\n");
+ printf (";; (remove-xbindkey key)\n");
+ printf (";; (run-command \"foo-bar-command [args]\")\n");
+ printf (";; (grab-all-keys)\n");
+ printf (";; (ungrab-all-keys)\n");
+ printf (";; (remove-all-keys)\n");
+ printf (";; (debug)\n");
+ printf ("\n");
+ printf ("\n");
+ printf (";; Examples of commands:\n");
+ printf ("\n");
+ printf ("(xbindkey '(control shift q) \"xbindkeys_show\")\n");
+ printf ("\n");
+ printf (";; set directly keycode (here control + f with my keyboard)\n");
+ printf ("(xbindkey '(\"m:0x4\" \"c:41\") \"xterm\")\n");
+ printf ("\n");
+ printf (";; specify a mouse button\n");
+ printf ("(xbindkey '(control \"b:2\") \"xterm\")\n");
+ printf ("\n");
+ printf (";;(xbindkey '(shift mod2 alt s) \"xterm -geom 50x20+20+20\")\n");
+ printf ("\n");
+ printf (";; set directly keycode (control+alt+mod2 + f with my keyboard)\n");
+ printf ("(xbindkey '(alt \"m:4\" mod2 \"c:0x29\") \"xterm\")\n");
+ printf ("\n");
+ printf (";; Control+Shift+a release event starts rxvt\n");
+ printf (";;(xbindkey '(release control shift a) \"rxvt\")\n");
+ printf ("\n");
+ printf (";; Control + mouse button 2 release event starts rxvt\n");
+ printf (";;(xbindkey '(releace control \"b:2\") \"rxvt\")\n");
+ printf ("\n");
+ printf ("\n");
+ printf (";; Extra features\n");
+ printf ("(xbindkey-function '(control a)\n");
+ printf (" (lambda ()\n");
+ printf (" (display \"Hello from Scheme!\")\n");
+ printf (" (newline)))\n");
+ printf ("\n");
+ printf ("(xbindkey-function '(shift p)\n");
+ printf (" (lambda ()\n");
+ printf (" (run-command \"xterm\")))\n");
+ printf ("\n");
+ printf ("\n");
+ printf (";; Double click test\n");
+ printf ("(xbindkey-function '(control w)\n");
+ printf (" (let ((count 0))\n");
+ printf (" (lambda ()\n");
+ printf (" (set! count (+ count 1))\n");
+ printf (" (if (> count 1)\n");
+ printf (" (begin\n");
+ printf (" (set! count 0)\n");
+ printf (" (run-command \"xterm\"))))))\n");
+ printf ("\n");
+ printf (";; Time double click test:\n");
+ printf (";; - short double click -> run an xterm\n");
+ printf (";; - long double click -> run an rxvt\n");
+ printf ("(xbindkey-function '(shift w)\n");
+ printf (" (let ((time (current-time))\n");
+ printf (" (count 0))\n");
+ printf (" (lambda ()\n");
+ printf (" (set! count (+ count 1))\n");
+ printf (" (if (> count 1)\n");
+ printf (" (begin\n");
+ printf (" (if (< (- (current-time) time) 1)\n");
+ printf (" (run-command \"xterm\")\n");
+ printf (" (run-command \"rxvt\"))\n");
+ printf (" (set! count 0)))\n");
+ printf (" (set! time (current-time)))))\n");
+ printf ("\n");
+ printf ("\n");
+ printf (";; Chording keys test: Start differents program if only one key is\n");
+ printf (";; pressed or another if two keys are pressed.\n");
+ printf (";; If key1 is pressed start cmd-k1\n");
+ printf (";; If key2 is pressed start cmd-k2\n");
+ printf (";; If both are pressed start cmd-k1-k2 or cmd-k2-k1 following the\n");
+ printf (";; release order\n");
+ printf ("(define (define-chord-keys key1 key2 cmd-k1 cmd-k2 cmd-k1-k2 cmd-k2-k1)\n");
+ printf (" \"Define chording keys\"\n");
+ printf (" (let ((k1 #f) (k2 #f))\n");
+ printf (" (xbindkey-function key1 (lambda () (set! k1 #t)))\n");
+ printf (" (xbindkey-function key2 (lambda () (set! k2 #t)))\n");
+ printf (" (xbindkey-function (cons 'release key1)\n");
+ printf (" (lambda ()\n");
+ printf (" (if (and k1 k2)\n");
+ printf (" (run-command cmd-k1-k2)\n");
+ printf (" (if k1 (run-command cmd-k1)))\n");
+ printf (" (set! k1 #f) (set! k2 #f)))\n");
+ printf (" (xbindkey-function (cons 'release key2)\n");
+ printf (" (lambda ()\n");
+ printf (" (if (and k1 k2)\n");
+ printf (" (run-command cmd-k2-k1)\n");
+ printf (" (if k2 (run-command cmd-k2)))\n");
+ printf (" (set! k1 #f) (set! k2 #f)))))\n");
+ printf ("\n");
+ printf ("\n");
+ printf (";; Example:\n");
+ printf (";; Shift + b:1 start an xterm\n");
+ printf (";; Shift + b:3 start an rxvt\n");
+ printf (";; Shift + b:1 then Shift + b:3 start gv\n");
+ printf (";; Shift + b:3 then Shift + b:1 start xpdf\n");
+ printf ("\n");
+ printf ("(define-chord-keys '(shift \"b:1\") '(shift \"b:3\")\n");
+ printf (" \"xterm\" \"rxvt\" \"gv\" \"xpdf\")\n");
+ printf ("\n");
+ printf (";; Here the release order have no importance\n");
+ printf (";; (the same program is started in both case)\n");
+ printf ("(define-chord-keys '(alt \"b:1\") '(alt \"b:3\")\n");
+ printf (" \"gv\" \"xpdf\" \"xterm\" \"xterm\")\n");
+ printf ("\n");
+ printf ("\n");
+ printf (";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
+ printf (";; End of xbindkeys guile configuration ;;\n");
+ printf (";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
+
+ exit (1);
+}
+#endif
+
+
+
+static int
+file_exist (char * filename)
+{
+ FILE * stream;
+
+ if ((stream = fopen (filename, "r")) == NULL)
+ return 0;
+
+ fclose (stream);
+ return 1;
+}
+
+
+int
+rc_file_exist (void)
+{
+#ifdef GUILE_FLAG
+ if (file_exist (rc_guile_file))
+ return 1;
+#endif
+
+ if (!file_exist (rc_file))
+ {
+ fprintf (stderr, "Error : %s not found or reading not allowed.\n",
+ rc_file);
+ fprintf (stderr,
+ "please, create one with 'xbindkeys --defaults > %s'.\n",
+ rc_file);
+#ifdef GUILE_FLAG
+ fprintf (stderr,
+ "or, if you want scheme configuration style,\n");
+ fprintf (stderr,
+ "with 'xbindkeys --defaults-guile > %s'.\n",
+ rc_guile_file);
+#endif
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+
+
+int
+get_rc_file (void)
+{
+ char line[1024];
+ char line2[1024];
+ char command[1024];
+ KeyType_t type;
+ EventType_t event_type;
+ KeySym keysym;
+ KeyCode keycode;
+ unsigned int button;
+ unsigned int modifier;
+ FILE *stream = NULL;
+ char *pos1;
+ char *pos2;
+ char *p;
+ int i;
+
+
+ if (init_keys () != 0)
+ return (-1);
+
+ /* Open RC File */
+ if ((stream = fopen (rc_file, "r")) == NULL)
+ {
+ fprintf (stderr, "Error : %s not found or reading not allowed.\n",
+ rc_file);
+ fprintf (stderr,
+ "please, create one with 'xbindkeys --defaults > %s'.\n",
+ rc_file);
+ return (-1);
+ }
+
+
+ /* Read RC file */
+ while (fgets (line, sizeof (line), stream))
+ {
+ /* search for keystate options */
+ if (strstr (line, "keystate_numlock") != NULL)
+ {
+ /* search for comment or command line */
+ pos1 = strchr (line, '"');
+ pos2 = strchr (line, '#');
+ if (!pos1 && !pos2)
+ {
+ if (strstr (line, "enable") != NULL)
+ {
+ numlock_mask = 0;
+ }
+ if (verbose)
+ printf ("keystate_numlock: %s\n",
+ numlock_mask == 0 ? "Enabled" : "Disabled");
+
+ continue;
+ }
+ }
+
+ if (strstr (line, "keystate_capslock") != NULL)
+ {
+ /* search for comment or command line */
+ pos1 = strchr (line, '"');
+ pos2 = strchr (line, '#');
+ if (!pos1 && !pos2)
+ {
+ if (strstr (line, "enable") != NULL)
+ {
+ capslock_mask = 0;
+ }
+ if (verbose)
+ printf ("keystate_capslock: %s\n",
+ capslock_mask == 0 ? "Enabled" : "Disabled");
+
+ continue;
+ }
+ }
+
+ if (strstr (line, "keystate_scrolllock") != NULL)
+ {
+ /* search for comment or command line */
+ pos1 = strchr (line, '"');
+ pos2 = strchr (line, '#');
+ if (!pos1 && !pos2)
+ {
+ if (strstr (line, "enable") != NULL)
+ {
+ scrolllock_mask = 0;
+ }
+ if (verbose)
+ printf ("keystate_scrolllock: %s\n",
+ scrolllock_mask == 0 ? "Enabled" : "Disabled");
+
+ continue;
+ }
+ }
+
+
+ pos1 = strchr (line, '"');
+ if (pos1)
+ {
+ pos2 = strchr (line, '#');
+
+ if (!pos2 || pos2 > pos1)
+ {
+ /* search for command line */
+ pos2 = strrchr (line, '"');
+ if (pos2 && pos1 < pos2)
+ {
+ command[0] = '\0';
+ type = SYM;
+ event_type = PRESS;
+ keysym = 0;
+ keycode = 0;
+ button = 0;
+ modifier = 0;
+
+ for (p = pos1 + 1, i = 0;
+ p < pos2 && i < sizeof (command); p++, i++)
+ {
+ command[i] = *p;
+ }
+ command[i] = '\0';
+
+ /* get associated keys */
+ if (fgets (line, sizeof (line), stream))
+ {
+ pos1 = line;
+
+ while (*pos1 != '\n')
+ {
+ /* jump space */
+ for (; *pos1 == '+' || *pos1 == ' '
+ || *pos1 == '\t'; pos1++);
+
+ /* find corresponding + or \n */
+ pos2 = strchr (pos1, '+');
+ if (!pos2)
+ {
+ for (pos2 = pos1; *pos2 != '\n'; pos2++);
+ }
+
+ /* copy string in line2 */
+ for (p = pos1, i = 0;
+ p < pos2 && i < sizeof (line2)
+ && *p != '+' && *p != ' ' && *p != '\t';
+ p++, i++)
+ {
+ line2[i] = *p;
+ }
+ line2[i] = '\0';
+
+ /* is a numeric keycode (c:nnn) ? */
+ if (line2[0] == 'c' && line2[1] == ':')
+ {
+ if (isdigit (line2[2]))
+ {
+ type = CODE;
+ keycode = strtol (line2+2, (char **) NULL, 0);
+ }
+ else
+ {
+ keysym = 0;
+ keycode = 0;
+ button = 0;
+ break;
+ }
+ }
+ else
+ /* is a numeric modifier (m:nnn) ? */
+ if (line2[0] == 'm' && line2[1] == ':')
+ {
+ if (isdigit (line2[2]))
+ {
+ modifier |= strtol (line2+2, (char **) NULL, 0);
+ }
+ else
+ {
+ keysym = 0;
+ keycode = 0;
+ button = 0;
+ break;
+ }
+ }
+ else
+ /* is a mouse button (b:nnn) ? */
+ if (line2[0] == 'b' && line2[1] == ':')
+ {
+ if (isdigit (line2[2]))
+ {
+ type = BUTTON;
+ button = strtol (line2+2, (char **) NULL, 0);
+ }
+ else
+ {
+ keysym = 0;
+ keycode = 0;
+ button = 0;
+ break;
+ }
+ }
+ else
+ {
+ /* apply to modifier, release/press or key */
+ if (strcasecmp (line2, "control") == 0)
+ modifier |= ControlMask;
+ else if (strcasecmp (line2, "shift") == 0)
+ modifier |= ShiftMask;
+ else if (strcasecmp (line2, "mod1") == 0
+ || strcasecmp (line2, "alt") == 0)
+ modifier |= Mod1Mask;
+ else if (strcasecmp (line2, "mod2") == 0)
+ modifier |= Mod2Mask;
+ else if (strcasecmp (line2, "mod3") == 0)
+ modifier |= Mod3Mask;
+ else if (strcasecmp (line2, "mod4") == 0)
+ modifier |= Mod4Mask;
+ else if (strcasecmp (line2, "mod5") == 0)
+ modifier |= Mod5Mask;
+ else if (strcasecmp (line2, "release") == 0)
+ event_type = RELEASE;
+ else
+ {
+ type = SYM;
+ keysym = XStringToKeysym (line2);
+ if (keysym == 0)
+ break;
+ }
+ }
+
+ pos1 = pos2;
+ }
+ }
+
+ if (add_key (type, event_type, keysym, keycode,
+ button, modifier, command, 0) != 0)
+ break;
+ }
+ }
+ }
+ }
+
+
+ /* Close RC File */
+ if (stream != NULL)
+ fclose (stream);
+
+ if (keys == NULL)
+ {
+ fprintf (stderr, "Error in alocation of keys\n");
+ return (-1);
+ }
+
+ /* Verify if all is good (like my english) */
+ for (i = 0; i < nb_keys; i++)
+ {
+ if (keys[i].key.sym == 0 || keys[i].command == NULL)
+ {
+ fprintf (stderr, "Error in RC file : %s\n", rc_file);
+ return (-1);
+ }
+ }
+
+ if (verbose)
+ printf ("%d keys in %s\n", nb_keys, rc_file);
+
+ return (0);
+}
+
+
+
+//Everything from here on out has been changed by MMH
+#ifdef GUILE_FLAG
+int
+init_xbk_guile_fns (void)
+{
+ if (verbose)
+ printf("initializing guile fns...\n");
+ scm_c_define_gsubr("set-numlock!", 1, 0, 0, set_numlock_wrapper);
+ scm_c_define_gsubr("set-scrolllock!", 1, 0, 0, set_scrolllock_wrapper);
+ scm_c_define_gsubr("set-capslock!", 1, 0, 0, set_capslock_wrapper);
+ scm_c_define_gsubr("xbindkey", 2, 0, 0, xbindkey_wrapper);
+ scm_c_define_gsubr("xbindkey-function", 2, 0, 0, xbindkey_function_wrapper);
+ scm_c_define_gsubr("remove-xbindkey", 1, 0, 0, remove_xbindkey_wrapper);
+ scm_c_define_gsubr("run-command", 1, 0, 0, run_command_wrapper);
+ scm_c_define_gsubr("grab-all-keys", 0, 0, 0, grab_all_keys_wrapper);
+ scm_c_define_gsubr("ungrab-all-keys", 0, 0, 0, ungrab_all_keys_wrapper);
+ scm_c_define_gsubr("remove-all-keys", 0, 0, 0, remove_all_keys_wrapper);
+ scm_c_define_gsubr("debug", 0, 0, 0, debug_info_wrapper);
+ return 0;
+}
+
+int
+get_rc_guile_file (void)
+{
+ FILE *stream;
+
+ if (verbose)
+ printf("getting rc guile file %s.\n", rc_guile_file);
+
+ if (init_keys () != 0)
+ return (-1);
+
+ /* Open RC File */
+ if ((stream = fopen (rc_guile_file, "r")) == NULL)
+ {
+ if (verbose)
+ fprintf (stderr, "WARNING : %s not found or reading not allowed.\n",
+ rc_guile_file);
+ return (-1);
+ }
+ fclose (stream);
+
+ init_xbk_guile_fns();
+ scm_primitive_load(scm_take0str(rc_guile_file));
+ return 0;
+}
+
+#define MAKE_MASK_WRAPPER(name, mask_name) \
+SCM name (SCM val) \
+{ \
+ if (verbose) \
+ printf("Running mask cmd!\n"); \
+ mask_name = SCM_FALSEP(val); \
+ return SCM_UNSPECIFIED; \
+}
+
+MAKE_MASK_WRAPPER(set_numlock_wrapper, numlock_mask);
+MAKE_MASK_WRAPPER(set_scrolllock_wrapper, scrolllock_mask);
+MAKE_MASK_WRAPPER(set_capslock_wrapper, capslock_mask);
+
+
+
+SCM extract_key (SCM key, KeyType_t *type, EventType_t *event_type,
+ KeySym *keysym, KeyCode *keycode,
+ unsigned int *button, unsigned int *modifier)
+{
+ char *str;
+ int len;
+
+ while(SCM_CONSP(key)){ //Iterate through the list (If it is a list)
+ if(!SCM_CONSP(SCM_CDR(key))){ //if this is the last item
+ key = SCM_CAR(key); //go to that
+ break; //and continue
+ }
+ //Otherwise, this is a modifyer.
+
+ //So copy it:
+ //Guile strings are not \0 terminated. hence we must copy.
+ len = SCM_LENGTH(SCM_CAR(key));
+ str = malloc(sizeof(char)*(len+1));
+ strncpy(str, SCM_CHARS(SCM_CAR(key)), len);
+ str[len] = '\0';
+
+ if(verbose) //extra verbosity here.
+ printf("xbindkey_wrapper debug: modifier = %s.\n", str);
+
+ //copied directly with some substitutions. ie. line2 -> str
+ //Do whatever needs to be done with modifiers.
+ if (strncasecmp (str, "control", len) == 0)
+ *modifier |= ControlMask;
+ else if (strncasecmp (str, "shift", len) == 0)
+ *modifier |= ShiftMask;
+ else if (strncasecmp (str, "mod1", len) == 0
+ || strncasecmp (str, "alt", len) == 0)
+ *modifier |= Mod1Mask;
+ else if (strncasecmp (str, "mod2", len) == 0)
+ *modifier |= Mod2Mask;
+ else if (strncasecmp (str, "mod3", len) == 0)
+ *modifier |= Mod3Mask;
+ else if (strncasecmp (str, "mod4", len) == 0)
+ *modifier |= Mod4Mask;
+ else if (strncasecmp (str, "mod5", len) == 0)
+ *modifier |= Mod5Mask;
+ else if (strncasecmp (str, "release", len) == 0)
+ *event_type = RELEASE;
+ else if(strlen (str) > 2 && str[0] == 'm' && str[1] == ':'){
+ *modifier |= strtol (str+2, (char **) NULL, 0);
+ //this break have nothing to do here!
+ //break
+ }else{
+ printf("Bad modifier:\n%s\n", str); //or error
+ return SCM_BOOL_F; //and return false
+ }
+ free(str); //we copied, so we must destroy this
+ str=NULL;
+ key = SCM_CDR(key); //and go a step down the list
+ }
+ //So this was either the only or last item of the 1st arg
+ //Hence it is the key
+
+ //So copy it:
+ //Guile strings are not \0 terminated. hence we must copy.
+ len = SCM_LENGTH(key);
+ str = malloc(sizeof(char)*(len+1));
+ strncpy(str, SCM_CHARS(key), len);
+ str[len] = '\0';
+ if(verbose)
+ printf("xbindkey_wrapper debug: key = %s\n", str);
+
+ //Check for special numeric stuff.
+ //This way is really far nicer looking and more efficient than
+ //having three copies of the code.
+ if(strlen (str) > 2 && str[1] == ':' && isdigit (str[2]))
+ {
+ switch (str[0])
+ {
+ case 'b':
+ *type = BUTTON;
+ *button = strtol (str+2, (char **) NULL, 0);
+ break;
+ case 'c':
+ *type = CODE;
+ *keycode = strtol (str+2, (char **) NULL, 0);
+ break;
+ case 'm': //is a modifier so it is in the other part.
+ printf("bad modifyer: %s.", str);
+ printf("m: modifiers need be applied to keys\n");
+ return SCM_BOOL_F;
+ default:
+ printf("bad modifyer: %c: shoud be b:, c: or m: .\n", str[0]);
+ return SCM_BOOL_F;
+ }
+ }
+ else //regular key
+ {
+ *type = SYM;
+ *keysym = XStringToKeysym (str);
+ if (*keysym == 0){
+ printf("No keysym for key: %s\n", str);
+ return SCM_BOOL_F;
+ }
+ }
+
+ free(str); //these were used by add key and copied.
+
+ return SCM_BOOL_T;
+}
+
+
+
+SCM xbindkey_wrapper(SCM key, SCM cmd)
+{
+ KeyType_t type = SYM;
+ EventType_t event_type = PRESS;
+ KeySym keysym = 0;
+ KeyCode keycode = 0;
+ unsigned int button = 0;
+ unsigned int modifier = 0;
+ char *cmdstr;
+
+ //Guile strings are not \0 terminated. hence we must copy.
+ cmdstr = malloc(sizeof(char) * SCM_LENGTH(cmd) + 1);
+ strncpy(cmdstr, SCM_CHARS(cmd), SCM_LENGTH(cmd));
+ cmdstr[SCM_LENGTH(cmd)] = '\0';
+ if(verbose)
+ printf("xbindkey_wrapper debug: cmd=%s.\n", cmdstr);
+
+ if (extract_key (key, &type, &event_type, &keysym, &keycode,
+ &button, &modifier) == SCM_BOOL_F)
+ {
+ return SCM_BOOL_F;
+ }
+
+ if (add_key (type, event_type, keysym, keycode,
+ button, modifier, cmdstr, 0) != 0)
+ {
+ printf("add_key didn't return 0!!!\n");
+ return SCM_BOOL_F;
+ }
+
+ free(cmdstr); //we may get rid of them!
+
+ return SCM_UNSPECIFIED;
+}
+
+
+SCM xbindkey_function_wrapper (SCM key, SCM fun)
+{
+ KeyType_t type = SYM;
+ EventType_t event_type = PRESS;
+ KeySym keysym = 0;
+ KeyCode keycode = 0;
+ unsigned int button = 0;
+ unsigned int modifier = 0;
+
+ if (extract_key (key, &type, &event_type, &keysym, &keycode,
+ &button, &modifier) == SCM_BOOL_F)
+ {
+ return SCM_BOOL_F;
+ }
+
+ if (add_key (type, event_type, keysym, keycode,
+ button, modifier, NULL, fun) != 0)
+ {
+ printf("add_key didn't return 0!!!\n");
+ return SCM_BOOL_F;
+ }
+
+ return SCM_UNSPECIFIED;
+}
+
+
+
+SCM remove_xbindkey_wrapper (SCM key)
+{
+ KeyType_t type = SYM;
+ EventType_t event_type = PRESS;
+ KeySym keysym = 0;
+ KeyCode keycode = 0;
+ unsigned int button = 0;
+ unsigned int modifier = 0;
+
+ if (extract_key (key, &type, &event_type, &keysym, &keycode,
+ &button, &modifier) == SCM_BOOL_F)
+ {
+ return SCM_BOOL_F;
+ }
+
+ if (remove_key (type, event_type, keysym, keycode, button, modifier) != 0)
+ {
+ printf("remove_key didn't return 0!!!\n");
+ return SCM_BOOL_F;
+ }
+
+
+ return SCM_UNSPECIFIED;
+}
+
+
+SCM run_command_wrapper (SCM command)
+{
+ char *cmdstr;
+
+ cmdstr = malloc(sizeof(char) * SCM_LENGTH(command) + 1);
+ strncpy(cmdstr, SCM_CHARS(command), SCM_LENGTH(command));
+ cmdstr[SCM_LENGTH(command)] = '\0';
+
+ run_command (cmdstr);
+
+ free(cmdstr);
+
+ return SCM_UNSPECIFIED;
+}
+
+SCM grab_all_keys_wrapper (void)
+{
+ grab_keys (current_display);
+
+ return SCM_UNSPECIFIED;
+}
+
+
+SCM ungrab_all_keys_wrapper (void)
+{
+ ungrab_all_keys (current_display);
+
+ return SCM_UNSPECIFIED;
+}
+
+SCM remove_all_keys_wrapper (void)
+{
+ close_keys ();
+
+ return SCM_UNSPECIFIED;
+}
+
+
+SCM debug_info_wrapper (void)
+{
+ printf ("\nKeys = %p\n", keys);
+ printf ("nb_keys = %d\n", nb_keys);
+
+ return SCM_UNSPECIFIED;
+}
+
+#endif