Example #1
0
/**
 * egg_accelerator_parse_virtual:
 * @accelerator:      string representing an accelerator
 * @accelerator_key:  return location for accelerator keyval
 * @accelerator_mods: return location for accelerator modifier mask
 *
 * Parses a string representing a virtual accelerator. The format
 * looks like "<Control>a" or "<Shift><Alt>F1" or
 * "<Release>z" (the last one is for key release).  The parser
 * is fairly liberal and allows lower or upper case, and also
 * abbreviations such as "<Ctl>" and "<Ctrl>".
 *
 * If the parse fails, @accelerator_key and @accelerator_mods will
 * be set to 0 (zero) and %FALSE will be returned. If the string contains
 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
 * returned.
 *
 * The virtual vs. concrete accelerator distinction is a relic of
 * how the X Window System works; there are modifiers Mod2-Mod5 that
 * can represent various keyboard keys (numlock, meta, hyper, etc.),
 * the virtual modifier represents the keyboard key, the concrete
 * modifier the actual Mod2-Mod5 bits in the key press event.
 * 
 * Returns: %TRUE on success.
 */
gboolean
egg_accelerator_parse_virtual (const gchar            *accelerator,
                               guint                  *accelerator_key,
                               EggVirtualModifierType *accelerator_mods)
{
  guint keyval;
  GdkModifierType mods;
  gint len;
  gboolean bad_keyval;
  
  if (accelerator_key)
    *accelerator_key = 0;
  if (accelerator_mods)
    *accelerator_mods = 0;

  g_return_val_if_fail (accelerator != NULL, FALSE);

  bad_keyval = FALSE;
  
  keyval = 0;
  mods = 0;
  len = strlen (accelerator);
  while (len)
    {
      if (*accelerator == '<')
	{
	  if (len >= 9 && is_release (accelerator))
	    {
	      accelerator += 9;
	      len -= 9;
	      mods |= EGG_VIRTUAL_RELEASE_MASK;
	    }
	  else if (len >= 9 && is_control (accelerator))
	    {
	      accelerator += 9;
	      len -= 9;
	      mods |= EGG_VIRTUAL_CONTROL_MASK;
	    }
	  else if (len >= 7 && is_shift (accelerator))
	    {
	      accelerator += 7;
	      len -= 7;
	      mods |= EGG_VIRTUAL_SHIFT_MASK;
	    }
	  else if (len >= 6 && is_shft (accelerator))
	    {
	      accelerator += 6;
	      len -= 6;
	      mods |= EGG_VIRTUAL_SHIFT_MASK;
	    }
	  else if (len >= 6 && is_ctrl (accelerator))
	    {
	      accelerator += 6;
	      len -= 6;
	      mods |= EGG_VIRTUAL_CONTROL_MASK;
	    }
	  else if (len >= 6 && is_modx (accelerator))
	    {
	      static const guint mod_vals[] = {
		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
	      };

	      len -= 6;
	      accelerator += 4;
	      mods |= mod_vals[*accelerator - '1'];
	      accelerator += 2;
	    }
	  else if (len >= 5 && is_ctl (accelerator))
	    {
	      accelerator += 5;
	      len -= 5;
	      mods |= EGG_VIRTUAL_CONTROL_MASK;
	    }
	  else if (len >= 5 && is_alt (accelerator))
	    {
	      accelerator += 5;
	      len -= 5;
	      mods |= EGG_VIRTUAL_ALT_MASK;
	    }
          else if (len >= 6 && is_meta (accelerator))
	    {
	      accelerator += 6;
	      len -= 6;
	      mods |= EGG_VIRTUAL_META_MASK;
	    }
          else if (len >= 7 && is_hyper (accelerator))
	    {
	      accelerator += 7;
	      len -= 7;
	      mods |= EGG_VIRTUAL_HYPER_MASK;
	    }
          else if (len >= 7 && is_super (accelerator))
	    {
	      accelerator += 7;
	      len -= 7;
	      mods |= EGG_VIRTUAL_SUPER_MASK;
	    }
          else if (len >= 9 && is_primary (accelerator))
        {
          accelerator += 9;
          len -= 9;
          mods |= EGG_VIRTUAL_CONTROL_MASK;
        }
	      else
	    {
	      gchar last_ch;
	      
	      last_ch = *accelerator;
	      while (last_ch && last_ch != '>')
            {
		      last_ch = *accelerator;
		      accelerator += 1;
		      len -= 1;
		    }
	    }
	}
      else
	{
          keyval = gdk_keyval_from_name (accelerator);
          
          if (keyval == 0)
            bad_keyval = TRUE;
          
          accelerator += len;
          len -= len;              
	}
    }
  
  if (accelerator_key)
    *accelerator_key = gdk_keyval_to_lower (keyval);
  if (accelerator_mods)
    *accelerator_mods = mods;

  return !bad_keyval;
}
Example #2
0
static gboolean
accelerator_parse (const gchar         *accelerator,
                   MetaKeyCombo        *combo)
{
    guint keyval, keycode;
    MetaVirtualModifier mods;
    gint len;

    combo->keysym = 0;
    combo->keycode = 0;
    combo->modifiers = 0;

    if (accelerator == NULL)
        return FALSE;

    keyval = 0;
    keycode = 0;
    mods = 0;
    len = strlen (accelerator);
    while (len)
    {
        if (*accelerator == '<')
        {
            if (len >= 9 && is_primary (accelerator))
            {
                /* Primary is treated the same as Control */
                accelerator += 9;
                len -= 9;
                mods |= META_VIRTUAL_CONTROL_MASK;
            }
            else if (len >= 9 && is_control (accelerator))
            {
                accelerator += 9;
                len -= 9;
                mods |= META_VIRTUAL_CONTROL_MASK;
            }
            else if (len >= 7 && is_shift (accelerator))
            {
                accelerator += 7;
                len -= 7;
                mods |= META_VIRTUAL_SHIFT_MASK;
            }
            else if (len >= 6 && is_shft (accelerator))
            {
                accelerator += 6;
                len -= 6;
                mods |= META_VIRTUAL_SHIFT_MASK;
            }
            else if (len >= 6 && is_ctrl (accelerator))
            {
                accelerator += 6;
                len -= 6;
                mods |= META_VIRTUAL_CONTROL_MASK;
            }
            else if (len >= 6 && is_modx (accelerator))
            {
                static const guint mod_vals[] = {
                    META_VIRTUAL_ALT_MASK,
                    META_VIRTUAL_MOD2_MASK,
                    META_VIRTUAL_MOD3_MASK,
                    META_VIRTUAL_MOD4_MASK,
                    META_VIRTUAL_MOD5_MASK,
                };

                len -= 6;
                accelerator += 4;
                mods |= mod_vals[*accelerator - '1'];
                accelerator += 2;
            }
            else if (len >= 5 && is_ctl (accelerator))
            {
                accelerator += 5;
                len -= 5;
                mods |= META_VIRTUAL_CONTROL_MASK;
            }
            else if (len >= 5 && is_alt (accelerator))
            {
                accelerator += 5;
                len -= 5;
                mods |= META_VIRTUAL_ALT_MASK;
            }
            else if (len >= 6 && is_meta (accelerator))
            {
                accelerator += 6;
                len -= 6;
                mods |= META_VIRTUAL_META_MASK;
            }
            else if (len >= 7 && is_hyper (accelerator))
            {
                accelerator += 7;
                len -= 7;
                mods |= META_VIRTUAL_HYPER_MASK;
            }
            else if (len >= 7 && is_super (accelerator))
            {
                accelerator += 7;
                len -= 7;
                mods |= META_VIRTUAL_SUPER_MASK;
            }
            else
            {
                gchar last_ch;

                last_ch = *accelerator;
                while (last_ch && last_ch != '>')
                {
                    last_ch = *accelerator;
                    accelerator += 1;
                    len -= 1;
                }
            }
        }
        else
        {
            if (len >= 4 && is_keycode (accelerator))
            {
                keycode = strtoul (accelerator, NULL, 16);
                goto out;
            }
            else if (strcmp (accelerator, "Above_Tab") == 0)
            {
                keyval = META_KEY_ABOVE_TAB;
                goto out;
            }
            else
            {
                keyval = xkb_keysym_from_name (accelerator, XKB_KEYSYM_CASE_INSENSITIVE);
                if (keyval == XKB_KEY_NoSymbol)
                {
                    char *with_xf86 = g_strconcat ("XF86", accelerator, NULL);
                    keyval = xkb_keysym_from_name (with_xf86, XKB_KEYSYM_CASE_INSENSITIVE);
                    g_free (with_xf86);

                    if (keyval == XKB_KEY_NoSymbol)
                        return FALSE;
                }
            }

            accelerator += len;
            len -= len;
        }
    }

out:
    combo->keysym = keyval;
    combo->keycode = keycode;
    combo->modifiers = mods;
    return TRUE;
}
Example #3
0
/**
 * egg_accelerator_parse_virtual:
 * @accelerator:      string representing an accelerator
 * @accelerator_key:  return location for accelerator keyval
 * @accelerator_mods: return location for accelerator modifier mask
 *
 * Parses a string representing a virtual accelerator. The format
 * looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
 * "&lt;Release&gt;z" (the last one is for key release).  The parser
 * is fairly liberal and allows lower or upper case, and also
 * abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
 *
 * If the parse fails, @accelerator_key and @accelerator_mods will
 * be set to 0 (zero) and %FALSE will be returned. If the string contains
 * only modifiers, @accelerator_key will be set to 0 but %TRUE will be
 * returned.
 *
 * The virtual vs. concrete accelerator distinction is a relic of
 * how the X Window System works; there are modifiers Mod2-Mod5 that
 * can represent various keyboard keys (numlock, meta, hyper, etc.),
 * the virtual modifier represents the keyboard key, the concrete
 * modifier the actual Mod2-Mod5 bits in the key press event.
 *
 * Returns: %TRUE on success.
 */
