gpt4 book ai didi

c++ - 在 X11 中监听键盘事件而不消耗它们 - 键盘 Hook

转载 作者:IT王子 更新时间:2023-10-29 00:24:22 33 4
gpt4 key购买 nike

我尝试编写一个程序,它可以 Hook 键盘消息,以便在 Ubuntu (KDE) 中按下时读出每个键的名称;不干扰程序中键盘的正常操作(仅报出键名)。

这是我的程序:

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

using namespace std;

void SendPressKeyEvent(Display *display, XKeyEvent xkey)
{
Window current_focus_window;
int current_focus_revert;
XGetInputFocus(display, &current_focus_window, &current_focus_revert);
xkey.type = KeyPress;
xkey.display = display;
xkey.window = current_focus_window;
xkey.root = DefaultRootWindow(display);
xkey.subwindow = None;
xkey.time = 1000 * time(0);
xkey.x = 0;
xkey.y = 0;
xkey.x_root = 0;
xkey.y_root = 0;
xkey.same_screen = True;
XSendEvent(display, InputFocus, True, KeyPressMask, (XEvent *)(&xkey));
}

void SendReleaseKeyEvent(Display *display, XKeyEvent xkey)
{
Window current_focus_window;
int current_focus_revert;
XGetInputFocus(display, &current_focus_window, &current_focus_revert);
xkey.type = KeyRelease;
xkey.display = display;
xkey.window = current_focus_window;
xkey.root = DefaultRootWindow(display);
xkey.subwindow = None;
xkey.time = 1000 * time(0);
xkey.x = 0;
xkey.y = 0;
xkey.x_root = 0;
xkey.y_root = 0;
xkey.same_screen = True;
XSendEvent(display, InputFocus, True, KeyReleaseMask, (XEvent *)(&xkey));
}

void *TaskCode(void* arg)
{
switch(*(int*)arg)
{
case 38:
system("espeak -v en " "\"a\"");
}
return 0;
}

int main()
{
Display *display = XOpenDisplay(0);
if(display == 0)
exit(1);
XGrabKeyboard(display, DefaultRootWindow(display), True, GrabModeAsync, GrabModeAsync, CurrentTime);
XEvent event;
while(true)
{
XNextEvent(display, &event);
if(event.type == Expose)
{

}
if(event.type == KeyPress)
{
SendPressKeyEvent(display,event.xkey);
if(event.xkey.keycode == 38)
{
pthread_t thread;
int thread_arg = event.xkey.keycode;
pthread_create(&thread,0, TaskCode, (void*) &thread_arg);
}
}
if(event.type == KeyRelease)
SendReleaseKeyEvent(display,event.xkey);
}
XCloseDisplay(display);
}

此程序仅针对键a,可以扩展到其他键。

但是当这个程序运行时,一些程序(例如 Chromium)不会在它们的编辑框中显示 blinker(光标)。所有 KDE 热键也将被禁用。

如何解决这个问题?

最佳答案

这是我的简单粗暴的例子

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <ctype.h>


int main ()
{
Display* d = XOpenDisplay(NULL);
Window root = DefaultRootWindow(d);
Window curFocus;
char buf[17];
KeySym ks;
XComposeStatus comp;
int len;
int revert;

XGetInputFocus (d, &curFocus, &revert);
XSelectInput(d, curFocus, KeyPressMask|KeyReleaseMask|FocusChangeMask);

while (1)
{
XEvent ev;
XNextEvent(d, &ev);
switch (ev.type)
{
case FocusOut:
printf ("Focus changed!\n");
printf ("Old focus is %d\n", (int)curFocus);
if (curFocus != root)
XSelectInput(d, curFocus, 0);
XGetInputFocus (d, &curFocus, &revert);
printf ("New focus is %d\n", (int)curFocus);
if (curFocus == PointerRoot)
curFocus = root;
XSelectInput(d, curFocus, KeyPressMask|KeyReleaseMask|FocusChangeMask);
break;

case KeyPress:
printf ("Got key!\n");
len = XLookupString(&ev.xkey, buf, 16, &ks, &comp);
if (len > 0 && isprint(buf[0]))
{
buf[len]=0;
printf("String is: %s\n", buf);
}
else
{
printf ("Key is: %d\n", (int)ks);
}
}

}
}

它不可靠,但大部分时间都有效。 (它显示了我现在正在在此框中键入的键)。您可以调查为什么它有时会失败;)原则上它也不能显示热键。热键是抓取的 key ,只有一个客户端可以获得抓取的 key 。除了加载为此目的设计的特殊 X11 扩展(例如 XEvIE)之外,这里什么也做不了。

关于c++ - 在 X11 中监听键盘事件而不消耗它们 - 键盘 Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22749444/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com