AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题

问题[tablet](unix)

Martin Hope
tobiasBora
Asked: 2019-03-22 02:48:05 +0800 CST

图形平板 VEIKK:Linux 上的压力敏感度

  • 4

我刚买了图形平板电脑 VEIKK A30。鼠标直接被识别。不幸的是,我找不到如何在 Linux 上启用压力敏感度。我看到一个人报告说,通过一些调整可以使其工作,但找不到任何参考。

编辑:这是 dmesg 的输出

[mars19 01:15] usb 2-1: new full-speed USB device number 10 using xhci_hcd
[  +0,153026] usb 2-1: New USB device found, idVendor=2feb, idProduct=0002, bcdDevice= 0.00
[  +0,000006] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  +0,000004] usb 2-1: Product: A30
[  +0,000003] usb 2-1: Manufacturer: VEIKK.INC
[  +0,000004] usb 2-1: SerialNumber: 0000001
[  +0,003052] input: VEIKK.INC A30 Mouse as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/0003:2FEB:0002.000C/input/input64
[  +0,064250] input: VEIKK.INC A30 as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/0003:2FEB:0002.000C/input/input65
[  +0,000429] hid-generic 0003:2FEB:0002.000C: input,hidraw0: USB HID v1.00 Mouse [VEIKK.INC A30] on usb-0000:00:14.0-1/input0
[  +0,001079] input: VEIKK.INC A30 as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:2FEB:0002.000D/input/input66
[  +0,062599] hid-generic 0003:2FEB:0002.000D: input,hidraw1: USB HID v1.00 Keyboard [VEIKK.INC A30] on usb-0000:00:14.0-1/input1
[  +0,001208] hid-generic 0003:2FEB:0002.000E: hiddev0,hidraw2: USB HID v1.00 Device [VEIKK.INC A30] on usb-0000:00:14.0-1/input2

Gimp 展示: 在此处输入图像描述

Edit2:嗯,似乎可以读取发送压力的设备,sudo cat /dev/hidraw0因为模式因我施加的压力而异。我不知道如何阅读这个二进制文件^^如果可以,也许我可以使用uinput将其映射到新设备?^^ 请注意,/dev/input包含mouseX、eventY 和mouse1 之类的文件与数位板相关,但与压力无关,并且此文件夹中唯一显示与数位板相关的大量信息的文件是文件/dev/input/by-id/usb-VEIKK.INC_A30_0000001-event-mouse。但是模式是否与压力匹配不太清楚,这里发送的信息太多。如果您知道如何解析它们,请告诉我!

Edit3:所以我还没有驱动程序,但至少从设备原始通信中读取输入似乎很容易。我制作了这个 python 脚本作为概念证明:

#!/usr/bin/env python3
import struct
PRINT_TIMESTAMP = True
# Open the file in the read-binary mode
f = open("/dev/input/by-id/usb-VEIKK.INC_A30_0000001-event-mouse", "rb" )

while 1:
    data = f.read(24)
    # print struct.unpack('4IHHI',data)
    ###### FORMAT = ( Time Stamp_INT , 0 , Time Stamp_DEC , 0 , 
    ######   type , code ( key pressed ) , value (press/release) )
    time_int, _, time_dec, _, ev_type, ev_code, ev_val = struct.unpack('4IHHI',data)
    t = (ev_type, ev_code)
    if ((t == (0,0) and ev_val == 0)
        or (t == (4, 4) and ev_val >= 589825 and ev_val <= 589827)):
      # Redundant as it's for normal/bottom/top clicks
      # (same code for press/release), or just garbage 0,0,0
        continue
    if PRINT_TIMESTAMP:
        print("[{:.2f}] ".format(time_int + time_dec/1e6),
              end="", flush=True)
    if t == (3,0):
        print("Pos x: {} ({:.2f}%)".format(ev_val, 100*ev_val/32767), flush=True)
    elif t == (3,1):
        print("Pos y: {} ({:.2f}%)".format(ev_val, 100*ev_val/32767), flush=True)
    elif t == (3,24):
        print("Pression: {} ({:.2f}%)".format(ev_val, 100*ev_val/8191), flush=True)
    elif t == (1,272):
        print("Normal click ({})".format("press" if ev_val else "release"), flush=True)
    elif t == (1,273):
        print("click button 2 (bottom) ({})".format("press" if ev_val else "release"), flush=True)
    elif t == (1,274):
        print("click button 3 (top) ({})".format("press" if ev_val else "release"), flush=True)
    else:
        print("Unknow: type={}, code={}, value={}".format(ev_type, ev_code, ev_val), flush=True)

