"Fossies" - the Fresh Open Source Software Archive

Member "xbindkeys-1.8.7/options.c" (23 May 2020, 31689 Bytes) of package /linux/privat/xbindkeys-1.8.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "options.c" see the Fossies "Dox" file reference documentation.

    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 "config.h"
   19 #include <stdio.h>
   20 #include <string.h>
   21 #include <stdlib.h>
   22 #include <X11/keysym.h>
   23 #include <ctype.h>
   24 #include "options.h"
   25 #include "xbindkeys.h"
   26 #include "keys.h"
   27 #include "grab_key.h"
   28 
   29 #ifdef GUILE_FLAG
   30 #include <libguile.h>
   31 #endif
   32 
   33 char *display_name = NULL;
   34 
   35 char rc_file[512];
   36 #ifdef GUILE_FLAG
   37 char rc_guile_file[512];
   38 #endif
   39 
   40 int verbose = 0;
   41 int poll_rc = 0;
   42 int have_to_show_binding = 0;
   43 int have_to_get_binding = 0;
   44 int have_to_start_as_daemon = 1;
   45 int detectable_ar = 0;
   46 
   47 char *geom = NULL;
   48 
   49 
   50 static void show_version (void);
   51 static void show_help (void);
   52 static void show_defaults_rc (void);
   53 #ifdef GUILE_FLAG
   54 static void show_defaults_guile_rc (void);
   55 int init_xbk_guile_fns (void);
   56 SCM set_numlock_wrapper (SCM x);
   57 SCM set_scrolllock_wrapper (SCM x);
   58 SCM set_capslock_wrapper (SCM x);
   59 SCM xbindkey_wrapper(SCM key, SCM cmd);
   60 SCM xbindkey_function_wrapper(SCM key, SCM fun);
   61 SCM remove_xbindkey_wrapper(SCM key);
   62 SCM run_command_wrapper (SCM command);
   63 SCM grab_all_keys_wrapper (void);
   64 SCM ungrab_all_keys_wrapper (void);
   65 SCM remove_all_keys_wrapper (void);
   66 SCM debug_info_wrapper (void);
   67 #endif
   68 
   69 
   70 
   71 void
   72 get_options (int argc, char **argv)
   73 {
   74   int i;
   75   char *home;
   76 
   77   strncpy (rc_file, "", sizeof(rc_file));
   78 #ifdef GUILE_FLAG
   79   strncpy (rc_guile_file, "", sizeof (rc_guile_file));
   80 #endif
   81 
   82   verbose = 0;
   83   have_to_show_binding = 0;
   84   have_to_get_binding = 0;
   85   have_to_start_as_daemon = 1;
   86 
   87 
   88   for (i = 1; i < argc; i++)
   89     {
   90       if (strcmp (argv[i], "-V") == 0 || strcmp (argv[i], "--version") == 0)
   91     {
   92       show_version ();
   93       exit (1);
   94     }
   95       else if ((strcmp (argv[i], "-X") == 0
   96         || strcmp (argv[i], "--display") == 0) && i + 1 < argc)
   97     {
   98       display_name = argv[++i];
   99     }
  100       else if ((strcmp (argv[i], "-f") == 0
  101         || strcmp (argv[i], "--file") == 0) && i + 1 < argc)
  102     {
  103       strncpy (rc_file, argv[++i], sizeof (rc_file) - 1);
  104     }
  105 #ifdef GUILE_FLAG
  106       else if ((strcmp (argv[i], "-fg") == 0
  107         || strcmp (argv[i], "--guile-file") == 0) && i + 1 < argc)
  108     {
  109       strncpy (rc_guile_file, argv[++i], sizeof (rc_guile_file) - 1);
  110     }
  111 #endif
  112       else if (strcmp (argv[i], "-p") == 0 || strcmp (argv[i], "--poll-rc") == 0)
  113     {
  114       poll_rc = 1;
  115     }
  116       else if (strcmp (argv[i], "-s") == 0 || strcmp (argv[i], "--show") == 0)
  117     {
  118       have_to_show_binding = 1;
  119     }
  120       else if (strcmp (argv[i], "-k") == 0 || strcmp (argv[i], "--key") == 0)
  121     {
  122       have_to_get_binding = 1;
  123     }
  124       else if (strcmp (argv[i], "-mk") == 0
  125            || strcmp (argv[i], "--multikey") == 0)
  126     {
  127       have_to_get_binding = 2;
  128     }
  129       else if (strcmp (argv[i], "-v") == 0
  130            || strcmp (argv[i], "--verbose") == 0)
  131     {
  132       verbose = 1;
  133       have_to_start_as_daemon = 0;
  134     }
  135       else if (strcmp (argv[i], "-d") == 0
  136            || strcmp (argv[i], "--defaults") == 0)
  137     {
  138       show_defaults_rc ();
  139     }
  140 #ifdef GUILE_FLAG
  141       else if (strcmp (argv[i], "-dg") == 0
  142            || strcmp (argv[i], "--defaults-guile") == 0)
  143     {
  144       show_defaults_guile_rc ();
  145     }
  146 #endif
  147       else if (strcmp (argv[i], "-h") == 0 || strcmp (argv[i], "--help") == 0)
  148     {
  149       show_help ();
  150       exit (1);
  151     }
  152       else if ((strcmp (argv[i], "-g") == 0
  153         || strcmp (argv[i], "--geometry") == 0) && i + 1 < argc)
  154     {
  155       geom = argv[++i];
  156     }
  157       else if (strcmp (argv[i], "-n") == 0
  158            || strcmp (argv[i], "--nodaemon") == 0)
  159     {
  160       have_to_start_as_daemon = 0;
  161     }
  162       else if (strcmp (argv[i], "-sd") == 0
  163            || strcmp (argv[i], "--detectable-ar") == 0)
  164     {
  165       detectable_ar = 1;
  166     }
  167       else
  168     {
  169       show_help ();
  170       exit (1);
  171     }
  172     }
  173 
  174   if (strcmp (rc_file, "") == 0)
  175     {
  176       home = getenv ("HOME");
  177 
  178       if (rc_file != NULL)
  179     {
  180       strncpy (rc_file, home, sizeof (rc_file) - 20);
  181       strncat (rc_file, "/.xbindkeysrc", 20);
  182     }
  183     }
  184 
  185 #ifdef GUILE_FLAG
  186   if (strcmp (rc_guile_file, "") == 0)
  187     {
  188       home = getenv ("HOME");
  189 
  190       if (rc_guile_file != NULL)
  191     {
  192       strncpy (rc_guile_file, home, sizeof (rc_guile_file) - 20);
  193       strncat (rc_guile_file, "/.xbindkeysrc.scm", 20);
  194     }
  195     }
  196 #endif
  197 }
  198 
  199 void
  200 show_options (void)
  201 {
  202   if (verbose)
  203     {
  204       printf ("displayName = %s\n", display_name);
  205       printf ("rc file = %s\n", rc_file);
  206 #ifdef GUILE_FLAG
  207       printf ("rc guile file = %s\n", rc_guile_file);
  208 #endif
  209     }
  210 }
  211 
  212 
  213 static void
  214 show_version (void)
  215 {
  216   fprintf (stderr, "xbindkeys %s by Philippe Brochard\n", PACKAGE_VERSION);
  217 }
  218 
  219 static void
  220 show_help (void)
  221 {
  222   show_version ();
  223 
  224   fprintf (stderr, "usage: xbindkeys [options]\n");
  225   fprintf (stderr, "  where options are:\n");
  226 
  227   fprintf (stderr, "  -V, --version           Print version and exit\n");
  228   fprintf (stderr, "  -d, --defaults          Print a default rc file\n");
  229 #ifdef GUILE_FLAG
  230   fprintf (stderr, " -dg, --defaults-guile    Print a default guile configuration file\n");
  231 #endif
  232   fprintf (stderr, "  -f, --file              Use an alternative rc file\n");
  233 #ifdef GUILE_FLAG
  234   fprintf (stderr, " -fg, --file-guile        Use an alternative guile configuration file\n");
  235 #endif
  236   fprintf (stderr, "  -p, --poll-rc           Poll the rc/guile configs for updates\n");
  237   fprintf (stderr, "  -h, --help              This help!\n");
  238   fprintf (stderr, "  -X, --display           Set X display to use\n");
  239   fprintf (stderr,
  240        "  -v, --verbose           More information on xbindkeys when it run\n");
  241   fprintf (stderr, "  -s, --show              Show the actual keybinding\n");
  242   fprintf (stderr, "  -k, --key               Identify one key pressed\n");
  243   fprintf (stderr, " -mk, --multikey          Identify multi key pressed\n");
  244   fprintf (stderr,
  245        "  -g, --geometry          size and position of window open with -k|-mk option\n");
  246   fprintf (stderr, "  -n, --nodaemon          don't start as daemon\n");
  247 }
  248 
  249 
  250 static void
  251 show_defaults_rc (void)
  252 {
  253   printf ("# For the benefit of emacs users: -*- shell-script -*-\n");
  254   printf ("###########################\n");
  255   printf ("# xbindkeys configuration #\n");
  256   printf ("###########################\n");
  257   printf ("#\n");
  258   printf ("# Version: %s\n", PACKAGE_VERSION);
  259   printf ("#\n");
  260   printf ("# If you edit this file, do not forget to uncomment any lines\n");
  261   printf ("# that you change.\n");
  262   printf ("# The pound(#) symbol may be used anywhere for comments.\n");
  263   printf ("#\n");
  264 
  265   printf ("# To specify a key, you can use 'xbindkeys --key' or\n");
  266   printf
  267     ("# 'xbindkeys --multikey' and put one of the two lines in this file.\n");
  268   printf ("#\n");
  269   printf ("# The format of a command line is:\n");
  270   printf ("#    \"command to start\"\n");
  271   printf ("#       associated key\n");
  272   printf ("#\n");
  273   printf ("#\n");
  274   printf ("# A list of keys is in /usr/include/X11/keysym.h and in\n");
  275   printf ("# /usr/include/X11/keysymdef.h\n");
  276   printf ("# The XK_ is not needed.\n");
  277   printf ("#\n");
  278   printf ("# List of modifier:\n");
  279   printf ("#   Release, Control, Shift, Mod1 (Alt), Mod2 (NumLock),\n");
  280   printf ("#   Mod3 (CapsLock), Mod4, Mod5 (Scroll).\n");
  281   printf ("#\n");
  282   printf ("\n");
  283   printf ("# The release modifier is not a standard X modifier, but you can\n");
  284   printf ("# use it if you want to catch release events instead of press events\n");
  285   printf ("\n");
  286   printf
  287     ("# By defaults, xbindkeys does not pay attention with the modifiers\n");
  288   printf ("# NumLock, CapsLock and ScrollLock.\n");
  289   printf
  290     ("# Uncomment the lines above if you want to pay attention to them.\n");
  291   printf ("\n");
  292   printf ("#keystate_numlock = enable\n");
  293   printf ("#keystate_capslock = enable\n");
  294   printf ("#keystate_scrolllock= enable\n");
  295   printf ("\n");
  296   printf ("# Examples of commands:\n");
  297   printf ("\n");
  298 
  299   printf ("\"xbindkeys_show\" \n");
  300   printf ("  control+shift + q\n");
  301   printf ("\n");
  302   printf ("# set directly keycode (here control + f with my keyboard)\n");
  303   printf ("\"xterm\"\n");
  304   printf ("  c:41 + m:0x4\n");
  305   printf ("\n");
  306   printf ("# specify a mouse button\n");
  307   printf ("\"xterm\"\n");
  308   printf ("  control + b:2\n");
  309   printf ("\n");
  310   printf ("#\"xterm -geom 50x20+20+20\"\n");
  311   printf ("#   Shift+Mod2+alt + s\n");
  312   printf ("#\n");
  313   printf
  314     ("## set directly keycode (here control+alt+mod2 + f with my keyboard)\n");
  315   printf ("#\"xterm\"\n");
  316   printf ("#  alt + c:0x29 + m:4 + mod2\n");
  317   printf ("#\n");
  318   printf ("## Control+Shift+a  release event starts rxvt\n");
  319   printf ("#\"rxvt\"\n");
  320   printf ("#  release+control+shift + a\n");
  321   printf ("#\n");
  322   printf ("## Control + mouse button 2 release event starts rxvt\n");
  323   printf ("#\"rxvt\"\n");
  324   printf ("#  Control + b:2 + Release\n");
  325 
  326   printf ("\n");
  327   printf ("##################################\n");
  328   printf ("# End of xbindkeys configuration #\n");
  329   printf ("##################################\n");
  330 
  331   exit (1);
  332 }
  333 
  334 
  335 #ifdef GUILE_FLAG
  336 static void
  337 show_defaults_guile_rc (void)
  338 {
  339   printf (";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
  340   printf (";; Start of xbindkeys guile configuration ;;\n");
  341   printf (";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
  342   printf (";; This configuration is guile based.\n");
  343   printf (";;   http://www.gnu.org/software/guile/guile.html\n");
  344   printf (";; any functions that work in guile will work here.\n");
  345   printf (";; see EXTRA FUNCTIONS:\n");
  346   printf ("\n");
  347   printf (";; Version: %s\n", PACKAGE_VERSION);
  348   printf ("\n");
  349   printf (";; If you edit this file, do not forget to uncomment any lines\n");
  350   printf (";; that you change.\n");
  351   printf (";; The semicolon(;) symbol may be used anywhere for comments.\n");
  352   printf ("\n");
  353   printf (";; To specify a key, you can use 'xbindkeys --key' or\n");
  354   printf (";; 'xbindkeys --multikey' and put one of the two lines in this file.\n");
  355   printf ("\n");
  356   printf (";; A list of keys is in /usr/include/X11/keysym.h and in\n");
  357   printf (";; /usr/include/X11/keysymdef.h\n");
  358   printf (";; The XK_ is not needed.\n");
  359   printf ("\n");
  360   printf (";; List of modifier:\n");
  361   printf (";;   Release, Control, Shift, Mod1 (Alt), Mod2 (NumLock),\n");
  362   printf (";;   Mod3 (CapsLock), Mod4, Mod5 (Scroll).\n");
  363   printf ("\n");
  364   printf ("\n");
  365   printf (";; The release modifier is not a standard X modifier, but you can\n");
  366   printf (";; use it if you want to catch release instead of press events\n");
  367   printf ("\n");
  368   printf (";; By defaults, xbindkeys does not pay attention to modifiers\n");
  369   printf (";; NumLock, CapsLock and ScrollLock.\n");
  370   printf (";; Uncomment the lines below if you want to use them.\n");
  371   printf (";; To dissable them, call the functions with #f\n");
  372   printf ("\n");
  373   printf ("\n");
  374   printf (";;;;EXTRA FUNCTIONS: Enable numlock, scrolllock or capslock usage\n");
  375   printf (";;(set-numlock! #t)\n");
  376   printf (";;(set-scrolllock! #t)\n");
  377   printf (";;(set-capslock! #t)\n");
  378   printf ("\n");
  379   printf (";;;;; Scheme API reference\n");
  380   printf (";;;;\n");
  381   printf (";; Optional modifier state:\n");
  382   printf (";; (set-numlock! #f or #t)\n");
  383   printf (";; (set-scrolllock! #f or #t)\n");
  384   printf (";; (set-capslock! #f or #t)\n");
  385   printf (";; \n");
  386   printf (";; Shell command key:\n");
  387   printf (";; (xbindkey key \"foo-bar-command [args]\")\n");
  388   printf (";; (xbindkey '(modifier* key) \"foo-bar-command [args]\")\n");
  389   printf (";; \n");
  390   printf (";; Scheme function key:\n");
  391   printf (";; (xbindkey-function key function-name-or-lambda-function)\n");
  392   printf (";; (xbindkey-function '(modifier* key) function-name-or-lambda-function)\n");
  393   printf (";; \n");
  394   printf (";; Other functions:\n");
  395   printf (";; (remove-xbindkey key)\n");
  396   printf (";; (run-command \"foo-bar-command [args]\")\n");
  397   printf (";; (grab-all-keys)\n");
  398   printf (";; (ungrab-all-keys)\n");
  399   printf (";; (remove-all-keys)\n");
  400   printf (";; (debug)\n");
  401   printf ("\n");
  402   printf ("\n");
  403   printf (";; Examples of commands:\n");
  404   printf ("\n");
  405   printf ("(xbindkey '(control shift q) \"xbindkeys_show\")\n");
  406   printf ("\n");
  407   printf (";; set directly keycode (here control + f with my keyboard)\n");
  408   printf ("(xbindkey '(\"m:0x4\" \"c:41\") \"xterm\")\n");
  409   printf ("\n");
  410   printf (";; specify a mouse button\n");
  411   printf ("(xbindkey '(control \"b:2\") \"xterm\")\n");
  412   printf ("\n");
  413   printf (";;(xbindkey '(shift mod2 alt s) \"xterm -geom 50x20+20+20\")\n");
  414   printf ("\n");
  415   printf (";; set directly keycode (control+alt+mod2 + f with my keyboard)\n");
  416   printf ("(xbindkey '(alt \"m:4\" mod2 \"c:0x29\") \"xterm\")\n");
  417   printf ("\n");
  418   printf (";; Control+Shift+a  release event starts rxvt\n");
  419   printf (";;(xbindkey '(release control shift a) \"rxvt\")\n");
  420   printf ("\n");
  421   printf (";; Control + mouse button 2 release event starts rxvt\n");
  422   printf (";;(xbindkey '(releace control \"b:2\") \"rxvt\")\n");
  423   printf ("\n");
  424   printf ("\n");
  425   printf (";; Extra features\n");
  426   printf ("(xbindkey-function '(control a)\n");
  427   printf ("        (lambda ()\n");
  428   printf ("          (display \"Hello from Scheme!\")\n");
  429   printf ("          (newline)))\n");
  430   printf ("\n");
  431   printf ("(xbindkey-function '(shift p)\n");
  432   printf ("        (lambda ()\n");
  433   printf ("          (run-command \"xterm\")))\n");
  434   printf ("\n");
  435   printf ("\n");
  436   printf (";; Double click test\n");
  437   printf ("(xbindkey-function '(control w)\n");
  438   printf ("        (let ((count 0))\n");
  439   printf ("          (lambda ()\n");
  440   printf ("            (set! count (+ count 1))\n");
  441   printf ("            (if (> count 1)\n");
  442   printf ("            (begin\n");
  443   printf ("             (set! count 0)\n");
  444   printf ("             (run-command \"xterm\"))))))\n");
  445   printf ("\n");
  446   printf (";; Time double click test:\n");
  447   printf (";;  - short double click -> run an xterm\n");
  448   printf (";;  - long  double click -> run an rxvt\n");
  449   printf ("(xbindkey-function '(shift w)\n");
  450   printf ("        (let ((time (current-time))\n");
  451   printf ("          (count 0))\n");
  452   printf ("          (lambda ()\n");
  453   printf ("            (set! count (+ count 1))\n");
  454   printf ("            (if (> count 1)\n");
  455   printf ("            (begin\n");
  456   printf ("             (if (< (- (current-time) time) 1)\n");
  457   printf ("             (run-command \"xterm\")\n");
  458   printf ("             (run-command \"rxvt\"))\n");
  459   printf ("             (set! count 0)))\n");
  460   printf ("            (set! time (current-time)))))\n");
  461   printf ("\n");
  462   printf ("\n");
  463   printf (";; Chording keys test: Start differents program if only one key is\n");
  464   printf (";; pressed or another if two keys are pressed.\n");
  465   printf (";; If key1 is pressed start cmd-k1\n");
  466   printf (";; If key2 is pressed start cmd-k2\n");
  467   printf (";; If both are pressed start cmd-k1-k2 or cmd-k2-k1 following the\n");
  468   printf (";;   release order\n");
  469   printf ("(define (define-chord-keys key1 key2 cmd-k1 cmd-k2 cmd-k1-k2 cmd-k2-k1)\n");
  470   printf ("    \"Define chording keys\"\n");
  471   printf ("  (let ((k1 #f) (k2 #f))\n");
  472   printf ("    (xbindkey-function key1 (lambda () (set! k1 #t)))\n");
  473   printf ("    (xbindkey-function key2 (lambda () (set! k2 #t)))\n");
  474   printf ("    (xbindkey-function (cons 'release key1)\n");
  475   printf ("            (lambda ()\n");
  476   printf ("          (if (and k1 k2)\n");
  477   printf ("              (run-command cmd-k1-k2)\n");
  478   printf ("              (if k1 (run-command cmd-k1)))\n");
  479   printf ("          (set! k1 #f) (set! k2 #f)))\n");
  480   printf ("    (xbindkey-function (cons 'release key2)\n");
  481   printf ("            (lambda ()\n");
  482   printf ("          (if (and k1 k2)\n");
  483   printf ("              (run-command cmd-k2-k1)\n");
  484   printf ("              (if k2 (run-command cmd-k2)))\n");
  485   printf ("          (set! k1 #f) (set! k2 #f)))))\n");
  486   printf ("\n");
  487   printf ("\n");
  488   printf (";; Example:\n");
  489   printf (";;   Shift + b:1                   start an xterm\n");
  490   printf (";;   Shift + b:3                   start an rxvt\n");
  491   printf (";;   Shift + b:1 then Shift + b:3  start gv\n");
  492   printf (";;   Shift + b:3 then Shift + b:1  start xpdf\n");
  493   printf ("\n");
  494   printf ("(define-chord-keys '(shift \"b:1\") '(shift \"b:3\")\n");
  495   printf ("  \"xterm\" \"rxvt\" \"gv\" \"xpdf\")\n");
  496   printf ("\n");
  497   printf (";; Here the release order have no importance\n");
  498   printf (";; (the same program is started in both case)\n");
  499   printf ("(define-chord-keys '(alt \"b:1\") '(alt \"b:3\")\n");
  500   printf ("  \"gv\" \"xpdf\" \"xterm\" \"xterm\")\n");
  501   printf ("\n");
  502   printf ("\n");
  503   printf (";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
  504   printf (";; End of xbindkeys guile configuration ;;\n");
  505   printf (";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
  506 
  507   exit (1);
  508 }
  509 #endif
  510 
  511 
  512 
  513 static int
  514 file_exist (char * filename)
  515 {
  516   FILE * stream;
  517 
  518   if ((stream = fopen (filename, "r")) == NULL)
  519       return 0;
  520 
  521   fclose (stream);
  522   return 1;
  523 }
  524 
  525 
  526 int
  527 rc_file_exist (void)
  528 {
  529 #ifdef GUILE_FLAG
  530   if (file_exist (rc_guile_file))
  531     return 1;
  532 #endif
  533 
  534   if (!file_exist (rc_file))
  535     {
  536       fprintf (stderr, "Error : %s not found or reading not allowed.\n",
  537            rc_file);
  538       fprintf (stderr,
  539            "please, create one with 'xbindkeys --defaults > %s'.\n",
  540            rc_file);
  541 #ifdef GUILE_FLAG
  542       fprintf (stderr,
  543            "or, if you want scheme configuration style,\n");
  544       fprintf (stderr,
  545            "with 'xbindkeys --defaults-guile > %s'.\n",
  546            rc_guile_file);
  547 #endif
  548       return 0;
  549     }
  550 
  551   return 1;
  552 }
  553 
  554 
  555 
  556 
  557 
  558 int
  559 get_rc_file (void)
  560 {
  561   char line[1024];
  562   char line2[1024];
  563   char command[1024];
  564   KeyType_t type;
  565   EventType_t event_type;
  566   KeySym keysym;
  567   KeyCode keycode;
  568   unsigned int button;
  569   unsigned int modifier;
  570   FILE *stream = NULL;
  571   char *pos1;
  572   char *pos2;
  573   char *p;
  574   int i;
  575 
  576 
  577   if (init_keys () != 0)
  578     return (-1);
  579 
  580   /* Open RC File */
  581   if ((stream = fopen (rc_file, "r")) == NULL)
  582     {
  583       fprintf (stderr, "Error : %s not found or reading not allowed.\n",
  584            rc_file);
  585       fprintf (stderr,
  586            "please, create one with 'xbindkeys --defaults > %s'.\n",
  587            rc_file);
  588       return (-1);
  589     }
  590 
  591 
  592   /* Read RC file */
  593   while (fgets (line, sizeof (line), stream))
  594     {
  595       /* search for keystate options */
  596       if (strstr (line, "keystate_numlock") != NULL)
  597     {
  598       /* search for comment or command line */
  599       pos1 = strchr (line, '"');
  600       pos2 = strchr (line, '#');
  601       if (!pos1 && !pos2)
  602         {
  603           if (strstr (line, "enable") != NULL)
  604         {
  605           numlock_mask = 0;
  606         }
  607           if (verbose)
  608         printf ("keystate_numlock: %s\n",
  609             numlock_mask == 0 ? "Enabled" : "Disabled");
  610 
  611           continue;
  612         }
  613     }
  614 
  615       if (strstr (line, "keystate_capslock") != NULL)
  616     {
  617       /* search for comment or command line */
  618       pos1 = strchr (line, '"');
  619       pos2 = strchr (line, '#');
  620       if (!pos1 && !pos2)
  621         {
  622           if (strstr (line, "enable") != NULL)
  623         {
  624           capslock_mask = 0;
  625         }
  626           if (verbose)
  627         printf ("keystate_capslock: %s\n",
  628             capslock_mask == 0 ? "Enabled" : "Disabled");
  629 
  630           continue;
  631         }
  632     }
  633 
  634       if (strstr (line, "keystate_scrolllock") != NULL)
  635     {
  636       /* search for comment or command line */
  637       pos1 = strchr (line, '"');
  638       pos2 = strchr (line, '#');
  639       if (!pos1 && !pos2)
  640         {
  641           if (strstr (line, "enable") != NULL)
  642         {
  643           scrolllock_mask = 0;
  644         }
  645           if (verbose)
  646         printf ("keystate_scrolllock: %s\n",
  647             scrolllock_mask == 0 ? "Enabled" : "Disabled");
  648 
  649           continue;
  650         }
  651     }
  652 
  653 
  654       pos1 = strchr (line, '"');
  655       if (pos1)
  656     {
  657       pos2 = strchr (line, '#');
  658 
  659       if (!pos2 || pos2 > pos1)
  660         {
  661           /* search for command line */
  662           pos2 = strrchr (line, '"');
  663           if (pos2 && pos1 < pos2)
  664         {
  665           command[0] = '\0';
  666           type = SYM;
  667           event_type = PRESS;
  668           keysym = 0;
  669           keycode = 0;
  670           button = 0;
  671           modifier = 0;
  672 
  673           for (p = pos1 + 1, i = 0;
  674                p < pos2 && i < sizeof (command); p++, i++)
  675             {
  676               command[i] = *p;
  677             }
  678           command[i] = '\0';
  679 
  680           /* get associated keys */
  681           if (fgets (line, sizeof (line), stream))
  682             {
  683               pos1 = line;
  684 
  685               while (*pos1 != '\n')
  686             {
  687               /* jump space */
  688               for (; *pos1 == '+' || *pos1 == ' '
  689                    || *pos1 == '\t'; pos1++);
  690 
  691               /* find corresponding + or \n */
  692               pos2 = strchr (pos1, '+');
  693               if (!pos2)
  694                 {
  695                   for (pos2 = pos1; *pos2 != '\n'; pos2++);
  696                 }
  697 
  698               /* copy string in line2 */
  699               for (p = pos1, i = 0;
  700                    p < pos2 && i < sizeof (line2)
  701                    && *p != '+' && *p != ' ' && *p != '\t';
  702                    p++, i++)
  703                 {
  704                   line2[i] = *p;
  705                 }
  706               line2[i] = '\0';
  707 
  708               /* is a numeric keycode (c:nnn) ? */
  709               if (line2[0] == 'c' && line2[1] == ':')
  710                 {
  711                   if (isdigit (line2[2]))
  712                 {
  713                   type = CODE;
  714                   keycode = strtol (line2+2, (char **) NULL, 0);
  715                 }
  716                   else
  717                 {
  718                   keysym = 0;
  719                   keycode = 0;
  720                   button = 0;
  721                   break;
  722                 }
  723                 }
  724               else
  725                 /* is a numeric modifier (m:nnn) ? */
  726               if (line2[0] == 'm' && line2[1] == ':')
  727                 {
  728                   if (isdigit (line2[2]))
  729                 {
  730                   modifier |= strtol (line2+2, (char **) NULL, 0);
  731                 }
  732                   else
  733                 {
  734                   keysym = 0;
  735                   keycode = 0;
  736                   button = 0;
  737                   break;
  738                 }
  739                 }
  740               else
  741                 /* is a mouse button (b:nnn) ? */
  742               if (line2[0] == 'b' && line2[1] == ':')
  743                 {
  744                   if (isdigit (line2[2]))
  745                 {
  746                   type = BUTTON;
  747                   button = strtol (line2+2, (char **) NULL, 0);
  748                 }
  749                   else
  750                 {
  751                   keysym = 0;
  752                   keycode = 0;
  753                   button = 0;
  754                   break;
  755                 }
  756                 }
  757               else
  758                 {
  759                   /* apply to modifier, release/press or key */
  760                   if (strcasecmp (line2, "control") == 0)
  761                 modifier |= ControlMask;
  762                   else if (strcasecmp (line2, "shift") == 0)
  763                 modifier |= ShiftMask;
  764                   else if (strcasecmp (line2, "mod1") == 0
  765                        || strcasecmp (line2, "alt") == 0)
  766                 modifier |= Mod1Mask;
  767                   else if (strcasecmp (line2, "mod2") == 0)
  768                 modifier |= Mod2Mask;
  769                   else if (strcasecmp (line2, "mod3") == 0)
  770                 modifier |= Mod3Mask;
  771                   else if (strcasecmp (line2, "mod4") == 0)
  772                 modifier |= Mod4Mask;
  773                   else if (strcasecmp (line2, "mod5") == 0)
  774                 modifier |= Mod5Mask;
  775                   else if (strcasecmp (line2, "release") == 0)
  776                 event_type = RELEASE;
  777                   else
  778                 {
  779                   type = SYM;
  780                   keysym = XStringToKeysym (line2);
  781                   if (keysym == 0)
  782                     break;
  783                 }
  784                 }
  785 
  786               pos1 = pos2;
  787             }
  788             }
  789 
  790           if (add_key (type, event_type, keysym, keycode,
  791                    button, modifier, command, 0) != 0)
  792             break;
  793         }
  794         }
  795     }
  796     }
  797 
  798 
  799   /* Close RC File */
  800   if (stream != NULL)
  801     fclose (stream);
  802 
  803   if (keys == NULL)
  804     {
  805       fprintf (stderr, "Error in alocation of keys\n");
  806       return (-1);
  807     }
  808 
  809   /* Verify if all is good (like my english) */
  810   for (i = 0; i < nb_keys; i++)
  811     {
  812       if (keys[i].key.sym == 0 || keys[i].command == NULL)
  813     {
  814       fprintf (stderr, "Error in RC file : %s\n", rc_file);
  815       return (-1);
  816     }
  817     }
  818 
  819   if (verbose)
  820     printf ("%d keys in %s\n", nb_keys, rc_file);
  821 
  822   return (0);
  823 }
  824 
  825 
  826 
  827 //Everything from here on out has been changed by MMH
  828 #ifdef GUILE_FLAG
  829 int
  830 init_xbk_guile_fns (void)
  831 {
  832   if (verbose)
  833     printf("initializing guile fns...\n");
  834   scm_c_define_gsubr("set-numlock!", 1, 0, 0, set_numlock_wrapper);
  835   scm_c_define_gsubr("set-scrolllock!", 1, 0, 0, set_scrolllock_wrapper);
  836   scm_c_define_gsubr("set-capslock!", 1, 0, 0, set_capslock_wrapper);
  837   scm_c_define_gsubr("xbindkey", 2, 0, 0, xbindkey_wrapper);
  838   scm_c_define_gsubr("xbindkey-function", 2, 0, 0, xbindkey_function_wrapper);
  839   scm_c_define_gsubr("remove-xbindkey", 1, 0, 0, remove_xbindkey_wrapper);
  840   scm_c_define_gsubr("run-command", 1, 0, 0, run_command_wrapper);
  841   scm_c_define_gsubr("grab-all-keys", 0, 0, 0, grab_all_keys_wrapper);
  842   scm_c_define_gsubr("ungrab-all-keys", 0, 0, 0, ungrab_all_keys_wrapper);
  843   scm_c_define_gsubr("remove-all-keys", 0, 0, 0, remove_all_keys_wrapper);
  844   scm_c_define_gsubr("debug", 0, 0, 0, debug_info_wrapper);
  845   return 0;
  846 }
  847 
  848 int
  849 get_rc_guile_file (void)
  850 {
  851   FILE *stream;
  852 
  853   if (verbose)
  854     printf("getting rc guile file %s.\n", rc_guile_file);
  855 
  856   if (init_keys () != 0)
  857     return (-1);
  858 
  859   /* Open RC File */
  860   if ((stream = fopen (rc_guile_file, "r")) == NULL)
  861     {
  862       if (verbose)
  863     fprintf (stderr, "WARNING : %s not found or reading not allowed.\n",
  864          rc_guile_file);
  865       return (-1);
  866     }
  867   fclose (stream);
  868 
  869   init_xbk_guile_fns();
  870   scm_primitive_load(scm_from_locale_string(rc_guile_file));
  871   return 0;
  872 }
  873 
  874 #define MAKE_MASK_WRAPPER(name, mask_name) \
  875 SCM name (SCM val) \
  876 { \
  877   if (verbose) \
  878     printf("Running mask cmd!\n"); \
  879   mask_name = SCM_FALSEP(val); \
  880   return SCM_UNSPECIFIED; \
  881 }
  882 
  883 MAKE_MASK_WRAPPER(set_numlock_wrapper, numlock_mask);
  884 MAKE_MASK_WRAPPER(set_scrolllock_wrapper, scrolllock_mask);
  885 MAKE_MASK_WRAPPER(set_capslock_wrapper, capslock_mask);
  886 
  887 
  888 
  889 SCM extract_key (SCM key, KeyType_t *type, EventType_t *event_type,
  890          KeySym *keysym, KeyCode *keycode,
  891          unsigned int *button, unsigned int *modifier)
  892 {
  893   char *str;
  894   int len;
  895 
  896   while(SCM_CONSP(key)){ //Iterate through the list (If it is a list)
  897     if(!SCM_CONSP(SCM_CDR(key))){ //if this is the last item
  898       key = SCM_CAR(key);  //go to that
  899       break; //and continue
  900     }
  901     //Otherwise, this is a modifier.
  902 
  903     //So copy it:
  904     //Guile strings are not \0 terminated. hence we must copy.
  905     if (scm_is_true(scm_symbol_p(SCM_CAR(key)))) {
  906       SCM newkey = scm_symbol_to_string(SCM_CAR(key));
  907       str = scm_to_locale_string(newkey);
  908     } else {
  909       str = scm_to_locale_string(SCM_CAR(key));
  910     }
  911     len = strlen(str);
  912 
  913 
  914     /*str = scm_to_locale_string(SCM_CAR(key));*/
  915 
  916 
  917     if(verbose) //extra verbosity here.
  918       printf("xbindkey_wrapper debug: modifier = %s.\n", str);
  919 
  920     //copied directly with some substitutions. ie. line2 -> str
  921     //Do whatever needs to be done with modifiers.
  922     if (strncasecmp (str, "control", len) == 0)
  923       *modifier |= ControlMask;
  924     else if (strncasecmp (str, "shift", len) == 0)
  925       *modifier |= ShiftMask;
  926     else if (strncasecmp (str, "mod1", len) == 0
  927              || strncasecmp (str, "alt", len) == 0)
  928       *modifier |= Mod1Mask;
  929     else if (strncasecmp (str, "mod2", len) == 0)
  930       *modifier |= Mod2Mask;
  931     else if (strncasecmp (str, "mod3", len) == 0)
  932       *modifier |= Mod3Mask;
  933     else if (strncasecmp (str, "mod4", len) == 0)
  934       *modifier |= Mod4Mask;
  935     else if (strncasecmp (str, "mod5", len) == 0)
  936       *modifier |= Mod5Mask;
  937     else if (strncasecmp (str, "release", len) == 0)
  938       *event_type = RELEASE;
  939     else if(strlen (str) > 2 && str[0] == 'm' && str[1] == ':'){
  940       *modifier |= strtol (str+2, (char **) NULL, 0);
  941       //this break have nothing to do here!
  942       //break
  943     }else{
  944       printf("Bad modifier:\n%s\n", str); //or error
  945       return SCM_BOOL_F; //and return false
  946     }
  947     free(str); //we copied, so we must destroy this
  948     str=NULL;
  949     key = SCM_CDR(key); //and go a step down the list
  950   }
  951   //So this was either the only or last item of the 1st arg
  952   //Hence it is the key
  953 
  954   //So copy it:
  955   //Guile strings are not \0 terminated. hence we must copy.
  956   if (scm_is_true(scm_symbol_p(key))) {
  957     SCM newkey = scm_symbol_to_string(key);
  958     str = scm_to_locale_string(newkey);
  959   } else {
  960     str = scm_to_locale_string(key);
  961   }
  962   len = strlen(str);
  963 
  964   if(verbose)
  965     printf("xbindkey_wrapper debug: key = %s\n", str);
  966 
  967   //Check for special numeric stuff.
  968   //This way is really far nicer looking and more efficient than
  969   //having three copies of the code.
  970   if(strlen (str) > 2 && str[1] == ':' && isdigit (str[2]))
  971     {
  972       switch (str[0])
  973         {
  974     case 'b':
  975       *type = BUTTON;
  976       *button = strtol (str+2, (char **) NULL, 0);
  977       break;
  978     case 'c':
  979       *type = CODE;
  980       *keycode = strtol (str+2, (char **) NULL, 0);
  981       break;
  982     case 'm': //is a modifier so it is in the other part.
  983       printf("bad modifyer: %s.", str);
  984       printf("m: modifiers need be applied to keys\n");
  985       return SCM_BOOL_F;
  986     default:
  987       printf("bad modifyer: %c: shoud be b:, c: or m: .\n", str[0]);
  988       return SCM_BOOL_F;
  989         }
  990     }
  991   else //regular key
  992     {
  993       *type = SYM;
  994       *keysym = XStringToKeysym (str);
  995       if (*keysym == 0){
  996         printf("No keysym for key: %s\n", str);
  997     return SCM_BOOL_F;
  998       }
  999     }
 1000 
 1001   free(str); //these were used by add key and copied.
 1002 
 1003   return SCM_BOOL_T;
 1004 }
 1005 
 1006 
 1007 
 1008 SCM xbindkey_wrapper(SCM key, SCM cmd)
 1009 {
 1010   KeyType_t type = SYM;
 1011   EventType_t event_type = PRESS;
 1012   KeySym keysym = 0;
 1013   KeyCode keycode = 0;
 1014   unsigned int button = 0;
 1015   unsigned int modifier = 0;
 1016   char *cmdstr;
 1017 
 1018   //Guile strings are not \0 terminated. hence we must copy.
 1019   cmdstr = scm_to_locale_string(cmd);
 1020   if(verbose)
 1021     printf("xbindkey_wrapper debug: cmd=%s.\n", cmdstr);
 1022 
 1023   if (extract_key (key, &type, &event_type, &keysym, &keycode,
 1024            &button, &modifier) == SCM_BOOL_F)
 1025     {
 1026       return SCM_BOOL_F;
 1027     }
 1028 
 1029   if (add_key (type, event_type, keysym, keycode,
 1030         button, modifier, cmdstr, 0) != 0)
 1031     {
 1032       printf("add_key didn't return 0!!!\n");
 1033       return SCM_BOOL_F;
 1034     }
 1035 
 1036   free(cmdstr); //we may get rid of them!
 1037 
 1038   return SCM_UNSPECIFIED;
 1039 }
 1040 
 1041 
 1042 SCM tab_scm[2];
 1043 
 1044 SCM xbindkey_function_wrapper (SCM key, SCM fun)
 1045 {
 1046   KeyType_t type = SYM;
 1047   EventType_t event_type = PRESS;
 1048   KeySym keysym = 0;
 1049   KeyCode keycode = 0;
 1050   unsigned int button = 0;
 1051   unsigned int modifier = 0;
 1052 
 1053   if (extract_key (key, &type, &event_type, &keysym, &keycode,
 1054            &button, &modifier) == SCM_BOOL_F)
 1055     {
 1056       return SCM_BOOL_F;
 1057     }
 1058 
 1059   tab_scm[0] = fun;
 1060 
 1061   if (add_key (type, event_type, keysym, keycode,
 1062            button, modifier, NULL, tab_scm[0]) != 0)
 1063     {
 1064       printf("add_key didn't return 0!!!\n");
 1065       return SCM_BOOL_F;
 1066     }
 1067   else {
 1068     printf ("add_key ok!!!  fun=%d\n", (scm_procedure_p (fun) == SCM_BOOL_T));
 1069   }
 1070 
 1071   //scm_permanent_object (tab_scm[0]);
 1072   scm_remember_upto_here_1 (tab_scm[0]);
 1073 
 1074   return SCM_UNSPECIFIED;
 1075 }
 1076 
 1077 
 1078 
 1079 SCM remove_xbindkey_wrapper (SCM key)
 1080 {
 1081   KeyType_t type = SYM;
 1082   EventType_t event_type = PRESS;
 1083   KeySym keysym = 0;
 1084   KeyCode keycode = 0;
 1085   unsigned int button = 0;
 1086   unsigned int modifier = 0;
 1087 
 1088   if (extract_key (key, &type, &event_type, &keysym, &keycode,
 1089            &button, &modifier) == SCM_BOOL_F)
 1090     {
 1091       return SCM_BOOL_F;
 1092     }
 1093 
 1094   if (remove_key (type, event_type, keysym, keycode, button, modifier) != 0)
 1095     {
 1096       printf("remove_key didn't return 0!!!\n");
 1097       return SCM_BOOL_F;
 1098     }
 1099 
 1100 
 1101   return SCM_UNSPECIFIED;
 1102 }
 1103 
 1104 
 1105 SCM run_command_wrapper (SCM command)
 1106 {
 1107   char *cmdstr;
 1108 
 1109   cmdstr = scm_to_locale_string(command);
 1110 
 1111   run_command (cmdstr);
 1112 
 1113   free(cmdstr);
 1114 
 1115   return SCM_UNSPECIFIED;
 1116 }
 1117 
 1118 SCM grab_all_keys_wrapper (void)
 1119 {
 1120   grab_keys (current_display);
 1121 
 1122   return SCM_UNSPECIFIED;
 1123 }
 1124 
 1125 
 1126 SCM ungrab_all_keys_wrapper (void)
 1127 {
 1128   ungrab_all_keys (current_display);
 1129 
 1130   return SCM_UNSPECIFIED;
 1131 }
 1132 
 1133 SCM remove_all_keys_wrapper (void)
 1134 {
 1135   close_keys ();
 1136 
 1137   return SCM_UNSPECIFIED;
 1138 }
 1139 
 1140 
 1141 SCM debug_info_wrapper (void)
 1142 {
 1143   printf ("\nKeys = %p\n", keys);
 1144   printf ("nb_keys = %d\n", nb_keys);
 1145 
 1146   return SCM_UNSPECIFIED;
 1147 }
 1148 
 1149 #endif