AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 507687
Accepted
tobiasBora
tobiasBora
Asked: 2019-03-22 02:48:05 +0800 CST2019-03-22 02:48:05 +0800 CST 2019-03-22 02:48:05 +0800 CST

Tablet gráfico VEIKK: sensibilidade à pressão no Linux

  • 772

Acabei de comprar o tablet gráfico VEIKK A30. O mouse é reconhecido diretamente. Infelizmente, não consigo encontrar como habilitar a sensibilidade à pressão no Linux. Eu vi um cara relatando que com alguns ajustes foi possível fazer funcionar, mas não consigo encontrar nenhuma referência sobre isso.

Edit: aqui está a saída do 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

Exibição do Gimp: insira a descrição da imagem aqui

Edit2: hum, parece que o dispositivo que envia a pressão pode ser lido, sudo cat /dev/hidraw0pois os padrões diferem dependendo da pressão que aplico. Eu não sei como ler este binário ^^ Se eu puder, talvez eu possa usar uinput para mapeá-lo para um novo dispositivo? ^^ Observe que /dev/inputcontém arquivos como mouseX, eventY e mouse1 está correlacionado com o tablet, mas não com a pressão, e o único arquivo nesta pasta que exibe muitas informações vinculadas ao tablet é o arquivo /dev/input/by-id/usb-VEIKK.INC_A30_0000001-event-mouse. Mas é menos claro que os padrões correspondem à pressão, muitas informações são enviadas aqui. Se você souber como analisá-los me avise!

Edit3: Então eu ainda não tenho um driver, mas pelo menos parece ser fácil ler a entrada da comunicação bruta do dispositivo. Eu fiz este script python como uma prova de conceito:

#!/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)

Demonstração:

[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%)

Edit 4: Página incrível: https://digimend.github.io/support/howto/trbl/locating_failure/ No entanto, tudo funciona aqui ... exceto na última etapa, quando quero testá-lo. Tentei testar com o MyPaint, e não detecta pressão.

Eu também tentei fazer meu próprio código que basicamente copia a entrada do arquivo de evento para um novo dispositivo assim:

#!/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)

e percebi que é mais ou menos igual ao mouse Veikk, e não funciona melhor.

tablet
  • 1 1 respostas
  • 4926 Views

