Estou procurando criar um programa de método de entrada simples. Atualmente, eu sou capaz de capturar a entrada de qualquer janela usando as teclas passivas ( agradece ao usuário dirkt! ).
Separadamente, também posso enviar pressionamentos de tecla usando XTestFakeKeyEvent()
.
A questão é que não posso colocar essas duas partes juntas. Ao emitir um evento de chave falso, ele é recebido pelo meu programa em vez do aplicativo pretendido que tem foco. Isso ocorre mesmo que meu programa não tenha uma captura passiva no código de chave emitido pelo evento falso. Eu suspeito que isso seja porque estou obtendo eventos da janela raiz, mas se eu não fizer isso, não acho que posso capturar a entrada de outras janelas.
#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;
}
Tags keyboard x11 input-method