gnome-commander r1677 - in trunk: . po src
- From: epiotr svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-commander r1677 - in trunk: . po src
- Date: Mon, 31 Mar 2008 22:42:16 +0100 (BST)
Author: epiotr
Date: Mon Mar 31 22:42:16 2008
New Revision: 1677
URL: http://svn.gnome.org/viewvc/gnome-commander?rev=1677&view=rev
Log:
Added libegg cell renderer and accelerators
Added:
trunk/src/eggaccelerators.cc
trunk/src/eggaccelerators.h
trunk/src/eggcellrendererkeys.cc
trunk/src/eggcellrendererkeys.h
Modified:
trunk/ChangeLog
trunk/po/POTFILES.in
trunk/src/Makefile.am
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Mon Mar 31 22:42:16 2008
@@ -8,6 +8,7 @@
plugins/fileroller/file-roller-plugin.c
plugins/test/test-plugin.c
src/dirlist.cc
+src/eggcellrendererkeys.cc
src/gnome-cmd-about-plugin.cc
src/gnome-cmd-advrename-dialog.cc
src/gnome-cmd-bookmark-dialog.cc
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Mon Mar 31 22:42:16 2008
@@ -17,6 +17,8 @@
cap.cc cap.h \
dict.h \
dirlist.h dirlist.cc \
+ eggaccelerators.h eggaccelerators.cc \
+ eggcellrendererkeys.h eggcellrendererkeys.cc \
filter.h filter.cc \
gnome-cmd-about-plugin.h gnome-cmd-about-plugin.cc \
gnome-cmd-advrename-dialog.h gnome-cmd-advrename-dialog.cc \
Added: trunk/src/eggaccelerators.cc
==============================================================================
--- (empty file)
+++ trunk/src/eggaccelerators.cc Mon Mar 31 22:42:16 2008
@@ -0,0 +1,610 @@
+/*
+ GNOME Commander - A GNOME based file manager
+ Copyright (C) 2001-2006 Marcus Bjurman
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/* eggaccelerators.c
+ * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
+ * Developed by Havoc Pennington, Tim Janik
+ *
+ * This file is part of gnome-terminal.
+ *
+ * Gnome-terminal 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.
+ *
+ * Gnome-terminal 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "eggaccelerators.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+
+enum
+{
+ EGG_MODMAP_ENTRY_SHIFT = 0,
+ EGG_MODMAP_ENTRY_LOCK = 1,
+ EGG_MODMAP_ENTRY_CONTROL = 2,
+ EGG_MODMAP_ENTRY_MOD1 = 3,
+ EGG_MODMAP_ENTRY_MOD2 = 4,
+ EGG_MODMAP_ENTRY_MOD3 = 5,
+ EGG_MODMAP_ENTRY_MOD4 = 6,
+ EGG_MODMAP_ENTRY_MOD5 = 7,
+ EGG_MODMAP_ENTRY_LAST = 8
+};
+
+#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
+
+typedef struct
+{
+ EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
+
+} EggModmap;
+
+
+const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
+
+
+inline gboolean is_alt (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 'a' || string[1] == 'A') &&
+ (string[2] == 'l' || string[2] == 'L') &&
+ (string[3] == 't' || string[3] == 'T') &&
+ (string[4] == '>'));
+}
+
+
+inline gboolean is_ctl (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 'c' || string[1] == 'C') &&
+ (string[2] == 't' || string[2] == 'T') &&
+ (string[3] == 'l' || string[3] == 'L') &&
+ (string[4] == '>'));
+}
+
+
+inline gboolean is_modx (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 'm' || string[1] == 'M') &&
+ (string[2] == 'o' || string[2] == 'O') &&
+ (string[3] == 'd' || string[3] == 'D') &&
+ (string[4] >= '1' && string[4] <= '5') &&
+ (string[5] == '>'));
+}
+
+
+inline gboolean is_ctrl (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 'c' || string[1] == 'C') &&
+ (string[2] == 't' || string[2] == 'T') &&
+ (string[3] == 'r' || string[3] == 'R') &&
+ (string[4] == 'l' || string[4] == 'L') &&
+ (string[5] == '>'));
+}
+
+
+inline gboolean is_shft (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 's' || string[1] == 'S') &&
+ (string[2] == 'h' || string[2] == 'H') &&
+ (string[3] == 'f' || string[3] == 'F') &&
+ (string[4] == 't' || string[4] == 'T') &&
+ (string[5] == '>'));
+}
+
+
+inline gboolean is_shift (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 's' || string[1] == 'S') &&
+ (string[2] == 'h' || string[2] == 'H') &&
+ (string[3] == 'i' || string[3] == 'I') &&
+ (string[4] == 'f' || string[4] == 'F') &&
+ (string[5] == 't' || string[5] == 'T') &&
+ (string[6] == '>'));
+}
+
+
+inline gboolean is_control (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 'c' || string[1] == 'C') &&
+ (string[2] == 'o' || string[2] == 'O') &&
+ (string[3] == 'n' || string[3] == 'N') &&
+ (string[4] == 't' || string[4] == 'T') &&
+ (string[5] == 'r' || string[5] == 'R') &&
+ (string[6] == 'o' || string[6] == 'O') &&
+ (string[7] == 'l' || string[7] == 'L') &&
+ (string[8] == '>'));
+}
+
+
+inline gboolean is_release (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 'r' || string[1] == 'R') &&
+ (string[2] == 'e' || string[2] == 'E') &&
+ (string[3] == 'l' || string[3] == 'L') &&
+ (string[4] == 'e' || string[4] == 'E') &&
+ (string[5] == 'a' || string[5] == 'A') &&
+ (string[6] == 's' || string[6] == 'S') &&
+ (string[7] == 'e' || string[7] == 'E') &&
+ (string[8] == '>'));
+}
+
+
+inline gboolean is_meta (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 'm' || string[1] == 'M') &&
+ (string[2] == 'e' || string[2] == 'E') &&
+ (string[3] == 't' || string[3] == 'T') &&
+ (string[4] == 'a' || string[4] == 'A') &&
+ (string[5] == '>'));
+}
+
+
+static inline gboolean is_super (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 's' || string[1] == 'S') &&
+ (string[2] == 'u' || string[2] == 'U') &&
+ (string[3] == 'p' || string[3] == 'P') &&
+ (string[4] == 'e' || string[4] == 'E') &&
+ (string[5] == 'r' || string[5] == 'R') &&
+ (string[6] == '>'));
+}
+
+
+inline gboolean is_hyper (const gchar *string)
+{
+ return ((string[0] == '<') &&
+ (string[1] == 'h' || string[1] == 'H') &&
+ (string[2] == 'y' || string[2] == 'Y') &&
+ (string[3] == 'p' || string[3] == 'P') &&
+ (string[4] == 'e' || string[4] == 'E') &&
+ (string[5] == 'r' || string[5] == 'R') &&
+ (string[6] == '>'));
+}
+
+
+/**
+ * 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)
+{
+ g_return_val_if_fail (accelerator != NULL, FALSE);
+
+ if (accelerator_key)
+ *accelerator_key = 0;
+
+ if (accelerator_mods)
+ *accelerator_mods = (EggVirtualModifierType) 0;
+
+ gboolean bad_keyval = FALSE;
+
+ guint keyval = 0;
+ guint mods = 0;
+ gint 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)
+ bad_keyval = TRUE;
+
+ accelerator += len;
+ len -= len;
+ }
+ }
+
+ if (accelerator_key)
+ *accelerator_key = gdk_keyval_to_lower (keyval);
+
+ if (accelerator_mods)
+ *accelerator_mods = (EggVirtualModifierType) mods;
+
+ return !bad_keyval;
+}
+
+
+/**
+ * egg_virtual_accelerator_name:
+ * @accelerator_key: accelerator keyval
+ * @accelerator_mods: accelerator modifier mask
+ * @returns: a newly-allocated accelerator name
+ *
+ * Converts an accelerator keyval and modifier mask
+ * into a string parseable by egg_accelerator_parse_virtual().
+ * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
+ * this function returns "<Control>q".
+ *
+ * The caller of this function must free the returned string.
+ */
+gchar *egg_virtual_accelerator_name (guint accelerator_key, EggVirtualModifierType accelerator_mods)
+{
+ static const gchar text_release[] = "<Release>";
+ static const gchar text_shift[] = "<Shift>";
+ static const gchar text_control[] = "<Control>";
+ static const gchar text_mod1[] = "<Alt>";
+ static const gchar text_mod2[] = "<Mod2>";
+ static const gchar text_mod3[] = "<Mod3>";
+ static const gchar text_mod4[] = "<Mod4>";
+ static const gchar text_mod5[] = "<Mod5>";
+ static const gchar text_meta[] = "<Meta>";
+ static const gchar text_super[] = "<Super>";
+ static const gchar text_hyper[] = "<Hyper>";
+
+ (guint &) accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
+
+ gchar *keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
+ if (!keyval_name)
+ keyval_name = "";
+
+ guint l = 0;
+
+ if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+ l += sizeof (text_release)-1;
+ if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+ l += sizeof (text_shift)-1;
+ if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+ l += sizeof (text_control)-1;
+ if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+ l += sizeof (text_mod1)-1;
+ if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+ l += sizeof (text_mod2)-1;
+ if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+ l += sizeof (text_mod3)-1;
+ if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+ l += sizeof (text_mod4)-1;
+ if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+ l += sizeof (text_mod5)-1;
+ if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+ l += sizeof (text_meta)-1;
+ if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+ l += sizeof (text_hyper)-1;
+ if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+ l += sizeof (text_super)-1;
+
+ l += strlen (keyval_name);
+
+ gchar *accelerator = g_new (gchar, l+1);
+
+ l = 0;
+ accelerator[l] = 0;
+
+ if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
+ {
+ strcpy (accelerator + l, text_release);
+ l += sizeof (text_release) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
+ {
+ strcpy (accelerator + l, text_shift);
+ l += sizeof (text_shift) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
+ {
+ strcpy (accelerator + l, text_control);
+ l += sizeof (text_control) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
+ {
+ strcpy (accelerator + l, text_mod1);
+ l += sizeof (text_mod1) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
+ {
+ strcpy (accelerator + l, text_mod2);
+ l += sizeof (text_mod2) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
+ {
+ strcpy (accelerator + l, text_mod3);
+ l += sizeof (text_mod3) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
+ {
+ strcpy (accelerator + l, text_mod4);
+ l += sizeof (text_mod4) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
+ {
+ strcpy (accelerator + l, text_mod5);
+ l += sizeof (text_mod5) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_META_MASK)
+ {
+ strcpy (accelerator + l, text_meta);
+ l += sizeof (text_meta) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
+ {
+ strcpy (accelerator + l, text_hyper);
+ l += sizeof (text_hyper) - 1;
+ }
+ if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
+ {
+ strcpy (accelerator + l, text_super);
+ l += sizeof (text_super) - 1;
+ }
+
+ strcpy (accelerator + l, keyval_name);
+
+ return accelerator;
+}
+
+
+void egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, EggVirtualModifierType virtual_mods, GdkModifierType *concrete_mods)
+{
+ g_return_if_fail (GDK_IS_KEYMAP (keymap));
+ g_return_if_fail (concrete_mods != NULL);
+
+ guint concrete = 0;
+ const EggModmap *modmap = egg_keymap_get_modmap (keymap);
+
+ // Not so sure about this algorithm
+
+ for (gint i = 0; i<EGG_MODMAP_ENTRY_LAST; ++i)
+ if (modmap->mapping[i] & virtual_mods)
+ concrete |= (1 << i);
+
+ *concrete_mods = (GdkModifierType) concrete;
+}
+
+
+void egg_keymap_virtualize_modifiers (GdkKeymap *keymap, GdkModifierType concrete_mods, EggVirtualModifierType *virtual_mods)
+{
+ g_return_if_fail (GDK_IS_KEYMAP (keymap));
+ g_return_if_fail (virtual_mods != NULL);
+
+ const EggModmap *modmap = egg_keymap_get_modmap (keymap);
+
+ guint virtual_mod = 0;
+
+ // Not so sure about this algorithm
+
+ for (int i=0; i < EGG_MODMAP_ENTRY_LAST; ++i)
+ if ((1 << i) & concrete_mods)
+ {
+ guint cleaned;
+
+ cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
+ EGG_VIRTUAL_MOD3_MASK |
+ EGG_VIRTUAL_MOD4_MASK |
+ EGG_VIRTUAL_MOD5_MASK);
+ if (cleaned != 0)
+ virtual_mod |= cleaned;
+ else
+ virtual_mod |= modmap->mapping[i]; // Rather than dropping mod2->mod5 if not bound, go ahead and use the concrete names
+ }
+
+ *virtual_mods = (EggVirtualModifierType) virtual_mod;
+}
+
+
+inline void reload_modmap (GdkKeymap *keymap, EggModmap *modmap)
+{
+ /* FIXME multihead */
+ XModifierKeymap *xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
+
+ memset (modmap->mapping, 0, sizeof (modmap->mapping));
+
+ // there are 8 modifiers, and the first 3 are shift, shift lock and control
+ int map_size = 8 * xmodmap->max_keypermod;
+ int i = 3 * xmodmap->max_keypermod;
+
+ while (i < map_size)
+ {
+ /* get the key code at this point in the map,
+ * see if its keysym is one we're interested in
+ */
+ int keycode = xmodmap->modifiermap[i];
+
+ GdkKeymapKey *keys = NULL;
+ guint *keyvals = NULL;
+ int n_entries = 0;
+
+ gdk_keymap_get_entries_for_keycode (keymap, keycode, &keys, &keyvals, &n_entries);
+
+ guint mask = (EggVirtualModifierType) 0; // EggVirtualModifierType
+
+ for (gint j=0; j<n_entries; ++j)
+ if (keyvals[j] == GDK_Num_Lock)
+ mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
+ else if (keyvals[j] == GDK_Scroll_Lock)
+ mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
+ else if (keyvals[j] == GDK_Meta_L || keyvals[j] == GDK_Meta_R)
+ mask |= EGG_VIRTUAL_META_MASK;
+ else if (keyvals[j] == GDK_Hyper_L || keyvals[j] == GDK_Hyper_R)
+ mask |= EGG_VIRTUAL_HYPER_MASK;
+ else if (keyvals[j] == GDK_Super_L || keyvals[j] == GDK_Super_R)
+ mask |= EGG_VIRTUAL_SUPER_MASK;
+ else if (keyvals[j] == GDK_Mode_switch)
+ mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
+
+ // Mod1Mask is 1 << 3 for example, i.e. the fourth modifier, i / keyspermod is the modifier index
+
+ (guint &) modmap->mapping[i/xmodmap->max_keypermod] |= mask;
+
+ g_free (keyvals);
+ g_free (keys);
+
+ ++i;
+ }
+
+ /* Add in the not-really-virtual fixed entries */
+ (guint &) modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
+ (guint &) modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
+ (guint &) modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
+ (guint &) modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
+ (guint &) modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
+ (guint &) modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
+ (guint &) modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
+ (guint &) modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
+
+ XFreeModifiermap (xmodmap);
+}
+
+
+const EggModmap *egg_keymap_get_modmap (GdkKeymap *keymap)
+{
+ //This is all a hack, much simpler when we can just modify GDK directly.
+
+ EggModmap *modmap = (EggModmap *) g_object_get_data (G_OBJECT (keymap), "egg-modmap");
+
+ if (!modmap)
+ {
+ modmap = g_new0 (EggModmap, 1);
+
+ // FIXME modify keymap change events with an event filter and force a reload if we get one
+
+ reload_modmap (keymap, modmap);
+
+ g_object_set_data_full (G_OBJECT (keymap), "egg-modmap", modmap, g_free);
+ }
+
+ g_assert (modmap != NULL);
+
+ return modmap;
+}
Added: trunk/src/eggaccelerators.h
==============================================================================
--- (empty file)
+++ trunk/src/eggaccelerators.h Mon Mar 31 22:42:16 2008
@@ -0,0 +1,92 @@
+/*
+ GNOME Commander - A GNOME based file manager
+ Copyright (C) 2001-2006 Marcus Bjurman
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/* eggaccelerators.h
+ * Copyright (C) 2002 Red Hat, Inc.
+ * Developed by Havoc Pennington
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EGG_ACCELERATORS_H__
+#define __EGG_ACCELERATORS_H__
+
+#include <gtk/gtkaccelgroup.h>
+#include <gdk/gdk.h>
+
+// Where a value is also in GdkModifierType we coincide, otherwise we don't overlap.
+typedef enum
+{
+ EGG_VIRTUAL_SHIFT_MASK = 1 << 0,
+ EGG_VIRTUAL_LOCK_MASK = 1 << 1,
+ EGG_VIRTUAL_CONTROL_MASK = 1 << 2,
+
+ EGG_VIRTUAL_ALT_MASK = 1 << 3, // fixed as MOD1
+
+ EGG_VIRTUAL_MOD2_MASK = 1 << 4,
+ EGG_VIRTUAL_MOD3_MASK = 1 << 5,
+ EGG_VIRTUAL_MOD4_MASK = 1 << 6,
+ EGG_VIRTUAL_MOD5_MASK = 1 << 7,
+
+#if 0
+ GDK_BUTTON1_MASK = 1 << 8,
+ GDK_BUTTON2_MASK = 1 << 9,
+ GDK_BUTTON3_MASK = 1 << 10,
+ GDK_BUTTON4_MASK = 1 << 11,
+ GDK_BUTTON5_MASK = 1 << 12,
+ /* 13, 14 are used by Xkb for the keyboard group */
+#endif
+
+ EGG_VIRTUAL_META_MASK = 1 << 24,
+ EGG_VIRTUAL_SUPER_MASK = 1 << 25,
+ EGG_VIRTUAL_HYPER_MASK = 1 << 26,
+ EGG_VIRTUAL_MODE_SWITCH_MASK = 1 << 27,
+ EGG_VIRTUAL_NUM_LOCK_MASK = 1 << 28,
+ EGG_VIRTUAL_SCROLL_LOCK_MASK = 1 << 29,
+
+ /* Also in GdkModifierType */
+ EGG_VIRTUAL_RELEASE_MASK = 1 << 30,
+
+ // 28-31 24-27 20-23 16-19 12-15 8-11 4-7 0-3
+ // 7 f 0 0 0 0 f f
+
+ EGG_VIRTUAL_MODIFIER_MASK = 0x7f0000ff
+
+} EggVirtualModifierType;
+
+gboolean egg_accelerator_parse_virtual (const gchar *accelerator, guint *accelerator_key, EggVirtualModifierType *accelerator_mods);
+void egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, EggVirtualModifierType virtual_mods, GdkModifierType *concrete_mods);
+void egg_keymap_virtualize_modifiers (GdkKeymap *keymap, GdkModifierType concrete_mods, EggVirtualModifierType *virtual_mods);
+
+gchar *egg_virtual_accelerator_name (guint accelerator_key, EggVirtualModifierType accelerator_mods);
+
+#endif // __EGG_ACCELERATORS_H__
Added: trunk/src/eggcellrendererkeys.cc
==============================================================================
--- (empty file)
+++ trunk/src/eggcellrendererkeys.cc Mon Mar 31 22:42:16 2008
@@ -0,0 +1,605 @@
+/*
+ GNOME Commander - A GNOME based file manager
+ Copyright (C) 2001-2006 Marcus Bjurman
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/*
+ * This file is part of gnome-terminal.
+ *
+ * Gnome-terminal 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.
+ *
+ * Gnome-terminal 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <libintl.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
+#include "eggcellrendererkeys.h"
+#include "eggaccelerators.h"
+#include "gnome-cmd-includes.h"
+
+#define EGG_CELL_RENDERER_TEXT_PATH "egg-cell-renderer-text"
+
+static void egg_cell_renderer_keys_finalize (GObject *object);
+static void egg_cell_renderer_keys_init (EggCellRendererKeys *cell_keys);
+static void egg_cell_renderer_keys_class_init (EggCellRendererKeysClass *cell_keys_class);
+static GtkCellEditable *egg_cell_renderer_keys_start_editing (GtkCellRenderer *cell,
+ GdkEvent *event,
+ GtkWidget *widget,
+ const gchar *path,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GtkCellRendererState flags);
+
+
+static void egg_cell_renderer_keys_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void egg_cell_renderer_keys_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void egg_cell_renderer_keys_get_size (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ GdkRectangle *cell_area,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height);
+
+
+enum
+{
+ PROP_0,
+
+ PROP_ACCEL_KEY,
+ PROP_ACCEL_MASK,
+ PROP_ACCEL_MODE
+};
+
+static GtkCellRendererTextClass *parent_class = NULL;
+
+
+GType egg_cell_renderer_keys_get_type (void)
+{
+ static GType cell_keys_type = 0;
+
+ if (!cell_keys_type)
+ {
+ static const GTypeInfo cell_keys_info =
+ {
+ sizeof (EggCellRendererKeysClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc)egg_cell_renderer_keys_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EggCellRendererKeys),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) egg_cell_renderer_keys_init
+ };
+
+ cell_keys_type = g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT, "EggCellRendererKeys", &cell_keys_info, GTypeFlags(0));
+ }
+
+ return cell_keys_type;
+}
+
+
+static void egg_cell_renderer_keys_init (EggCellRendererKeys *cell_keys)
+{
+ cell_keys->accel_mode = EGG_CELL_RENDERER_KEYS_MODE_GTK;
+}
+
+/* FIXME setup stuff to generate this */
+/* VOID:STRING,UINT,FLAGS,UINT */
+static void
+marshal_VOID__STRING_UINT_FLAGS_UINT (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ g_return_if_fail (n_param_values == 5);
+
+ typedef void (*GMarshalFunc_VOID__STRING_UINT_FLAGS_UINT) (gpointer data1,
+ const char *arg_1,
+ guint arg_2,
+ int arg_3,
+ guint arg_4,
+ gpointer data2);
+ register GMarshalFunc_VOID__STRING_UINT_FLAGS_UINT callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+
+ callback = (GMarshalFunc_VOID__STRING_UINT_FLAGS_UINT) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_value_get_string (param_values + 1),
+ g_value_get_uint (param_values + 2),
+ g_value_get_flags (param_values + 3),
+ g_value_get_uint (param_values + 4),
+ data2);
+}
+
+
+static void egg_cell_renderer_keys_class_init (EggCellRendererKeysClass *cell_keys_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (cell_keys_class);
+ GtkCellRendererClass *cell_renderer_class = GTK_CELL_RENDERER_CLASS (cell_keys_class);
+
+ parent_class = (GtkCellRendererTextClass *) g_type_class_peek_parent (object_class);
+
+ GTK_CELL_RENDERER_CLASS (cell_keys_class)->start_editing = egg_cell_renderer_keys_start_editing;
+
+ object_class->get_property = egg_cell_renderer_keys_get_property;
+ object_class->set_property = egg_cell_renderer_keys_set_property;
+ cell_renderer_class->get_size = egg_cell_renderer_keys_get_size;
+
+ object_class->finalize = egg_cell_renderer_keys_finalize;
+
+ // FIXME if this gets moved to a real library, rename the properties to match whatever the GTK convention is
+
+ g_object_class_install_property (object_class,
+ PROP_ACCEL_KEY,
+ g_param_spec_uint ("accel_key",
+ _("Accelerator key"),
+ _("Accelerator key"),
+ 0,
+ G_MAXINT,
+ 0,
+ GParamFlags(G_PARAM_READABLE | G_PARAM_WRITABLE)));
+
+ g_object_class_install_property (object_class,
+ PROP_ACCEL_MASK,
+ g_param_spec_flags ("accel_mask",
+ _("Accelerator modifiers"),
+ _("Accelerator modifiers"),
+ GDK_TYPE_MODIFIER_TYPE,
+ 0,
+ GParamFlags(G_PARAM_READABLE | G_PARAM_WRITABLE)));
+
+ /* FIXME: Register the enum when moving to GTK+ */
+ g_object_class_install_property (object_class,
+ PROP_ACCEL_MODE,
+ g_param_spec_int ("accel_mode",
+ _("Accelerator Mode"),
+ _("The type of accelerator."),
+ 0,
+ 2,
+ 0,
+ GParamFlags(G_PARAM_READABLE | G_PARAM_WRITABLE)));
+
+ g_signal_new ("keys_edited",
+ EGG_TYPE_CELL_RENDERER_KEYS,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggCellRendererKeysClass, keys_edited),
+ NULL, NULL,
+ marshal_VOID__STRING_UINT_FLAGS_UINT,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING,
+ G_TYPE_UINT,
+ GDK_TYPE_MODIFIER_TYPE,
+ G_TYPE_UINT);
+}
+
+
+GtkCellRenderer *egg_cell_renderer_keys_new (void)
+{
+ return GTK_CELL_RENDERER (g_object_new (EGG_TYPE_CELL_RENDERER_KEYS, NULL));
+}
+
+
+static void egg_cell_renderer_keys_finalize (GObject *object)
+{
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+static gchar *convert_keysym_state_to_string (guint keysym, EggVirtualModifierType mask)
+{
+ return keysym == 0 ? g_strdup (_("Disabled")) : egg_virtual_accelerator_name (keysym, mask);
+}
+
+
+static void egg_cell_renderer_keys_get_property (GObject *object, guint param_id, GValue *value, GParamSpec *pspec)
+{
+ g_return_if_fail (EGG_IS_CELL_RENDERER_KEYS (object));
+
+ EggCellRendererKeys *keys = EGG_CELL_RENDERER_KEYS (object);
+
+ switch (param_id)
+ {
+ case PROP_ACCEL_KEY:
+ g_value_set_uint (value, keys->accel_key);
+ break;
+
+ case PROP_ACCEL_MASK:
+ g_value_set_flags (value, keys->accel_mask);
+ break;
+
+ case PROP_ACCEL_MODE:
+ g_value_set_int (value, keys->accel_mode);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ }
+}
+
+
+static void egg_cell_renderer_keys_set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
+{
+ g_return_if_fail (EGG_IS_CELL_RENDERER_KEYS (object));
+
+ EggCellRendererKeys *keys = EGG_CELL_RENDERER_KEYS (object);
+
+ switch (param_id)
+ {
+ case PROP_ACCEL_KEY:
+ egg_cell_renderer_keys_set_accelerator (keys, g_value_get_uint (value), keys->accel_mask);
+ break;
+
+ case PROP_ACCEL_MASK:
+ egg_cell_renderer_keys_set_accelerator (keys, keys->accel_key, (EggVirtualModifierType) g_value_get_flags (value));
+ break;
+
+ case PROP_ACCEL_MODE:
+ egg_cell_renderer_keys_set_accel_mode (keys, (EggCellRendererKeysMode) g_value_get_int (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ }
+}
+
+
+inline gboolean is_modifier (guint keycode)
+{
+ gboolean retval = FALSE;
+
+ XModifierKeymap *mod_keymap = XGetModifierMapping (gdk_display);
+
+ gint map_size = 8 * mod_keymap->max_keypermod;
+
+ for (gint i=0; i<map_size; ++i)
+ if (keycode == mod_keymap->modifiermap[i])
+ {
+ retval = TRUE;
+ break;
+ }
+
+ XFreeModifiermap (mod_keymap);
+
+ return retval;
+}
+
+
+void egg_cell_renderer_keys_get_size (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ GdkRectangle *cell_area,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height)
+{
+ EggCellRendererKeys *keys = (EggCellRendererKeys *) cell;
+ GtkRequisition requisition;
+
+ if (keys->sizing_label == NULL)
+ keys->sizing_label = gtk_label_new (_("Type a new accelerator, or press Backspace to clear"));
+
+ gtk_widget_size_request (keys->sizing_label, &requisition);
+ (* GTK_CELL_RENDERER_CLASS (parent_class)->get_size) (cell, widget, cell_area, x_offset, y_offset, width, height);
+
+ /* FIXME: need to take the cell_area et al. into account */
+ if (width)
+ *width = MAX (*width, requisition.width);
+ if (height)
+ *height = MAX (*height, requisition.height);
+}
+
+
+// FIXME: Currently we don't differentiate between a 'bogus' key (like tab in GTK mode) and a removed key.
+static gboolean grab_key_callback (GtkWidget *widget, GdkEventKey *event, void *data)
+{
+ char *path;
+ guint upper;
+ GdkModifierType ignored_modifiers;
+
+ EggCellRendererKeys *keys = EGG_CELL_RENDERER_KEYS (data);
+ guint accel_mods = 0;
+
+ if (is_modifier (event->hardware_keycode))
+ return TRUE;
+
+ gboolean edited = FALSE;
+ guint consumed_modifiers = 0;
+
+ gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
+ event->hardware_keycode,
+ (GdkModifierType) event->state,
+ event->group,
+ NULL, NULL, NULL, (GdkModifierType *) &consumed_modifiers);
+
+ upper = event->keyval;
+ guint accel_keyval = gdk_keyval_to_lower (upper);
+ if (accel_keyval == GDK_ISO_Left_Tab)
+ accel_keyval = GDK_Tab;
+
+
+
+ // Put shift back if it changed the case of the key, not otherwise.
+ if (upper != accel_keyval && (consumed_modifiers & GDK_SHIFT_MASK))
+ consumed_modifiers &= ~(GDK_SHIFT_MASK);
+
+ egg_keymap_resolve_virtual_modifiers (gdk_keymap_get_default (),
+ EggVirtualModifierType (EGG_VIRTUAL_NUM_LOCK_MASK | EGG_VIRTUAL_SCROLL_LOCK_MASK),
+ &ignored_modifiers);
+
+ /* filter consumed/ignored modifiers */
+
+ if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_GTK)
+ accel_mods = event->state & ~(consumed_modifiers | ignored_modifiers);
+ else if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_X)
+ accel_mods = event->state & ~(ignored_modifiers);
+ else
+ g_assert_not_reached ();
+
+ if (accel_mods == 0 && accel_keyval == GDK_Escape)
+ goto out; /* cancel */
+
+ /* clear the accelerator on Backspace */
+ if (keys->edit_key!=0 && accel_mods==0 && accel_keyval==GDK_BackSpace)
+ accel_keyval = 0;
+
+ if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_GTK)
+ {
+ if (!gtk_accelerator_valid (accel_keyval, (GdkModifierType) accel_mods))
+ {
+ accel_keyval = 0;
+ accel_mods = 0;
+ }
+
+ /* Remove modifiers like super and hyper, as GTK+ ignores them. */
+ accel_mods &= GDK_MODIFIER_MASK;
+ }
+
+ edited = TRUE;
+
+ out:
+ path = g_strdup ((gchar *) g_object_get_data (G_OBJECT (keys->edit_widget), EGG_CELL_RENDERER_TEXT_PATH));
+
+ gdk_keyboard_ungrab (event->time);
+ gdk_pointer_ungrab (event->time);
+
+ gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (keys->edit_widget));
+ gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (keys->edit_widget));
+ keys->edit_widget = NULL;
+ keys->grab_widget = NULL;
+
+ if (edited)
+ g_signal_emit_by_name (G_OBJECT (keys), "keys_edited", path, accel_keyval, accel_mods, event->hardware_keycode);
+
+ g_free (path);
+
+ return TRUE;
+}
+
+
+static void ungrab_stuff (GtkWidget *widget, gpointer data)
+{
+ EggCellRendererKeys *keys = EGG_CELL_RENDERER_KEYS (data);
+
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+ gdk_pointer_ungrab (GDK_CURRENT_TIME);
+
+ g_signal_handlers_disconnect_by_func (G_OBJECT (keys->grab_widget), (gpointer) G_CALLBACK (grab_key_callback), data);
+}
+
+
+static void pointless_eventbox_start_editing (GtkCellEditable *cell_editable, GdkEvent *event)
+{
+ /* do nothing, because we are pointless */
+}
+
+
+static void pointless_eventbox_cell_editable_init (GtkCellEditableIface *iface)
+{
+ iface->start_editing = pointless_eventbox_start_editing;
+}
+
+
+static GType pointless_eventbox_subclass_get_type (void)
+{
+ static GType eventbox_type = 0;
+
+ if (!eventbox_type)
+ {
+ static const GTypeInfo eventbox_info =
+ {
+ sizeof (GtkEventBoxClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkEventBox),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ static const GInterfaceInfo cell_editable_info = { (GInterfaceInitFunc) pointless_eventbox_cell_editable_init, NULL, NULL };
+
+ eventbox_type = g_type_register_static (GTK_TYPE_EVENT_BOX, "EggCellEditableEventBox", &eventbox_info, GTypeFlags(0));
+
+ g_type_add_interface_static (eventbox_type,
+ GTK_TYPE_CELL_EDITABLE,
+ &cell_editable_info);
+ }
+
+ return eventbox_type;
+}
+
+
+static GtkCellEditable *
+egg_cell_renderer_keys_start_editing (GtkCellRenderer *cell,
+ GdkEvent *event,
+ GtkWidget *widget,
+ const gchar *path,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GtkCellRendererState flags)
+{
+ g_return_val_if_fail (widget->window != NULL, NULL);
+
+ GtkWidget *label;
+ GtkWidget *eventbox;
+
+ GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (cell);
+ EggCellRendererKeys *keys = EGG_CELL_RENDERER_KEYS (cell);
+
+ // If the cell isn't editable we return NULL
+ if (celltext->editable == FALSE)
+ return NULL;
+
+ if (gdk_keyboard_grab (widget->window, FALSE, gdk_event_get_time (event)) != GDK_GRAB_SUCCESS)
+ return NULL;
+
+ if (gdk_pointer_grab (widget->window, FALSE,
+ GDK_BUTTON_PRESS_MASK,
+ NULL, NULL,
+ gdk_event_get_time (event)) != GDK_GRAB_SUCCESS)
+ {
+ gdk_keyboard_ungrab (gdk_event_get_time (event));
+ return NULL;
+ }
+
+ keys->grab_widget = widget;
+
+ g_signal_connect (G_OBJECT (widget), "key_press_event", G_CALLBACK (grab_key_callback), keys);
+
+ eventbox = (GtkWidget *) g_object_new (pointless_eventbox_subclass_get_type (), NULL);
+ keys->edit_widget = eventbox;
+ g_object_add_weak_pointer (G_OBJECT (keys->edit_widget), (void**) &keys->edit_widget);
+
+ label = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL, &widget->style->bg[GTK_STATE_SELECTED]);
+
+ gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &widget->style->fg[GTK_STATE_SELECTED]);
+
+ if (keys->accel_key != 0)
+ gtk_label_set_text (GTK_LABEL (label), _("Type a new accelerator, or press Backspace to clear"));
+ else
+ gtk_label_set_text (GTK_LABEL (label), _("Type a new accelerator"));
+
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+
+ g_object_set_data_full (G_OBJECT (keys->edit_widget), EGG_CELL_RENDERER_TEXT_PATH, g_strdup (path), g_free);
+
+ gtk_widget_show_all (keys->edit_widget);
+
+ g_signal_connect (G_OBJECT (keys->edit_widget), "unrealize", G_CALLBACK (ungrab_stuff), keys);
+
+ keys->edit_key = keys->accel_key;
+
+ return GTK_CELL_EDITABLE (keys->edit_widget);
+}
+
+
+void egg_cell_renderer_keys_set_accelerator (EggCellRendererKeys *keys, guint keyval, EggVirtualModifierType mask)
+{
+ g_return_if_fail (EGG_IS_CELL_RENDERER_KEYS (keys));
+
+ g_object_freeze_notify (G_OBJECT (keys));
+
+ gboolean changed = FALSE;
+
+ if (keyval != keys->accel_key)
+ {
+ keys->accel_key = keyval;
+ g_object_notify (G_OBJECT (keys), "accel_key");
+ changed = TRUE;
+ }
+
+ if (mask != keys->accel_mask)
+ {
+ keys->accel_mask = mask;
+
+ g_object_notify (G_OBJECT (keys), "accel_mask");
+ changed = TRUE;
+ }
+
+ g_object_thaw_notify (G_OBJECT (keys));
+
+ if (changed)
+ {
+ /* sync string to the key values */
+ GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (keys);
+ char *text = convert_keysym_state_to_string (keys->accel_key, keys->accel_mask);
+ g_object_set (keys, "text", text, NULL);
+ g_free (text);
+ }
+
+}
+
+
+void egg_cell_renderer_keys_get_accelerator (EggCellRendererKeys *keys, guint *keyval, EggVirtualModifierType *mask)
+{
+ g_return_if_fail (EGG_IS_CELL_RENDERER_KEYS (keys));
+
+ if (keyval)
+ *keyval = keys->accel_key;
+
+ if (mask)
+ *mask = keys->accel_mask;
+}
+
+
+void egg_cell_renderer_keys_set_accel_mode (EggCellRendererKeys *keys, EggCellRendererKeysMode accel_mode)
+{
+ g_return_if_fail (EGG_IS_CELL_RENDERER_KEYS (keys));
+
+ keys->accel_mode = accel_mode;
+ g_object_notify (G_OBJECT (keys), "accel_mode");
+}
Added: trunk/src/eggcellrendererkeys.h
==============================================================================
--- (empty file)
+++ trunk/src/eggcellrendererkeys.h Mon Mar 31 22:42:16 2008
@@ -0,0 +1,93 @@
+/*
+ GNOME Commander - A GNOME based file manager
+ Copyright (C) 2001-2006 Marcus Bjurman
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/* gtkcellrendererkeybinding.h
+ * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb redhat com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EGG_CELL_RENDERER_KEYS_H__
+#define __EGG_CELL_RENDERER_KEYS_H__
+
+#include <gtk/gtkcellrenderertext.h>
+#include "eggaccelerators.h"
+
+#define EGG_TYPE_CELL_RENDERER_KEYS (egg_cell_renderer_keys_get_type ())
+#define EGG_CELL_RENDERER_KEYS(obj) (GTK_CHECK_CAST ((obj), EGG_TYPE_CELL_RENDERER_KEYS, EggCellRendererKeys))
+#define EGG_CELL_RENDERER_KEYS_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EGG_TYPE_CELL_RENDERER_KEYS, EggCellRendererKeysClass))
+#define EGG_IS_CELL_RENDERER_KEYS(obj) (GTK_CHECK_TYPE ((obj), EGG_TYPE_CELL_RENDERER_KEYS))
+#define EGG_IS_CELL_RENDERER_KEYS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), EGG_TYPE_CELL_RENDERER_KEYS))
+#define EGG_CELL_RENDERER_KEYS_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), EGG_TYPE_CELL_RENDERER_KEYS, EggCellRendererKeysClass))
+
+typedef struct _EggCellRendererKeys EggCellRendererKeys;
+typedef struct _EggCellRendererKeysClass EggCellRendererKeysClass;
+
+
+typedef enum
+{
+ EGG_CELL_RENDERER_KEYS_MODE_GTK,
+ EGG_CELL_RENDERER_KEYS_MODE_X,
+} EggCellRendererKeysMode;
+
+
+struct _EggCellRendererKeys
+{
+ GtkCellRendererText parent;
+ guint accel_key;
+ EggVirtualModifierType accel_mask;
+ GtkWidget *edit_widget;
+ GtkWidget *grab_widget;
+ guint edit_key;
+ GtkWidget *sizing_label;
+ EggCellRendererKeysMode accel_mode;
+};
+
+struct _EggCellRendererKeysClass
+{
+ GtkCellRendererTextClass parent_class;
+
+ void (* keys_edited) (EggCellRendererKeys *keys,
+ const char *path_string,
+ guint keyval,
+ EggVirtualModifierType mask,
+ guint hardware_keycode);
+};
+
+GType egg_cell_renderer_keys_get_type (void);
+GtkCellRenderer *egg_cell_renderer_keys_new (void);
+
+void egg_cell_renderer_keys_set_accelerator (EggCellRendererKeys *keys, guint keyval, EggVirtualModifierType mask);
+void egg_cell_renderer_keys_get_accelerator (EggCellRendererKeys *keys, guint *keyval, EggVirtualModifierType *mask);
+void egg_cell_renderer_keys_set_accel_mode (EggCellRendererKeys *keys, EggCellRendererKeysMode accel_mode);
+
+#endif // __GTK_CELL_RENDERER_KEYS_H__
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]