There are only two types of key event: GDK_KEY_PRESS and GDK_KEY_RELEASE. Some hardware does
not generate key release events; you should not write
code that depends on
GDK_KEY_RELEASE events, though your code should
respond sanely if one is received.
Here are the contents of a key event:
typedef struct _GdkEventKey GdkEventKey;
struct _GdkEventKey
{
GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 time;
guint state;
guint keyval;
gint length;
gchar *string;
};
|
The first three members are the standard members from
GdkEventAny; the time and state members are identical to those
found in GdkEventButton.
keyval contains a keysym. The X server keeps a global
translation table which converts combinations of physical
keys and modifiers to keysyms. For example, the key
marked "A" on the keyboard typically generates the keysym
GDK_a with no modifiers,
and GDK_A with shift held
down. Users can change the physical-key-to-keysym
mapping; for example, they may rearrange their keys to
create a Dvorak keyboard (more commonly, they might swap
Control and Caps Lock, or use the Alt key as a Meta key).
Keysyms are defined in
gdk/gdkkeysyms.h. You will need to include this file
to use the keyval field.
Keysyms are matched with a string representation. For
example, the GDK_a keysym
typically maps to the string
"a". (However, X allows the keysym-to-string
mapping to be modified.) The
string member of
GdkEventKey contains a keysym's string
representation, and the
length member contains the string's length. Keep
in mind that the length may be 0 (many non-alphanumeric
keys have no string representation by default). (If
you're familiar with Xlib, the
string field is simply the result of XLookupString() or
XmbLookupString(). Even if you aren't familiar with
Xlib, the man pages for these functions may be helpful.)
In general, if you are reading key events in order to
create a textual representation of what the user is
typing, you should use the
string field of
GdkEventKey.
GtkEntry and
GtkText use the
string field, for example. A word processor would
also read this field. If you're reading key events for
some other reason (such as keyboard shortcuts), or if you
are interested in keys with no string representation by
default (such as function keys or arrow keys), you will
need to use the keyval
field and the keysyms defined in
gdk/gdkkeysyms.h.
Here is a sample key event callback demonstrating how to
extract information from a key event. It would be
suitable for connection to the
"key_press_event" signal of any GtkWidget:
static gint
key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data)
{
if (event->length > 0)
printf("The key event's string is `%s'\n", event->string);
printf("The name of this keysym is `%s'\n",
gdk_keyval_name(event->keyval));
switch (event->keyval)
{
case GDK_Home:
printf("The Home key was pressed.\n");
break;
case GDK_Up:
printf("The Up arrow key was pressed.\n");
break;
default:
break;
}
if (gdk_keyval_is_lower(event->keyval))
{
printf("A non-uppercase key was pressed.\n");
}
else if (gdk_keyval_is_upper(event->keyval))
{
printf("An uppercase letter was pressed.\n");
}
}
|
gdk_keyval_name() is useful for
debugging; it returns the name of the keysym without the
GDK_ prefix. For example,
it returns "Home" if
passed the value
GDK_Home. The string is statically allocated. gdk_keyval_is_lower() returns FALSE if the keysym has an
uppercase equivalent. Thus it returns TRUE for lowercase letters, numbers,
and all non-alphanumeric characters. It returns FALSE only for uppercase
letters. gdk_keyval_is_upper()
returns the opposite values.