演示:

[1553182025.55] Pos y: 11458 (34.97%)
[1553182025.55] Pos x: 14310 (43.67%)
[1553182025.56] Pos x: 14314 (43.68%)
[1553182025.56] Pos x: 14318 (43.70%)
[1553182025.57] Pos x: 14321 (43.71%)
[1553182025.57] Normal click (press)
[1553182025.57] Pos x: 14323 (43.71%)
[1553182025.57] Pression: 1122 (13.70%)
[1553182025.57] Pos x: 14326 (43.72%)
[1553182025.57] Pos y: 11466 (34.99%)
[1553182025.57] Pression: 1260 (15.38%)
[1553182025.58] Pos x: 14329 (43.73%)
[1553182025.58] Pression: 1337 (16.32%)
[1553182025.58] Pos x: 14330 (43.73%)
[1553182025.58] Pos y: 11494 (35.08%)
[1553182025.58] Pression: 1515 (18.50%)
[1553182025.59] Pos y: 11506 (35.11%)
[1553182025.59] Pression: 1687 (20.60%)
[1553182025.59] Pos y: 11517 (35.15%)
[1553182025.59] Pression: 1689 (20.62%)
[1553182025.59] Pos y: 11529 (35.18%)
[1553182025.59] Pression: 1789 (21.84%)
[1553182025.60] Pos y: 11536 (35.21%)
[1553182025.60] Pression: 1829 (22.33%)
[1553182025.60] Pos y: 11542 (35.22%)
[1553182025.60] Pression: 1907 (23.28%)
[1553182025.61] Pression: 2031 (24.80%)
[1553182025.61] Pos y: 11549 (35.25%)
[1553182025.61] Pression: 2140 (26.13%)

编辑 4:惊人的页面:https ://digimend.github.io/support/howto/trbl/locating_failure/然而,一切都在这里工作......除了我想测试它的最后一步。我尝试使用 MyPaint 进行测试,但它没有检测到压力。

我还尝试编写自己的代码,基本上将事件文件中的输入复制到这样的新设备中:

#!/usr/bin/env python3
import sys
import libevdev
import time

def print_capabilities(l):
    v = l.driver_version
    print("Input driver version is {}.{}.{}".format(v >> 16, (v >> 8) & 0xff, v & 0xff))
    id = l.id
    print("Input device ID: bus {:#x} vendor {:#x} product {:#x} version {:#x}".format(
        id["bustype"],
        id["vendor"],
        id["product"],
        id["version"],
    ))
    print("Input device name: {}".format(l.name))
    print("Supported events:")

    for t, cs in l.evbits.items():
        print("  Event type {} ({})".format(t.value, t.name))

        for c in cs:
            if t in [libevdev.EV_LED, libevdev.EV_SND, libevdev.EV_SW]:
                v = l.value[c]
                print("    Event code {} ({}) state {}".format(c.value, c.name, v))
            else:
                print("    Event code {} ({})".format(c.value, c.name))

            if t == libevdev.EV_ABS:
                a = l.absinfo[c]
                print("       {:10s} {:6d}".format('Value', a.value))
                print("       {:10s} {:6d}".format('Minimum', a.minimum))
                print("       {:10s} {:6d}".format('Maximum', a.maximum))
                print("       {:10s} {:6d}".format('Fuzz', a.fuzz))
                print("       {:10s} {:6d}".format('Flat', a.flat))
                print("       {:10s} {:6d}".format('Resolution', a.resolution))

    print("Properties:")
    for p in l.properties:
        print("  Property type {} ({})".format(p.value, p.name))


def print_event(e):
        print("Event: time {}.{:06d}, ".format(e.sec, e.usec), end='')
        if e.matches(libevdev.EV_SYN):
            if e.matches(libevdev.EV_SYN.SYN_MT_REPORT):
                print("++++++++++++++ {} ++++++++++++".format(e.code.name))
            elif e.matches(libevdev.EV_SYN.SYN_DROPPED):
                print(">>>>>>>>>>>>>> {} >>>>>>>>>>>>".format(e.code.name))
            else:
                print("-------------- {} ------------".format(e.code.name))
        else:
            print("type {:02x} {} code {:03x} {:20s} value {:4d}".format(e.type.value, e.type.name, e.code.value, e.code.name, e.value))


def main(args):
    path = args[1]
    dev = libevdev.Device()
    dev.name = "Combined Both Devices"
    dev.enable(libevdev.EV_ABS.ABS_X,
               libevdev.InputAbsInfo(minimum=0, maximum=32767))
    dev.enable(libevdev.EV_ABS.ABS_Y,
               libevdev.InputAbsInfo(minimum=0, maximum=32767))
    dev.enable(libevdev.EV_ABS.ABS_Z,
               libevdev.InputAbsInfo(minimum=0, maximum=8191))
    dev.enable(libevdev.EV_ABS.ABS_0B,
               libevdev.InputAbsInfo(minimum=0, maximum=8191))
    dev.enable(libevdev.EV_ABS.ABS_DISTANCE,
               libevdev.InputAbsInfo(minimum=0, maximum=8191))
    dev.enable(libevdev.EV_ABS.ABS_PRESSURE,
               libevdev.InputAbsInfo(minimum=0, maximum=8191))
    dev.enable(libevdev.EV_MSC.MSC_SCAN)
    dev.enable(libevdev.EV_KEY.BTN_LEFT)
    dev.enable(libevdev.EV_KEY.BTN_RIGHT)
    dev.enable(libevdev.EV_KEY.BTN_MIDDLE)
    dev.enable(libevdev.EV_KEY.BTN_TOUCH)
    dev.enable(libevdev.EV_SYN.SYN_REPORT)
    dev.enable(libevdev.EV_SYN.SYN_CONFIG)
    dev.enable(libevdev.EV_SYN.SYN_MT_REPORT)
    dev.enable(libevdev.EV_SYN.SYN_DROPPED)
    dev.enable(libevdev.EV_SYN.SYN_04)
    dev.enable(libevdev.EV_SYN.SYN_05)
    dev.enable(libevdev.EV_SYN.SYN_06)
    dev.enable(libevdev.EV_SYN.SYN_07)
    dev.enable(libevdev.EV_SYN.SYN_08)
    dev.enable(libevdev.EV_SYN.SYN_09)
    dev.enable(libevdev.EV_SYN.SYN_0A)
    dev.enable(libevdev.EV_SYN.SYN_0B)
    dev.enable(libevdev.EV_SYN.SYN_0C)
    dev.enable(libevdev.EV_SYN.SYN_0D)
    dev.enable(libevdev.EV_SYN.SYN_0E)
    dev.enable(libevdev.EV_SYN.SYN_MAX)
    try:
        uinput = dev.create_uinput_device()
        print("New device at {} ({})".format(uinput.devnode, uinput.syspath))
        # Sleep for a bit so udev, libinput, Xorg, Wayland, ...
        # all have had a chance to see the device and initialize
        # it. Otherwise the event will be sent by the kernel but
        # nothing is ready to listen to the device yet.
        time.sleep(1)

        with open(path, "rb") as fd:
            l = libevdev.Device(fd)
            print_capabilities(l)
            print("################################\n"
                  "#      Waiting for events      #\n"
                  "################################")
            while True:
                try:
                    ev = l.events()
                    for e in ev:
                        uinput.send_events([e])
                        print_event(e)
                        if e.matches(libevdev.EV_ABS.ABS_PRESSURE):
                            print("Pressure! Will send another packeton Z axis!")
                            uinput.send_events([libevdev.InputEvent(libevdev.EV_ABS.ABS_Z, e.value)])
                            uinput.send_events([libevdev.InputEvent(libevdev.EV_ABS.ABS_0B, e.value)])
                            uinput.send_events([libevdev.InputEvent(libevdev.EV_ABS.ABS_DISTANCE, e.value)])

                except libevdev.EventsDroppedException:
                    for e in l.sync():
                        print_event(e)
                        uinput.send_events([e])
    except KeyboardInterrupt:
        pass
    except IOError as e:
        import errno
        if e.errno == errno.EACCES:
            print("Insufficient permissions to access {}".format(path))
        elif e.errno == errno.ENOENT:
            print("Device {} does not exist".format(path))
        else:
            raise e
    except OSError as e:
        print(e)


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: {} /dev/input/eventX".format(sys.argv[0]))
        sys.exit(1)
    main(sys.argv)

我意识到它或多或少与 Veikk 鼠标相同,而且效果并不好。

tablet
  • 1 个回答
  • 4926 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve