Add support for extra virtual modifiers: (#85780, Owen Taylor)

2005-09-06  Matthias Clasen  <mclasen@redhat.com>

	Add support for extra virtual modifiers:  (#85780, Owen Taylor)

	* gdk/x11/gdkkeys-x11.c (struct _GdkKeymapX11): Add a
	modmap to maintain the information which X modifiers map to
	virtual modifiers.
	(get_xkb): Set up the modmap from the XKB tables.
	(update_keymaps): Set up the modmap from the information returned
	by XGetModifierMapping in the non-XKB case.

	* gdk/x11/gdkprivate-x11.h:
	* gdk/x11/gdkkeys-x11.c (_gdk_keymap_add_virtual_modifiers): New
	function to set the virtual modifiers in the state.

	* gdk/x11/gdkevents-x11.c (translate_key_event): Call
	_gdk_keymap_add_virtual_modifiers here.

	* gdk/gdktypes.h (GdkModifierType): Add bits for virtual Super,
	Hyper and Meta modifiers. Also add GDK_ALT_MASK as an alias
	for GDK_MOD1_MASK.
This commit is contained in:
Matthias Clasen 2005-09-06 17:56:01 +00:00 committed by Matthias Clasen
parent 5e93e9da16
commit 543ce67477
6 changed files with 147 additions and 9 deletions

View File

@ -1,3 +1,25 @@
2005-09-06 Matthias Clasen <mclasen@redhat.com>
Add support for extra virtual modifiers: (#85780, Owen Taylor)
* gdk/x11/gdkkeys-x11.c (struct _GdkKeymapX11): Add a
modmap to maintain the information which X modifiers map to
virtual modifiers.
(get_xkb): Set up the modmap from the XKB tables.
(update_keymaps): Set up the modmap from the information returned
by XGetModifierMapping in the non-XKB case.
* gdk/x11/gdkprivate-x11.h:
* gdk/x11/gdkkeys-x11.c (_gdk_keymap_add_virtual_modifiers): New
function to set the virtual modifiers in the state.
* gdk/x11/gdkevents-x11.c (translate_key_event): Call
_gdk_keymap_add_virtual_modifiers here.
* gdk/gdktypes.h (GdkModifierType): Add bits for virtual Super,
Hyper and Meta modifiers. Also add GDK_ALT_MASK as an alias
for GDK_MOD1_MASK.
2005-09-05 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkaction.c (connect_proxy): Set the label of a button

View File

@ -1,3 +1,25 @@
2005-09-06 Matthias Clasen <mclasen@redhat.com>
Add support for extra virtual modifiers: (#85780, Owen Taylor)
* gdk/x11/gdkkeys-x11.c (struct _GdkKeymapX11): Add a
modmap to maintain the information which X modifiers map to
virtual modifiers.
(get_xkb): Set up the modmap from the XKB tables.
(update_keymaps): Set up the modmap from the information returned
by XGetModifierMapping in the non-XKB case.
* gdk/x11/gdkprivate-x11.h:
* gdk/x11/gdkkeys-x11.c (_gdk_keymap_add_virtual_modifiers): New
function to set the virtual modifiers in the state.
* gdk/x11/gdkevents-x11.c (translate_key_event): Call
_gdk_keymap_add_virtual_modifiers here.
* gdk/gdktypes.h (GdkModifierType): Add bits for virtual Super,
Hyper and Meta modifiers. Also add GDK_ALT_MASK as an alias
for GDK_MOD1_MASK.
2005-09-05 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkaction.c (connect_proxy): Set the label of a button

View File

@ -119,6 +119,7 @@ typedef enum
GDK_LOCK_MASK = 1 << 1,
GDK_CONTROL_MASK = 1 << 2,
GDK_MOD1_MASK = 1 << 3,
GDK_ALT_MASK = GDK_MOD1_MASK,
GDK_MOD2_MASK = 1 << 4,
GDK_MOD3_MASK = 1 << 5,
GDK_MOD4_MASK = 1 << 6,
@ -128,12 +129,18 @@ typedef enum
GDK_BUTTON3_MASK = 1 << 10,
GDK_BUTTON4_MASK = 1 << 11,
GDK_BUTTON5_MASK = 1 << 12,
/* The next few modifiers are used by XKB, so we skip to the end.
* Bits 16 - 28 are currently unused, but will eventually
* be used for "virtual modifiers". Bit 29 is used internally.
* Bits 15 - 25 are currently unused. Bit 29 is used internally.
*/
GDK_SUPER_MASK = 1 << 26,
GDK_HYPER_MASK = 1 << 27,
GDK_META_MASK = 1 << 28,
GDK_RELEASE_MASK = 1 << 30,
GDK_MODIFIER_MASK = GDK_RELEASE_MASK | 0x1fff
GDK_MODIFIER_MASK = 0x5c001fff
} GdkModifierType;
typedef enum

View File

@ -610,6 +610,8 @@ translate_key_event (GdkDisplay *display,
&event->key.keyval,
NULL, NULL, NULL);
_gdk_keymap_add_virtual_modifiers (keymap, &event->key.state);
/* Fill in event->string crudely, since various programs
* depend on it.
*/

View File

@ -80,6 +80,7 @@ struct _GdkKeymapX11
guint lock_keysym;
GdkModifierType group_switch_mask;
GdkModifierType num_lock_mask;
GdkModifierType modmap[8];
gboolean sun_keypad;
PangoDirection current_direction;
gboolean have_direction;
@ -168,6 +169,43 @@ update_keyrange (GdkKeymapX11 *keymap_x11)
#ifdef HAVE_XKB
static void
update_modmap (Display *display,
GdkKeymapX11 *keymap_x11)
{
static struct {
const gchar *name;
Atom atom;
GdkModifierType mask;
} vmods[] = {
{ "Meta", 0, GDK_META_MASK },
{ "Super", 0, GDK_SUPER_MASK },
{ "Hyper", 0, GDK_HYPER_MASK },
{ NULL, 0, 0 }
};
gint i, j, k;
if (!vmods[0].atom)
for (i = 0; vmods[i].name; i++)
vmods[i].atom = XInternAtom (display, vmods[i].name, FALSE);
for (i = 0; i < XkbNumVirtualMods; i++)
{
for (j = 0; vmods[j].atom; j++)
{
if (keymap_x11->xkb_desc->names->vmods[i] == vmods[j].atom)
{
for (k = 0; k < 8; k++)
{
if (keymap_x11->xkb_desc->server->vmods[i] & (1 << k))
keymap_x11->modmap[k] |= vmods[j].mask;
}
}
}
}
}
static XkbDescPtr
get_xkb (GdkKeymapX11 *keymap_x11)
{
@ -178,17 +216,21 @@ get_xkb (GdkKeymapX11 *keymap_x11)
if (keymap_x11->xkb_desc == NULL)
{
keymap_x11->xkb_desc = XkbGetMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask, XkbUseCoreKbd);
keymap_x11->xkb_desc = XkbGetMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask | XkbVirtualModsMask, XkbUseCoreKbd);
if (keymap_x11->xkb_desc == NULL)
g_error ("Failed to get keymap");
XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc);
XkbGetNames (xdisplay, XkbGroupNamesMask | XkbVirtualModNamesMask, keymap_x11->xkb_desc);
update_modmap (xdisplay, keymap_x11);
}
else if (keymap_x11->current_serial != display_x11->keymap_serial)
{
XkbGetUpdatedMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask,
XkbGetUpdatedMap (xdisplay, XkbKeySymsMask | XkbKeyTypesMask | XkbVirtualModsMask,
keymap_x11->xkb_desc);
XkbGetNames (xdisplay, XkbGroupNamesMask, keymap_x11->xkb_desc);
XkbGetNames (xdisplay, XkbGroupNamesMask | XkbVirtualModNamesMask, keymap_x11->xkb_desc);
update_modmap (xdisplay, keymap_x11);
}
keymap_x11->current_serial = display_x11->keymap_serial;
@ -324,7 +366,7 @@ update_keymaps (GdkKeymapX11 *keymap_x11)
keymap_x11->lock_keysym = GDK_VoidSymbol;
keymap_x11->group_switch_mask = 0;
keymap_x11->num_lock_mask = 0;
/* There are 8 sets of modifiers, with each set containing
* max_keypermod keycodes.
*/
@ -344,6 +386,22 @@ update_keymaps (GdkKeymapX11 *keymap_x11)
syms = keymap_x11->keymap + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
mask = 0;
for (j = 0; j < keymap_x11->keysyms_per_keycode; j++)
{
if (syms[j] == GDK_Meta_L ||
syms[j] == GDK_Meta_R)
mask |= GDK_META_MASK;
else if (syms[j] == GDK_Hyper_L ||
syms[j] == GDK_Hyper_R)
mask |= GDK_HYPER_MASK;
else if (syms[j] == GDK_Super_L ||
syms[j] == GDK_Super_R)
mask |= GDK_SUPER_MASK;
}
keymap_x11->modmap[i/keymap_x11->mod_keymap->max_keypermod] |= mask;
/* The fourth modifier, GDK_MOD1_MASK is 1 << 3.
* Each group of max_keypermod entries refers to the same modifier.
*/
@ -1299,7 +1357,7 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap,
if (hardware_keycode < keymap_x11->min_keycode ||
hardware_keycode > keymap_x11->max_keycode)
return FALSE;
#ifdef HAVE_XKB
if (KEYMAP_USE_XKB (keymap))
{
@ -1447,5 +1505,30 @@ _gdk_x11_get_group_for_state (GdkDisplay *display,
}
}
void
_gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap,
GdkModifierType *modifiers)
{
GdkKeymapX11 *keymap_x11;
int i;
keymap = GET_EFFECTIVE_KEYMAP (keymap);
keymap_x11 = GDK_KEYMAP_X11 (keymap);
for (i = 3; i < 8; i++)
{
if ((1 << i) & *modifiers)
{
if (keymap_x11->modmap[i] & GDK_SUPER_MASK)
*modifiers |= GDK_SUPER_MASK;
else if (keymap_x11->modmap[i] & GDK_HYPER_MASK)
*modifiers |= GDK_HYPER_MASK;
else if (keymap_x11->modmap[i] & GDK_META_MASK)
*modifiers |= GDK_META_MASK;
}
}
}
#define __GDK_KEYS_X11_C__
#include "gdkaliasdef.c"

View File

@ -143,6 +143,8 @@ void _gdk_keymap_state_changed (GdkDisplay *display);
void _gdk_keymap_keys_changed (GdkDisplay *display);
gint _gdk_x11_get_group_for_state (GdkDisplay *display,
GdkModifierType state);
void _gdk_keymap_add_virtual_modifiers (GdkKeymap *keymap,
GdkModifierType *modifiers);
GC _gdk_x11_gc_flush (GdkGC *gc);