一、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 设备文件

  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