1 respostas

  • Voted
  1. Best Answer
    tobiasBora
    2019-03-27T05:45:44+08:002019-03-27T05:45:44+08:00

    Você!!! Consegui fazer um script python que me devolve a pressão em um novo dispositivo virtual :-D Agora posso usá-lo com Gimp/Krita/... A única parte restante a fazer é escrever um driver C adequado e carregá-lo diretamente no kernel... Se você tiver alguma idéia me avise!

    Prova:

    insira a descrição da imagem aqui

    Portanto, a idéia do script é ler a entrada do arquivo de eventos da mesa digitalizadora e, em seguida, criar os bons eventos (não mais BTN_LEFT, mas BTN_TOUCHem vez disso... veja minha outra pergunta/resposta aqui para mais detalhes).

    Para executar o script (veja abaixo), salve-o em combine_both.pye torne-o executável/instale deps:

    $ chmod +x combine_both.py
    $ sudo pip3 install libevdev
    

    Em seguida, confira os dispositivos de entrada disponíveis:

    $ xinput list
    

    Isso deve fornecer várias entradas, entre elas uma entrada como

    VEIKK.INC A30 Mouse                       id=12   [slave  pointer  (2)]
    

    Observe o id (anotado como <id veikk>mais adiante), bem como o id do ponteiro do núcleo virtual <id core>:

    Virtual core pointer                          id=2    [master pointer  (3)]
    

    Então, você precisa saber qual /dev/input/eventXarquivo escolher, o mais fácil é executar sudo evteste ler o nome do arquivo correspondente ao arquivo VEIKK.INC A30 Mouse. Em seguida, execute o script com este arquivo em argumento como em:

    sudo ./combine_both.py /dev/input/event7
    

    Este script deve produzir coisas quando você tentar clicar/mover no dispositivo. Além disso xinput list, também deve listar este dispositivo com o nome Tablet alone Pen (0)com um id <id fake tablet>e xinput test <id fake tablet>deve fornecer algo como (observe as 3 colunas para x/y/pressão):

    $ xinput test 21
    [...]
    motion a[0]=4151295 a[1]=4151295 a[2]=241 
    motion a[0]=4060671 a[1]=4060671 a[2]=226 
    motion a[0]=3969535 a[1]=3969535 a[2]=211 
    motion a[0]=3878399 a[1]=3878399 a[2]=196 
    motion a[0]=3787775 a[1]=3787775 a[2]=181 
    motion a[0]=3696639 a[1]=3696639 a[2]=166 
    motion a[0]=3605503 a[1]=3605503 a[2]=151 
    motion a[0]=3514879 a[1]=3514879 a[2]=137 
    motion a[0]=3423743 a[1]=3423743 a[2]=122 
    motion a[0]=3332607 a[1]=3332607 a[2]=107 
    motion a[0]=3241983 a[1]=3241983 a[2]=92 
    motion a[0]=3150847 a[1]=3150847 a[2]=77 
    motion a[0]=3059711 a[1]=3059711 a[2]=62 
    motion a[0]=2969087 a[1]=2969087 a[2]=47 
    motion a[0]=2877951 a[1]=2877951 a[2]=32 
    motion a[0]=2650623 a[1]=2650623 a[2]=17 
    button release 1
    

    Agora, para fazê-lo funcionar com o Gimp/Krita, você deseja desabilitar o mouse real (caso contrário, você terá conflitos entre o tablet real e o falso), com

    xinput float <id veikk>
    

    e quando terminar, você pode reconectar o dispositivo real com

    xinput reattach <id veikk> <id core>
    

    No gimp, não se esqueça de configurar Tablet alone Pen (0)com mode=screenin Edit/input devicese certifique-se de que o tablet real VEIKK.INC A30 Mouseesteja desabilitado. Por fim, escolhi uma boa dinâmica, gosto Pencil Genericde testar!

    Apreciar! (e eu vou deixar você saber se eu escrever o driver C em alguns pontos)

    Roteiro:

    #!/usr/bin/env python3
    import sys
    import libevdev
    import datetime
    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))
    
    
    class Tablet():
        def __init__(self, tablet_name):
            self.tablet_name = tablet_name
    
        def __enter__(self):
            self.dev = libevdev.Device()
            self.dev.name = "Tablet alone"
            ### NB: all the following information needs to be enabled
            ### in order to recognize the device as a tablet.
            # Say that the device will send "absolute" values
            self.dev.enable(libevdev.INPUT_PROP_DIRECT)
            # Say that we are using the pen (not the erasor), and should be set to 1 when we are at proximity to the device.
            # See http://www.infradead.org/~mchehab/kernel_docs_pdf/linux-input.pdf page 9 (=13) and guidelines page 12 (=16), or the https://github.com/linuxwacom/input-wacom/blob/master/4.5/wacom_w8001.c (rdy=proximity)
            self.dev.enable(libevdev.EV_KEY.BTN_TOOL_PEN)
            self.dev.enable(libevdev.EV_KEY.BTN_TOOL_RUBBER)
            # Click
            self.dev.enable(libevdev.EV_KEY.BTN_TOUCH)
            # Press button 1 on pen
            self.dev.enable(libevdev.EV_KEY.BTN_STYLUS)
            # Press button 2 on pen, see great doc
            self.dev.enable(libevdev.EV_KEY.BTN_STYLUS2)
            # Send absolute X coordinate
            self.dev.enable(libevdev.EV_ABS.ABS_X,
                            libevdev.InputAbsInfo(minimum=0, maximum=32767, resolution=100))
            # Send absolute Y coordinate
            self.dev.enable(libevdev.EV_ABS.ABS_Y,
                            libevdev.InputAbsInfo(minimum=0, maximum=32767, resolution=100))
            # Send absolute pressure
            self.dev.enable(libevdev.EV_ABS.ABS_PRESSURE,
                            libevdev.InputAbsInfo(minimum=0, maximum=8191))
            # Use to confirm that we finished to send the informations
            # (to be sent after every burst of information, otherwise
            # the kernel does not proceed the information)
            self.dev.enable(libevdev.EV_SYN.SYN_REPORT)
            # Report buffer overflow
            self.dev.enable(libevdev.EV_SYN.SYN_DROPPED)
            self.uinput = self.dev.create_uinput_device()
            print("New device at {} ({})".format(self.uinput.devnode, self.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. And it
            # will never be detected in the futur ;-)
            time.sleep(1)
            # self.simulate_first_click()
            self.reset_state()
            return self
    
        def __exit__(self, type, value, traceback):
            pass
    
        def reset_state(self):
            self.is_away = True
            self.is_touching = False
            self.pressed_button_1 = False
            self.pressed_button_2 = False
            self.lastmodif = datetime.datetime.now()
    
        def send_events(self, events, is_away=False):
            self.lastmodif = datetime.datetime.now()
            self.is_away = is_away
            self.uinput.send_events(events)
    
        def simulate_first_click(self):
            """Useful only the first time to make sure
            xinput detected the input"""
            # Reports that the PEN is close to the surface
            # Important to make sure xinput can detect (and list)
            # the pen. Otherwise, it won't write anything in gimp.
            self.uinput.send_events([
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
                                    value=0),
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
                                    value=1),
                libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                    value=0),
            ])
            # Says that the pen it out of range of the tablet. Useful
            # to make sure you can move your mouse, and to avoid
            # strange things during the first draw.
            self.uinput.send_events([
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
                                    value=0),
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
                                    value=0),
                libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                    value=0),
            ])
    
    
        def send_state_no_pos(self, is_away=False):
            self.lastmodif = datetime.datetime.now()
            self.is_away = is_away
            print("Away: {}, Touching: {}".format(self.is_away, self.is_touching))
            self.uinput.send_events([
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
                                    value=1 if self.is_touching else 0),
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
                                    value=1 if not self.is_away else 0),
                libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS,
                                    value=1 if self.pressed_button_1 else 0),
                libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS2,
                                    value=1 if self.pressed_button_2 else 0),
                libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                    value=0),
            ])
    
    
        def touch_press(self):
            self.is_touching = True
            self.send_state_no_pos()
    
        def touch_release(self):
            self.is_touching = False
            self.send_state_no_pos()
    
        def button_1_press(self):
            self.pressed_button_1 = True
            self.send_state_no_pos()
    
        def button_1_release(self):
            self.pressed_button_1 = False
            self.send_state_no_pos()
    
        def button_2_press(self):
            self.pressed_button_2 = True
            self.send_state_no_pos()
    
        def button_2_release(self):
            self.pressed_button_2 = False
            self.send_state_no_pos()
    
        def move_x(self, abs_x):
            self.send_events([
                libevdev.InputEvent(libevdev.EV_ABS.ABS_X,
                                    value=abs_x),
                libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                    value=0),
            ])
    
        def move_y(self, abs_y):
            self.send_events([
                libevdev.InputEvent(libevdev.EV_ABS.ABS_Y,
                                    value=abs_y),
                libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                    value=0),
            ])
    
        def change_pressure(self, pressure):
            self.send_events([
                libevdev.InputEvent(libevdev.EV_ABS.ABS_PRESSURE,
                                    value=pressure),
                libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                    value=0),
            ])
    
        def handle_event(self, e):
            if e.matches(libevdev.EV_ABS.ABS_PRESSURE):
                self.change_pressure(e.value)
            elif e.matches(libevdev.EV_ABS.ABS_X):
                self.move_x(e.value)
            elif e.matches(libevdev.EV_ABS.ABS_Y):
                self.move_y(e.value)
            elif e.matches(libevdev.EV_KEY.BTN_LEFT):
                if e.value == 1:
                    self.touch_press()
                else:
                    self.touch_release()
            elif e.matches(libevdev.EV_SYN.SYN_REPORT):
                pass
            else:
                print("Unkown event:")
                print_event(e)
    
    
    
    def main(args):
        path = args[1]
        try:
            with Tablet("Tablet alone") as tablet:
                ### Read the events from real graphics tablet
                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:
                                print_event(e)
                                tablet.handle_event(e)
                        except libevdev.EventsDroppedException:
                            for e in l.sync():
                                print_event(e)
                                tablet.handle_event(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: sudo {} /dev/input/eventX".format(sys.argv[0]))
            print(" $ sudo evtest")
            print("can help you to know which file to use.")
            sys.exit(1)
        main(sys.argv)
    
    • 3

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

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

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve