summaryrefslogtreecommitdiffstats
path: root/source/x11-event-source.c
blob: f12f883ddc5b1e276f2f6dee71a4b82bb3a4775b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <glib.h>
#include <X11/Xlib.h>
#include "x11-event-source.h"

/**
 * Custom X11 Source implementation.
 */
typedef struct _X11EventSource
{
    // Source
    GSource  source;
    // Polling field
    gpointer fd_x11;
    Display  *display;
} X11EventSource;

static gboolean x11_event_source_prepare ( GSource * base, gint * timeout )
{
    X11EventSource *xs = (X11EventSource *) base;
    *timeout = -1;
    return /*XPending ( xs->display ) || */ g_source_query_unix_fd ( base, xs->fd_x11 );
}

static gboolean x11_event_source_check ( GSource * base )
{
    X11EventSource *xs = (X11EventSource *) base;
    if ( g_source_query_unix_fd ( base, xs->fd_x11 ) ) {
        return TRUE;
    }
    return FALSE;
}

static gboolean x11_event_source_dispatch ( GSource * base, GSourceFunc callback, gpointer data )
{
    X11EventSource *xs = (X11EventSource *) base;
    if ( callback ) {
        if ( g_source_query_unix_fd ( base, xs->fd_x11 ) ) {
            callback ( data );
        }
    }
    return G_SOURCE_CONTINUE;;
}

static GSourceFuncs x11_event_source_funcs = {
    x11_event_source_prepare,
    x11_event_source_check,
    x11_event_source_dispatch,
    NULL
};

GSource * x11_event_source_new ( Display  *display )
{
    int            x11_fd  = ConnectionNumber ( display );
    X11EventSource *source = (X11EventSource *) g_source_new ( &x11_event_source_funcs, sizeof ( X11EventSource ) );
    source->display = display;
    source->fd_x11  = g_source_add_unix_fd ( (GSource *) source, x11_fd, G_IO_IN | G_IO_ERR );

    // Attach it to main loop.
    g_source_attach ( (GSource *) source, NULL );
    return (GSource *) source;
}
void x11_event_source_set_callback ( GSource *source, GSourceFunc callback )
{
    g_source_set_callback ( source, callback, NULL, NULL );
}