XRecord 示例

jouyouyun posted @ 2013年12月26日 12:41 in xrecord with tags xrecord , 3425 阅读

最近做但按键绑定,用到了 XRecord。但其的示例程序很难找,故在此记录一下,以便日后温习。

XRecord 是 xlib 的一个扩展,在 xtest 扩展中。下面的程序主要监听按键与鼠标事件,其它的事件可以根据需要添加。

xrecord-example.c
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/**
 * Author:      jouyouyun <jouyouwen717@gmail.com>
 * Maintainer:  jouyouyun <jouyouwen717@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 **/
 
#include <glib.h>
#include <X11/Xlib.h>
#include <X11/extensions/record.h>
 
static void event_cb (XPointer user_data, XRecordInterceptData *hook);
 
int main (int argc, char *argv[])
{
    Display *ctrl_disp = XOpenDisplay(NULL);
    Display *data_disp = XOpenDisplay(NULL);
 
    if ( !ctrl_disp || !data_disp ) {
        g_warning ("Unable to connect to X11 display!");
        return -1;
    }
 
    gint major, minor, dummy;
 
    if ( !XQueryExtension (ctrl_disp, "XTEST", &major, &minor, &dummy) ) {
        g_warning ("XTest extension missing!");
        return -1;
    }
 
    if ( !XRecordQueryVersion (ctrl_disp, &major, &minor) ) {
        g_warning ("Failed to obtain xrecord version!");
        return -1;
    }
 
    XSynchronize(ctrl_disp, True);
    XFlush (ctrl_disp);
 
    XRecordRange *range = XRecordAllocRange ();
    /*
     * 设定事件监听的范围
     * 监听 first ~ last 之间的事件
     */
    range->device_events.first = KeyPress;
    range->device_events.last = ButtonRelease;
 
    XRecordClientSpec spec = XRecordAllClients;
    XRecordContext context = XRecordCreateContext (
                                 data_disp, 0, &spec, 1, &range, 1 );
 
    if ( !context ) {
        g_warning ("Failed to create context!");
        return -1;
    }
 
    if ( !XRecordEnableContext(data_disp, context, event_cb, NULL) ) {
        g_warning ("Failed to enable context!");
        return -1;
    }
 
    /*
    if ( !XRecordEnableContextAsync (data_disp, context, event_cb, NULL) ) {
        g_warning ("Failed to enable context!");
        return -1;
    }
 
    XRecordProcessReplies (data_disp);
    */
 
    XRecordDisableContext(data_disp, context);
    XRecordFreeContext (data_disp, context);
    XFree(range);
 
    XCloseDisplay (data_disp);
    XCloseDisplay (ctrl_disp);
    return 0;
}
 
static void
event_cb (XPointer user_data, XRecordInterceptData *hook)
{
    if ( hook->category != XRecordFromServer ) {
        g_warning ("Data not from server!");
        return;
    }
 
    int event_type = hook->data[0];
    KeyCode keycode = hook->data[1];
    g_print ("Intercepted event type: %d, code: %d\n",
             event_type, keycode);
 
    switch (event_type) {
        case KeyPress:
            g_print ("key press event!\n");
            break;
 
        case KeyRelease:
            g_print ("key release event!\n");
            break;
 
        case ButtonPress:
            g_print ("button press event!\n");
            break;
 
        case ButtonRelease:
            g_print ("button release event!\n");
            break;
 
        default:
            /* FIXME: other events grab */
            break;
    }
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter