Logo Search packages:      
Sourcecode: xbindkeys version File versions  Download package

options.c

/***************************************************************************
        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);
#endif



void
get_options (int argc, char **argv)
{
  int i;
  char *home;

  strcpy (rc_file, "");
#ifdef GUILE_FLAG
  strcpy (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);
        strcat (rc_file, "/.xbindkeysrc");
      }
    }

#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);
        strcat (rc_guile_file, "/.xbindkeysrc.scm");
      }
    }
#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 configuration ;\n");
  printf (";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
  printf ("; This configuration is guile based.\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:\n");
  printf (";(set-numlock! #t)\n");
  printf (";(set-scrolllock! #t)\n");
  printf (";(set-capslock! #t)\n");
  printf (";(xbindkey key \"foo-bar-command [args]\")\n");
  printf (";(xbindkey '(modifier* key) \"foo-bar-command [args]\")\n");
  printf (";that is, xbindkey can take a list of modifiers ended by a key\n");
  printf (";                  or it can just take a plain key.\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 ("; End of xbindkeys 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)
                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_make_gsubr("set-numlock!", 1, 0, 0, set_numlock_wrapper);
  scm_make_gsubr("set-scrolllock!", 1, 0, 0, set_scrolllock_wrapper);
  scm_make_gsubr("set-capslock!", 1, 0, 0, set_capslock_wrapper);
  scm_make_gsubr("xbindkey", 2, 0, 0, xbindkey_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 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, *str;
  int len;
  
  //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);
  
  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;
      }
    }
  if (add_key (type, event_type, keysym, keycode, 
            button, modifier, cmdstr) != 0)
    {
      printf("add_key didn't return 0!!!\n");
      return SCM_BOOL_F;
    }
  
  free(str); //these were used by add key and copied.
  free(cmdstr); //we may get rid of them!

  return SCM_UNSPECIFIED;
}
#endif

Generated by  Doxygen 1.6.0   Back to index