입력을 캡처하고 동시에 주요 이벤트를 보냅니다.

입력을 캡처하고 동시에 주요 이벤트를 보냅니다.

간단한 입력기 프로그램을 만들고 싶습니다. 현재 수동 키 잡기를 사용하여 모든 창에서 입력을 캡처할 수 있습니다(사용자 dirkt에게 감사드립니다!).

또한 보내기 버튼을 사용할 수도 있습니다 XTestFakeKeyEvent().

문제는 이 두 부분을 합칠 수 없다는 것이다. 가짜 키 이벤트가 발생하면 포커스가 있는 의도된 애플리케이션 대신 내 프로그램에서 이를 수신합니다. 내 프로그램이 가짜 이벤트에 의해 생성된 키코드를 수동적으로 가져오지 못하는 경우에도 이런 일이 발생합니다. 루트 창에서 이벤트를 받기 때문인 것 같지만 그렇게 하지 않으면 다른 창에서 입력을 캡처할 수 없을 것 같습니다.

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
#include <stdio.h>

int main()
{
    Display *display;
    Window   rootwindow;
    XEvent   event;

    display = XOpenDisplay(NULL);
    rootwindow = DefaultRootWindow(display);

    XSelectInput(display, rootwindow, KeyPressMask);    

    unsigned int modifiers[] = {
        0, 
        ShiftMask,
        LockMask, //capslock
        Mod2Mask, //numlock
        ShiftMask | LockMask,
        ShiftMask | Mod2Mask,
        LockMask | Mod2Mask,
        LockMask | Mod2Mask | ShiftMask,
    };

    int keys [] = {
        XKeysymToKeycode(display, XK_A),
        XKeysymToKeycode(display, XK_B),
        ...
        XKeysymToKeycode(display, XK_Z)
    };

    int l;
    int m;
    for(l = 0; l < sizeof(keys)/sizeof(int); l++){
        for(m = 0; m < sizeof(modifiers)/sizeof(unsigned int); m++){
            XGrabKey(display, keys[l], modifiers[m], rootwindow, False, GrabModeAsync, GrabModeAsync);
        }
    }

    int repeat = 0;

    while (1) {

        XNextEvent(display, &event);

        if (event.type == KeyPress && event.xkey.send_event == 0) {
            printf("KeyPress: keycode %u state %u send-event %d\n", event.xkey.keycode, event.xkey.state, event.xkey.send_event);
            fflush(stdout);

            if(repeat == 0){ //to avoid infinite loops
                repeat = 1;

                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_7), 1, CurrentTime);
                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_7), 0, CurrentTime);
            }

        }
    }

    XCloseDisplay(display);
    return 0;
}

관련 정보