Move meta_ui_parse_accelerator into core/

We're currently using GTK+ for this, but we'll stop doing that fairly
quickly and instead just copy the GTK+ code in-tree.
This commit is contained in:
Jasper St. Pierre 2014-04-07 10:48:16 -04:00
parent dbf5d8f9bc
commit 0466fe9301
7 changed files with 237 additions and 176 deletions

View File

@ -78,6 +78,8 @@ libmutter_wayland_la_SOURCES = \
backends/x11/meta-monitor-manager-xrandr.c \
backends/x11/meta-monitor-manager-xrandr.h \
backends/x11/meta-xrandr-shared.h \
core/meta-accel-parse.c \
core/meta-accel-parse.h \
core/above-tab-keycode.c \
core/barrier.c \
meta/barrier.h \

View File

@ -41,6 +41,7 @@
#include "screen-private.h"
#include <meta/prefs.h>
#include "util-private.h"
#include "meta-accel-parse.h"
#include <X11/keysym.h>
#include <string.h>
@ -1284,7 +1285,7 @@ meta_display_grab_accelerator (MetaDisplay *display,
guint mask = 0;
MetaVirtualModifier modifiers = 0;
if (!meta_ui_parse_accelerator (accelerator, &keysym, &keycode, &modifiers))
if (!meta_parse_accelerator (accelerator, &keysym, &keycode, &modifiers))
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Failed to parse accelerator\n");

184
src/core/meta-accel-parse.c Normal file
View File

@ -0,0 +1,184 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2014 Red Hat
*
* 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.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#include "config.h"
#include "meta-accel-parse.h"
#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>
static void
accelerator_parse (const char *accel,
guint *keysym,
guint *keycode,
GdkModifierType *keymask)
{
const char *above_tab;
if (accel[0] == '0' && accel[1] == 'x')
{
*keysym = 0;
*keycode = (guint) strtoul (accel, NULL, 16);
*keymask = 0;
return;
}
/* The key name 'Above_Tab' is special - it's not an actual keysym name,
* but rather refers to the key above the tab key. In order to use
* the GDK parsing for modifiers in combination with it, we substitute
* it with 'Tab' temporarily before calling gtk_accelerator_parse().
*/
#define is_word_character(c) (g_ascii_isalnum(c) || ((c) == '_'))
#define ABOVE_TAB "Above_Tab"
#define ABOVE_TAB_LEN 9
above_tab = strstr (accel, ABOVE_TAB);
if (above_tab &&
(above_tab == accel || !is_word_character (above_tab[-1])) &&
!is_word_character (above_tab[ABOVE_TAB_LEN]))
{
char *before = g_strndup (accel, above_tab - accel);
char *after = g_strdup (above_tab + ABOVE_TAB_LEN);
char *replaced = g_strconcat (before, "Tab", after, NULL);
gtk_accelerator_parse (replaced, NULL, keymask);
g_free (before);
g_free (after);
g_free (replaced);
*keysym = META_KEY_ABOVE_TAB;
return;
}
#undef is_word_character
#undef ABOVE_TAB
#undef ABOVE_TAB_LEN
gtk_accelerator_parse (accel, keysym, keymask);
}
gboolean
meta_parse_accelerator (const char *accel,
unsigned int *keysym,
unsigned int *keycode,
MetaVirtualModifier *mask)
{
GdkModifierType gdk_mask = 0;
guint gdk_sym = 0;
guint gdk_code = 0;
*keysym = 0;
*keycode = 0;
*mask = 0;
if (!accel[0] || strcmp (accel, "disabled") == 0)
return TRUE;
accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask);
if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0)
return FALSE;
if (gdk_sym == None && gdk_code == 0)
return FALSE;
if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */
return FALSE;
*keysym = gdk_sym;
*keycode = gdk_code;
if (gdk_mask & GDK_SHIFT_MASK)
*mask |= META_VIRTUAL_SHIFT_MASK;
if (gdk_mask & GDK_CONTROL_MASK)
*mask |= META_VIRTUAL_CONTROL_MASK;
if (gdk_mask & GDK_MOD1_MASK)
*mask |= META_VIRTUAL_ALT_MASK;
if (gdk_mask & GDK_MOD2_MASK)
*mask |= META_VIRTUAL_MOD2_MASK;
if (gdk_mask & GDK_MOD3_MASK)
*mask |= META_VIRTUAL_MOD3_MASK;
if (gdk_mask & GDK_MOD4_MASK)
*mask |= META_VIRTUAL_MOD4_MASK;
if (gdk_mask & GDK_MOD5_MASK)
*mask |= META_VIRTUAL_MOD5_MASK;
if (gdk_mask & GDK_SUPER_MASK)
*mask |= META_VIRTUAL_SUPER_MASK;
if (gdk_mask & GDK_HYPER_MASK)
*mask |= META_VIRTUAL_HYPER_MASK;
if (gdk_mask & GDK_META_MASK)
*mask |= META_VIRTUAL_META_MASK;
return TRUE;
}
gboolean
meta_parse_modifier (const char *accel,
MetaVirtualModifier *mask)
{
GdkModifierType gdk_mask = 0;
guint gdk_sym = 0;
guint gdk_code = 0;
*mask = 0;
if (accel == NULL || !accel[0] || strcmp (accel, "disabled") == 0)
return TRUE;
accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask);
if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0)
return FALSE;
if (gdk_sym != None || gdk_code != 0)
return FALSE;
if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */
return FALSE;
if (gdk_mask & GDK_SHIFT_MASK)
*mask |= META_VIRTUAL_SHIFT_MASK;
if (gdk_mask & GDK_CONTROL_MASK)
*mask |= META_VIRTUAL_CONTROL_MASK;
if (gdk_mask & GDK_MOD1_MASK)
*mask |= META_VIRTUAL_ALT_MASK;
if (gdk_mask & GDK_MOD2_MASK)
*mask |= META_VIRTUAL_MOD2_MASK;
if (gdk_mask & GDK_MOD3_MASK)
*mask |= META_VIRTUAL_MOD3_MASK;
if (gdk_mask & GDK_MOD4_MASK)
*mask |= META_VIRTUAL_MOD4_MASK;
if (gdk_mask & GDK_MOD5_MASK)
*mask |= META_VIRTUAL_MOD5_MASK;
if (gdk_mask & GDK_SUPER_MASK)
*mask |= META_VIRTUAL_SUPER_MASK;
if (gdk_mask & GDK_HYPER_MASK)
*mask |= META_VIRTUAL_HYPER_MASK;
if (gdk_mask & GDK_META_MASK)
*mask |= META_VIRTUAL_META_MASK;
return TRUE;
}

View File

@ -0,0 +1,43 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2014 Red Hat
*
* 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.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
*/
#ifndef META_ACCEL_PARSE_H
#define META_ACCEL_PARSE_H
#include <glib.h>
#include <meta/common.h>
/* Not a real key symbol but means "key above the tab key"; this is
* used as the default keybinding for cycle_group.
* 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are
* randomly chosen */
#define META_KEY_ABOVE_TAB 0x2f7259c9
gboolean meta_parse_accelerator (const char *accel,
unsigned int *keysym,
unsigned int *keycode,
MetaVirtualModifier *mask);
gboolean meta_parse_modifier (const char *accel,
MetaVirtualModifier *mask);
#endif /* META_ACCEL_PARSE_H */

View File

@ -36,6 +36,7 @@
#include <string.h>
#include <stdlib.h>
#include "keybindings-private.h"
#include "meta-accel-parse.h"
/* If you add a key, it needs updating in init() and in the gsettings
* notify listener and of course in the .schemas file.
@ -1323,7 +1324,7 @@ mouse_button_mods_handler (GVariant *value,
*result = NULL; /* ignored */
string_value = g_variant_get_string (value, NULL);
if (!string_value || !meta_ui_parse_modifier (string_value, &mods))
if (!string_value || !meta_parse_modifier (string_value, &mods))
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Failed to parse new GSettings value\n");
@ -1627,7 +1628,7 @@ overlay_key_handler (GVariant *value,
*result = NULL; /* ignored */
string_value = g_variant_get_string (value, NULL);
if (string_value && meta_ui_parse_accelerator (string_value, &combo.keysym,
if (string_value && meta_parse_accelerator (string_value, &combo.keysym,
&combo.keycode,
&combo.modifiers))
;
@ -1887,7 +1888,7 @@ update_binding (MetaKeyPref *binding,
keycode = 0;
mods = 0;
if (!meta_ui_parse_accelerator (strokes[i], &keysym, &keycode, &mods))
if (!meta_parse_accelerator (strokes[i], &keysym, &keycode, &mods))
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Failed to parse new GSettings value\n");

View File

@ -32,11 +32,6 @@
#include <stdlib.h>
#include <cairo-xlib.h>
static void meta_ui_accelerator_parse (const char *accel,
guint *keysym,
guint *keycode,
GdkModifierType *keymask);
struct _MetaUI
{
Display *xdisplay;
@ -715,159 +710,6 @@ meta_ui_have_a_theme (void)
return meta_theme_get_current () != NULL;
}
static void
meta_ui_accelerator_parse (const char *accel,
guint *keysym,
guint *keycode,
GdkModifierType *keymask)
{
const char *above_tab;
if (accel[0] == '0' && accel[1] == 'x')
{
*keysym = 0;
*keycode = (guint) strtoul (accel, NULL, 16);
*keymask = 0;
return;
}
/* The key name 'Above_Tab' is special - it's not an actual keysym name,
* but rather refers to the key above the tab key. In order to use
* the GDK parsing for modifiers in combination with it, we substitute
* it with 'Tab' temporarily before calling gtk_accelerator_parse().
*/
#define is_word_character(c) (g_ascii_isalnum(c) || ((c) == '_'))
#define ABOVE_TAB "Above_Tab"
#define ABOVE_TAB_LEN 9
above_tab = strstr (accel, ABOVE_TAB);
if (above_tab &&
(above_tab == accel || !is_word_character (above_tab[-1])) &&
!is_word_character (above_tab[ABOVE_TAB_LEN]))
{
char *before = g_strndup (accel, above_tab - accel);
char *after = g_strdup (above_tab + ABOVE_TAB_LEN);
char *replaced = g_strconcat (before, "Tab", after, NULL);
gtk_accelerator_parse (replaced, NULL, keymask);
g_free (before);
g_free (after);
g_free (replaced);
*keysym = META_KEY_ABOVE_TAB;
return;
}
#undef is_word_character
#undef ABOVE_TAB
#undef ABOVE_TAB_LEN
gtk_accelerator_parse (accel, keysym, keymask);
}
gboolean
meta_ui_parse_accelerator (const char *accel,
unsigned int *keysym,
unsigned int *keycode,
MetaVirtualModifier *mask)
{
GdkModifierType gdk_mask = 0;
guint gdk_sym = 0;
guint gdk_code = 0;
*keysym = 0;
*keycode = 0;
*mask = 0;
if (!accel[0] || strcmp (accel, "disabled") == 0)
return TRUE;
meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask);
if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0)
return FALSE;
if (gdk_sym == None && gdk_code == 0)
return FALSE;
if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */
return FALSE;
*keysym = gdk_sym;
*keycode = gdk_code;
if (gdk_mask & GDK_SHIFT_MASK)
*mask |= META_VIRTUAL_SHIFT_MASK;
if (gdk_mask & GDK_CONTROL_MASK)
*mask |= META_VIRTUAL_CONTROL_MASK;
if (gdk_mask & GDK_MOD1_MASK)
*mask |= META_VIRTUAL_ALT_MASK;
if (gdk_mask & GDK_MOD2_MASK)
*mask |= META_VIRTUAL_MOD2_MASK;
if (gdk_mask & GDK_MOD3_MASK)
*mask |= META_VIRTUAL_MOD3_MASK;
if (gdk_mask & GDK_MOD4_MASK)
*mask |= META_VIRTUAL_MOD4_MASK;
if (gdk_mask & GDK_MOD5_MASK)
*mask |= META_VIRTUAL_MOD5_MASK;
if (gdk_mask & GDK_SUPER_MASK)
*mask |= META_VIRTUAL_SUPER_MASK;
if (gdk_mask & GDK_HYPER_MASK)
*mask |= META_VIRTUAL_HYPER_MASK;
if (gdk_mask & GDK_META_MASK)
*mask |= META_VIRTUAL_META_MASK;
return TRUE;
}
gboolean
meta_ui_parse_modifier (const char *accel,
MetaVirtualModifier *mask)
{
GdkModifierType gdk_mask = 0;
guint gdk_sym = 0;
guint gdk_code = 0;
*mask = 0;
if (accel == NULL || !accel[0] || strcmp (accel, "disabled") == 0)
return TRUE;
meta_ui_accelerator_parse (accel, &gdk_sym, &gdk_code, &gdk_mask);
if (gdk_mask == 0 && gdk_sym == 0 && gdk_code == 0)
return FALSE;
if (gdk_sym != None || gdk_code != 0)
return FALSE;
if (gdk_mask & GDK_RELEASE_MASK) /* we don't allow this */
return FALSE;
if (gdk_mask & GDK_SHIFT_MASK)
*mask |= META_VIRTUAL_SHIFT_MASK;
if (gdk_mask & GDK_CONTROL_MASK)
*mask |= META_VIRTUAL_CONTROL_MASK;
if (gdk_mask & GDK_MOD1_MASK)
*mask |= META_VIRTUAL_ALT_MASK;
if (gdk_mask & GDK_MOD2_MASK)
*mask |= META_VIRTUAL_MOD2_MASK;
if (gdk_mask & GDK_MOD3_MASK)
*mask |= META_VIRTUAL_MOD3_MASK;
if (gdk_mask & GDK_MOD4_MASK)
*mask |= META_VIRTUAL_MOD4_MASK;
if (gdk_mask & GDK_MOD5_MASK)
*mask |= META_VIRTUAL_MOD5_MASK;
if (gdk_mask & GDK_SUPER_MASK)
*mask |= META_VIRTUAL_SUPER_MASK;
if (gdk_mask & GDK_HYPER_MASK)
*mask |= META_VIRTUAL_HYPER_MASK;
if (gdk_mask & GDK_META_MASK)
*mask |= META_VIRTUAL_META_MASK;
return TRUE;
}
gboolean
meta_ui_window_is_widget (MetaUI *ui,
Window xwindow)

View File

@ -145,18 +145,6 @@ gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
void meta_ui_set_current_theme (const char *name);
gboolean meta_ui_have_a_theme (void);
/* Not a real key symbol but means "key above the tab key"; this is
* used as the default keybinding for cycle_group.
* 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are
* randomly chosen */
#define META_KEY_ABOVE_TAB 0x2f7259c9
gboolean meta_ui_parse_accelerator (const char *accel,
unsigned int *keysym,
unsigned int *keycode,
MetaVirtualModifier *mask);
gboolean meta_ui_parse_modifier (const char *accel,
MetaVirtualModifier *mask);
gboolean meta_ui_window_is_widget (MetaUI *ui,
Window xwindow);