3

I'm trying to find a way to find out which key is pressed down in C. This will be in a graphical environment, written in GTK2, but I don't think the answer lies there. I think I might be able to do this using Xlib, but I haven't been able to find anything conclusive on this.

Does anyone have any suggestions on how to do this?

I've managed to catch a keypress using the follow code:

GtkWidget *window;
void gtk_widget_set_events(window,GDK_KEY_RELEASE_MASK);
g_signal_connect(window,"key_release_event",G_CALLBACK(hello),NULL);

However, I would like to identify which key is pressed. From the link posted by Aditya Kumar, I know the answer lies with using GdkEventKey, since it is a structure which has a keyval field, but I cannot seem to get the syntax right. What is the correct way of getting this number?

This is a method I've tried:

static void hello( GtkWidget *widget,
               guint   data ){

g_print ("Hello World, %d was pressed\n",data);}

I tried supplying "data" by doing this when I catch the key_release_event:

g_signal_connect(window,"key_release_event",G_CALLBACK(hello),GdkEventKey.keyval);

However, I get a compiler error like so:

hello.c:85:5: error: expected ‘)’ before ‘.’ token 
hello.c:85:5: error: expected expression before ‘,’ token
Sinthet
  • 873
  • 2
  • 8
  • 13

3 Answers3

9

You are correct with your original syntax.

g_signal_connect(window, "key-release-event", G_CALLBACK(key_event), NULL);

Where the key_event function looks something like (note I am using the gdk_keyval_name to convert the keyval int value to a string for printing):

static gboolean
key_event(GtkWidget *widget,
          GdkEventKey *event)
{
    g_printerr("%s\n",
               gdk_keyval_name (event->keyval));
    return FALSE;
}

Here's a complete example program:

#include <gtk/gtk.h>

static gboolean
key_event(GtkWidget *widget,
          GdkEventKey *event)
{
    g_printerr("%s\n",
               gdk_keyval_name (event->keyval));
    return FALSE;
}

int main( int   argc,
          char *argv[] )
{

    GtkWidget *window;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    g_signal_connect(window, "key-release-event", G_CALLBACK(key_event), NULL);

    gtk_widget_show (window);

    gtk_main ();

    return 0;
}
Mark
  • 106,305
  • 20
  • 172
  • 230
  • Great! This code works as expected. Could you please explain this line's syntax? gdk_keyval_name (event->keyval)); I'm confused about (event->keyval)); in particular. – Sinthet Aug 14 '11 at 23:52
  • 2
    @Sinthet, the event variable is a pointer to a GdkEventKey (http://developer.gnome.org/gdk/stable/gdk-Event-Structures.html#GdkEventKey) struct. It has a member keyval: an unsigned int that corresponds to the key that was pressed. This mapping is defined in gdkkeysyms.h (http://git.gnome.org/browse/gtk+/plain/gdk/gdkkeysyms.h) – Mark Aug 14 '11 at 23:57
  • Alright, I think I understand how everything comes together. Thanks a lot for your post! – Sinthet Aug 15 '11 at 00:00
1

while looking at the gdk reference manual i think you can capture the keyboard events using this unless you specifically want to have a 'C' program.

Here is the link to help you out.

http://www.gtk.org/api/2.6/gdk/gdk-Keyboard-Handling.html

A. K.
  • 34,395
  • 15
  • 52
  • 89
  • Alright, this seems correct, but how can I go about actually getting the keyval? Since its a structure, I tried doing something like keyval=GdkEventKey.keyval, but that doesn't work. – Sinthet Aug 13 '11 at 16:05
  • please post what u've tried by editing your original post. also post what didn't work – A. K. Aug 13 '11 at 19:07
  • I've posted what I've tried, truncated to the relevant portions. I tried a couple of variants, but I can't seem to get it correctly. – Sinthet Aug 13 '11 at 20:01
0

event->keyval is a pointer to a struct, where keyval contains a integer value for the key pressed, this has been used above in a function gdk_keyval_name (event->keyval) which gets a actual name for the key.

martin
  • 1