간단한 입력기 프로그램을 만들고 싶습니다. 현재 수동 키 잡기를 사용하여 모든 창에서 입력을 캡처할 수 있습니다(사용자 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;
}