(摘) Linux下捕获键盘输入

声明:内容源自网络,版权归原作者所有。若有侵权请在网页聊天中联系我

源于linux的root下,不能正常的获取到终端按键.使用直接读取硬件的方式应该能解决.
原文讲解: https://janczer.github.io/work-with-dev-input/

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"os"
	"time"
)

func main() {
	f, err := os.Open("/dev/input/event10")
	if err != nil {
		panic(err)
	}
	defer f.Close()
	b := make([]byte, 24)
	for {
		f.Read(b)
		sec := binary.LittleEndian.Uint64(b[0:8])
		usec := binary.LittleEndian.Uint64(b[8:16])
		t := time.Unix(int64(sec), int64(usec))
		fmt.Println(t)
		var value int32
		typ := binary.LittleEndian.Uint16(b[16:18])
		code := binary.LittleEndian.Uint16(b[18:20])
		binary.Read(bytes.NewReader(b[20:]), binary.LittleEndian, &value)
		fmt.Printf("type: %x\ncode: %d\nvalue: %d\n", typ, code, value)
	}
}

以上代码有误,理论没错,参数其它库作了一些修改.
在以下代码中,我只定义了6个键,因为我使用的是6个键位的键盘.

/*
EV_SYN 0x00 // 同步事件
EV_KEY 0x01 // 按键事件
EV_REL 0x02 // 相对坐标事件
EV_ABS 0x03 // 绝对坐标事件
EV_MSC 0x04 // 杂项事件
EV_SW  0x05 // 开关事件
EV_LED 0x11 // LED
EV_SND 0x12 // 声音
EV_REP 0x14 // 重复事件
EV_FF  0x15 // 压力事件
EV_PWR 0x16 // 电源事件
EV_FF_STATUS 0x17 // 压力状态事件
*/

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"os"
	"syscall"
	"time"
)

type InputEvent struct {
	Time  syscall.Timeval
	Type  uint16
	Code  uint16
	Value int32
}

var KEY = map[int]string{
	2: "1",
	3: "2",
	4: "3",
	5: "4",
	6: "5",
	7: "6",
}

func main() {
	fmt.Println("start...")
	// var eventsize = int(unsafe.Sizeof(InputEvent{}))
	f, err := os.Open("/dev/input/event1")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	event := InputEvent{}
	buffer := make([]byte, 16)

	evfmt := "time %s type %d , code %-3d (%s), value %d"
	for {
		f.Read(buffer)
		b := bytes.NewBuffer(buffer)
		binary.Read(b, binary.LittleEndian, &event)
		//fmt.Println(event)
		code := int(event.Code)
		etype := int(event.Type)
		code_name := ""
		switch event.Type {
		case 0: // EV_SYN 同步事件,通知用户接收消息
			break
		case 1: // 按键事件
			val, k := KEY[code]
			if k {
				code_name = val
			}
			res := fmt.Sprintf(evfmt, time.Unix(int64(event.Time.Sec), int64(event.Time.Usec)).Format("2006-01-02 15:04:05"), etype, event.Code, code_name, event.Value)
			fmt.Println(res)
			break
		case 4: //
			break
		}
		// res := fmt.Sprintf(evfmt, event.Time.Sec, event.Time.Usec, etype,event.Code, code_name, event.Value)
		// fmt.Println(res)
	}
}

相关文章