gboolean
egg_accelerator_parse_virtual (const gchar            *accelerator,
                               guint                  *accelerator_key,
			       guint                  *keycode,
                               EggVirtualModifierType *accelerator_mods)
{
  guint keyval;
  GdkModifierType mods;
  gint len;
  gboolean bad_keyval;

  if (accelerator_key)
    *accelerator_key = 0;
  if (accelerator_mods)
    *accelerator_mods = 0;
  if (keycode)
    *keycode = 0;

  g_return_val_if_fail (accelerator != NULL, FALSE);

  bad_keyval = FALSE;

  keyval = 0;
  mods = 0;
  len = strlen (accelerator);
  while (len)
    {
      if (*accelerator == '<')
	{
	  if (len >= 9 && is_release (accelerator))
	    {
	      accelerator += 9;
	      len -= 9;
	      mods |= EGG_VIRTUAL_RELEASE_MASK;
	    }
	  else if (len >= 9 && is_control (accelerator))
	    {
	      accelerator += 9;
	      len -= 9;
	      mods |= EGG_VIRTUAL_CONTROL_MASK;
	    }
	  else if (len >= 7 && is_shift (accelerator))
	    {
	      accelerator += 7;
	      len -= 7;
	      mods |= EGG_VIRTUAL_SHIFT_MASK;
	    }
	  else if (len >= 6 && is_shft (accelerator))
	    {
	      accelerator += 6;
	      len -= 6;
	      mods |= EGG_VIRTUAL_SHIFT_MASK;
	    }
	  else if (len >= 6 && is_ctrl (accelerator))
	    {
	      accelerator += 6;
	      len -= 6;
	      mods |= EGG_VIRTUAL_CONTROL_MASK;
	    }
	  else if (len >= 6 && is_modx (accelerator))
	    {
	      static const guint mod_vals[] = {
		EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
		EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
	      };

	      len -= 6;
	      accelerator += 4;
	      mods |= mod_vals[*accelerator - '1'];
	      accelerator += 2;
	    }
	  else if (len >= 5 && is_ctl (accelerator))
	    {
	      accelerator += 5;
	      len -= 5;
	      mods |= EGG_VIRTUAL_CONTROL_MASK;
	    }
	  else if (len >= 5 && is_alt (accelerator))
	    {
	      accelerator += 5;
	      len -= 5;
	      mods |= EGG_VIRTUAL_ALT_MASK;
	    }
          else if (len >= 6 && is_meta (accelerator))
	    {
	      accelerator += 6;
	      len -= 6;
	      mods |= EGG_VIRTUAL_META_MASK;
	    }
          else if (len >= 7 && is_hyper (accelerator))
	    {
	      accelerator += 7;
	      len -= 7;
	      mods |= EGG_VIRTUAL_HYPER_MASK;
	    }
          else if (len >= 7 && is_super (accelerator))
	    {
	      accelerator += 7;
	      len -= 7;
	      mods |= EGG_VIRTUAL_SUPER_MASK;
	    }
	  else
	    {
	      gchar last_ch;

	      last_ch = *accelerator;
	      while (last_ch && last_ch != '>')
		{
		  last_ch = *accelerator;
		  accelerator += 1;
		  len -= 1;
		}
	    }
	}
      else
	{
          keyval = gdk_keyval_from_name (accelerator);

          if (keyval == 0)
	    {
	      /* If keyval is 0, than maybe it's a keycode.  Check for 0x## */
	      if (len >= 4 && is_keycode (accelerator))
		{
		  char keystring[5];
		  gchar *endptr;
		  gint tmp_keycode;

		  memcpy (keystring, accelerator, 4);
		  keystring [4] = '\000';

		  tmp_keycode = strtol (keystring, &endptr, 16);

		  if (endptr == NULL || *endptr != '\000')
		    {
		      bad_keyval = TRUE;
		    }
		  else if (keycode != NULL)
		    {
		      *keycode = tmp_keycode;
		      /* 0x00 is an invalid keycode too. */
		      if (*keycode == 0)
			bad_keyval = TRUE;
		    }
		}
	    } else if (keycode != NULL)
		*keycode = XKeysymToKeycode (GDK_DISPLAY(), keyval);

          accelerator += len;
          len -= len;
	}
    }

  if (accelerator_key)
    *accelerator_key = gdk_keyval_to_lower (keyval);
  if (accelerator_mods)
    *accelerator_mods = mods;

  return !bad_keyval;
}