一、Linux输入子系统
https://github.com/spotify/linux/blob/master/include/linux/input.h https://www.kernel.org/doc/Documentation/input/event-codes.txt
SYN_REPORT:
- Used to synchronize and separate events into packets of input data changes occurring at the same moment in time. For example, motion of a mouse may set the REL_X and REL_Y values for one motion, then emit a SYN_REPORT. The next motion will emit more REL_X and REL_Y values and send another SYN_REPORT.
二、如何判断物理设备对应的设备文件
结论1: Linux输入子系统,可以模拟已经存在的(物理)键盘按键,如果没有插入任何设备,是无法实现模拟功能的。
结论2: ls 可以查看/dev/input下有哪些设备 cat /proc/bus/input/devices 可以查看物理设备和/dev下的设备文件对应关系。 通常一个物理设备可以包含多个功能,也会对应多个设备文件,主要看“Name”和“Handlers” Name: “Bluetooth 3.0 Keyboard Keyboard” 、”Bluetooth 3.0 Keyboard Consumer Control”、”Bluetooth 3.0 Keyboard System Control”,一般带有”Consumer Control、System Control的都不是可以操作的设备” Handlers: ** “sysrq kbd leds event9”、”kbd event10”、”kbd event11”,带有”sysrq”的才是 I: Bus=0005 Vendor=04e8 Product=7021 Version=0001 N: Name=”Bluetooth 3.0 Keyboard Keyboard“ P: Phys=dc:a6:32:46:57:f3 S: Sysfs=/devices/platform/soc/fe201000.serial/tty/ttyAMA0/xxx/input/input9 U: Uniq=20:20:01:17:d6:b2 H: Handlers=sysrq kbd leds event9 B: PROP=0 B: EV=120013 B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe B: MSC=10 B: LED=1f
2.1 设备文件
ls /dev/input/
当没有插入任何输入设备(mouse、keyboard)时,/dev/input下没有任何对应的设备
2.2 对应关系
cat /proc/bus/input/devices
三、模拟按键
https://gitee.com/chuankong/key-simulate.git
#include <linux/input.h>
#include "common.h"
#define DEVNAME "/dev/input/event3"
/*
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
#define EV_KEY 0x01
*/
void simulate_key(int fd,int kval)
{
struct input_event event;
event.type = EV_KEY;
event.code = kval;
event.value = 1; //press down
gettimeofday(&event.time,0);
write(fd,&event,sizeof(event)) ;
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(fd, &event, sizeof(event));
event.type = EV_KEY;
event.code = kval;
event.value = 0;
gettimeofday(&event.time, 0);
write(fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(fd, &event, sizeof(event));
}
int main(int argc, char *argv[])
{
uint16_t keycode;
int k_fd;
if((k_fd = open(DEVNAME, O_RDWR)) < 0)
{
printf("open error!\n");
return k_fd;
}
#if 0
keycode = KEY_LEFT;
keycode = KEY_HOME;
keycode = KEY_END;
keycode = KEY_F5;
#endif
keycode = KEY_A;
simulate_key(k_fd,keycode);
close(k_fd);
return 0;
}
二、PPT按键模拟
#!/bin/bash
ppt_dir=/home/pi/Programming/ppt_dir
open_office() {
filename=${ppt_dir}/$1
if [ -f $filename ]; then
$(`soffice --invisible --norestore --show ${filename}`)
else
echo "$filename is not exist."
fi
}
close_office() {
$(`pkill soffice`)
}
pageup_office() {
$(`/usr/bin/keysimulate 105`)
}
pagedown_office() {
$(`/usr/bin/keysimulate 106`)
}
pagebegin_office() {
$(`/usr/bin/keysimulate 102`)
}
pageend_office() {
$(`/usr/bin/keysimulate 107`)
}
if [ $# -lt 2 ]; then
echo "Usage: $0 <oper> <file>"
exit 0;
fi
case "$1" in
open)
open_office $2
;;
close)
close_office
;;
up)
pageup_office
;;
down)
pagedown_office
;;
begin)
pagebegin_office
;;
end)
pageend_office
;;
*)
echo "error: Invalid oper($1),Supports(open,close,up,down,begin,end)"
;;
esac
exit 0