Search code examples
cgtkgtk2

Detect which key is pressed in C


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

Solution

  • 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;
    }