问题描述
我想了解Linux桌面键事件处理.
I want to hook into linux desktop key event handling.
按CapsLock应该输入某种命令行.
Pressing CapsLock should enter some sort of command line.
一些我想实现的命令:
- d/x:从当前光标位置删除,直到字符
x
. (受vi启发) - a:转到行首,例如pos1. (受emacs启发).
- k:删除直到行尾. (受emacs启发).
- ...
- d/x: Delete from current cursor position until character
x
. (inspired by vi) - a: Goto to beginning of line, like pos1. (inspired by emacs).
- k: Delete until end of line. (inspired by emacs).
- ...
命令应可在任何文本字段中使用:浏览器,邮件客户端,gnome终端,...
The commands should work in any text field: Browser, Mail Client, gnome terminal, ...
AFAIK低级xmodmap在这里无济于事.
AFAIK low level xmodmap won't help me here.
这样可能吗?
我需要在哪里放置挂钩?
Where do I need to place the hook?
当前目标平台是Ubuntu> = 14.04
Current target platform is Ubuntu >= 14.04
背景:我想将手指保持在F和J上,并且在不看键盘的情况下使用计算机.几年来一直适用于A-Z,但是像Pos1/End这样的键不容易访问.
Background: I want to keep my pointing fingers on F and J, and use the computer without looking at the keyboard. Works for A-Z since several years, but keys like Pos1/End are not easy to access.
如果您不理解此问题的一部分,请发表评论.谢谢.
Please leave a comment if you don't understand a part of this question. Thank you.
更新
此问题仅与如何挂接到关键事件处理有关.其他内容(命令行)是一个不同的主题.您如何捕捉例如CapsLock x
?
This question is only about how to hook into the key event handling. The other stuff (command line) is a different topic. How can you catch for example CapsLock x
?
更新2 我看到没有简单而直接的解决方案.如果您没有答案,但是您知道我在哪里可以找到更多帮助(例如在邮件列表FOO上询问),请告诉我.
Update2I see there is no easy and straight forward solution. If you have no answer, but you know where I can find more help (like ask on mailing list FOO), please tell me.
更新3 由于有些人不了解我想要的东西,所以我尝试解释一下:如果我使用emacs或bash,我会感觉自己像是在控制计算机:这就像飞行,只有很少的动作,我就能告诉计算机去做什么.我想.在Web浏览器文本区域,LibreOffice或使用Thunderbird中编辑文本可以消除这种感觉.光标移动很麻烦,它感觉不像飞行.我想控制桌面,而不仅仅是单个应用程序,并且将手指保持在F和J键上.
Update3Since some people do not understand what I want, I try to explain it: If I use emacs or bash I feel like being in control if the computer: it is like flying, with only very few movements I can tell the computer to do what I want. Editing text in webbrowser textarea, LibreOffice or using thunderbird makes this feeling go away. Cursor movements are cumbersome, it does not feel like flying. I want to control the desktop, not just a single application, and keep my pointing fingers on the F and J keys.
推荐答案
更新
您可以使用EVIOCGRAB
ioctl,而不是告诉X服务器忽略该设备,而我将其添加到下面的程序中.
Instead of telling the X server to ignore the device, you can use EVIOCGRAB
ioctl, which I added to the program below.
您需要执行以下操作:
1.确保已编译并加载了CONFIG_UINPUT模块.我相信Ubuntu已经有了它.如果看不到/dev/uinput
设备,请尝试运行modprobe -v uinput
加载模块.
1.Make sure you have CONFIG_UINPUT module compiled and loaded. I believe Ubuntu already has it. If you don't see /dev/uinput
device, try running modprobe -v uinput
to load the module.
2.以root用户身份运行以下程序,并为其指定键盘设备的路径,例如:
2.Run the following program as root and give it the path of the keyboard device, eg:
./process /dev/input/by-id/usb-Microsoft_Wired_Keyboard_600-event-kbd
以下程序创建一个伪造的输入设备,称为uinput-sample
,并将所有事件从给定的输入设备转发到该输入设备.我根据 http://thiemonge.org/getting-started-with-uinput中给出的示例进行了改编
The following program creates a fake input device called uinput-sample
and forwards all events from a given input device to it. I adapted it from the sample given in http://thiemonge.org/getting-started-with-uinput
您可以对其进行修改以执行您想做的事情.
You can modify it to do things you want to do.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#define die(str, args...) do { \
perror(str); \
exit(EXIT_FAILURE); \
} while(0)
int
main(int argc, char* argv[])
{
int fdo, fdi;
struct uinput_user_dev uidev;
struct input_event ev;
int i;
if(argc != 2) die("error: specify input device");
fdo = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if(fdo < 0) die("error: open");
fdi = open(argv[1], O_RDONLY);
if(fdi < 0) die("error: open");
if(ioctl(fdi, EVIOCGRAB, 1) < 0) die("error: ioctl");
if(ioctl(fdo, UI_SET_EVBIT, EV_SYN) < 0) die("error: ioctl");
if(ioctl(fdo, UI_SET_EVBIT, EV_KEY) < 0) die("error: ioctl");
if(ioctl(fdo, UI_SET_EVBIT, EV_MSC) < 0) die("error: ioctl");
for(i = 0; i < KEY_MAX; ++i)
if(ioctl(fdo, UI_SET_KEYBIT, i) < 0) die("error: ioctl");
memset(&uidev, 0, sizeof(uidev));
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-sample");
uidev.id.bustype = BUS_USB;
uidev.id.vendor = 0x1;
uidev.id.product = 0x1;
uidev.id.version = 1;
if(write(fdo, &uidev, sizeof(uidev)) < 0) die("error: write");
if(ioctl(fdo, UI_DEV_CREATE) < 0) die("error: ioctl");
while(1)
{
if(read(fdi, &ev, sizeof(struct input_event)) < 0)
die("error: read");
ev.time.tv_sec = 0;
ev.time.tv_usec = 0;
if(write(fdo, &ev, sizeof(struct input_event)) < 0)
die("error: write");
}
if(ioctl(fdo, UI_DEV_DESTROY) < 0) die("error: ioctl");
close(fdi);
close(fdo);
return 0;
}
这篇关于钩入linux键事件处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!