¿Cómo puedo obtener las coordenadas absolutas del panel táctil?

¿Cómo puedo obtener las coordenadas absolutas del panel táctil?

Por lo que tengo entendido, las versiones anteriores del controlador Synaptic en Ubuntu tenían un 'modo absoluto' para el trackpad que permitía al usuario acceder a coordenadas absolutas y relativas. Sin embargo, Synaptic decidió eliminarlo (no estoy seguro de por qué) y ya no está disponible. ¿Hay alguna forma de acceder al modo absoluto en Ubuntu 20.04 LTS? Me gustaría poder obtener estas coordenadas en un programa C/C++ pero abierto a cualquier otra solución (Rust, script de shell, lo que sea que funcione). Me encontré con publicaciones similares pero todavía no puedo encontrar una solución satisfactoria. La mayoría recomienda el controlador evtest que tiene modo absoluto pero carece de otras funciones (desplazamiento con 2 dedos, etc.). Estoy pensando que volver a una versión anterior del controlador Synaptic podría ayudar, pero quería saber qué me estaría perdiendo. Quiero decir, ¿hay alguna característica importante en el controlador Synaptic más reciente que el anterior con modo absoluto no tenga?

Editar: investigué un poco más y encontré esta página -->http://manpages.ubuntu.com/manpages/bionic/man1/python-evdev.1.html

Muestra cómo usar una biblioteca de Python, evdev, y cómo usarla para acceder a eventos de entrada del sistema. Siguiendo los ejemplos, lo configuré para que observara los eventos de mi trackpad y al mover el dedo obtuve una gran cantidad de información que desafortunadamente no entendí. Noté términos como ABS_X, ABS_Y pero no pude entender nada. De todos modos, parece que puedo acceder a mucha información del trackpad a través de esta biblioteca, incluido algo relacionado con las coordenadas absolutas. ¿Cómo uso esta información? ¿Alguien puede mostrarme cómo escribir una función simple de Python usando evdev?

def foo():
    ...
    return (x,y)

¿Dónde (x,y) representa la posición de mi dedo en el trackpad?

Edición 2: salida de muestra de evdev monitoreando mi trackpad. ¿Se puede usar algo de esto para obtener coordenadas absolutas?

absolute axis event at 1623586006.216310, ABS_MT_TRACKING_ID 
absolute axis event at 1623586006.216310, ABS_MT_POSITION_X 
absolute axis event at 1623586006.216310, ABS_MT_POSITION_Y 
absolute axis event at 1623586006.216310, ABS_MT_PRESSURE 
key event at 1623586006.216310, 330 (BTN_TOUCH), down
absolute axis event at 1623586006.216310, ABS_X 
absolute axis event at 1623586006.216310, ABS_Y 
absolute axis event at 1623586006.216310, ABS_PRESSURE 
key event at 1623586006.216310, 325 (BTN_TOOL_FINGER), down
synchronization event at 1623586006.216310, SYN_REPORT 
absolute axis event at 1623586006.231209, ABS_MT_PRESSURE 
absolute axis event at 1623586006.231209, ABS_PRESSURE

Respuesta1

Usar

    >>> print(event)
    event at 1337197425.477827, code 04, type 04, val 458792

En este momento genera timestampy code, pero valdebería ser su coordenada, consultehttps://python-evdev.readthedocs.io/en/latest/_modules/evdev/events.html.

Respuesta2

Disculpa por la respuesta tardía. Espero que esto siga siendo al menos algo útil. De todos modos, he estado tratando de resolver esto. Lo más probable es que, si siguió el "tutorial" del enlace que publicó, tenga print(evdev.categorize(event))algo parecido.

Ahora no tengo idea de qué hace categorizar, pero deshacerme de la función de categorizar parece imprimir lo que estás buscando; posición xey sin procesar.

from evdev import InputDevice

device = InputDevice('/dev/input/event8')

for event in device.read_loop():
    print(event)

La salida de eventes así:

event at 1664686111.342840, code 53, type 03, val 1097
event at 1664686111.342840, code 54, type 03, val 736
event at 1664686111.342840, code 00, type 03, val 1097
event at 1664686111.342840, code 01, type 03, val 736
event at 1664686111.342840, code 05, type 04, val 201000

Parece que los códigos 53 y 54 contienen los datos correctos. Al menos para mí. Sin embargo, es posible que tengas que hacer algunas deducciones para descubrirlo por ti mismo. Y no tengo idea si su panel táctil funciona de la misma manera en evdev que para mí, por lo que es posible que esto ni siquiera funcione.

Se me ocurrirá un código muy rápido para que puedas copiarlo y pegarlo:

from evdev import InputDevice
#SET THIS TO YOUR DEVICE
device = InputDevice('/dev/input/event8')

x = 0
y = 0

def get_xy_coords(e):
    #you may need to change this number here; i don't know
    if e.code == 53:
        global x
        x = e.value
    #this one too
    if e.code == 54:
        global y
        y = e.value
        

for event in device.read_loop():
    get_xy_coords(event)

Aquí. Este código exacto establecerá xey en sus respectivas coordenadas en cada ciclo de lectura. Espero poder ayudar, a pesar de publicar esto un año después.

Respuesta3

Basado en la respuesta de @Greyson Phipps, creé un script simple para hacer que el panel táctil se comporte como una tableta gráfica. https://github.com/Vaisakhkm2625/touchpaddraw

No es ideal, ya que no soy principalmente un desarrollador de Python y esta es una solución complicada, pero funciona. funciona solo en xorg.in wayland (gnome), esto obtiene 2 cursores, uno con absoluto y otro con relativo y jumbs entre ellos...


import math
import os
import time

#get trackpad absolute coords
from evdev import InputDevice
 
import argparse
 
from pynput import mouse
from pynput.mouse import Button
 
# Initialize parser
parser = argparse.ArgumentParser()
 
# Adding optional argument
parser.add_argument("-d", "--device", help = "device (event*)")
 
# Read arguments from command line
args = parser.parse_args()

#SET THIS TO YOUR DEVICE
device = InputDevice('/dev/input/'+ args.device if args.device else 'event7')

touchpad_x_max = 1224
touchpad_y_max = 804

max_x = 1920
max_y = 1080

x = 0
y = 0

def get_xy_coords(e):
    #you may need to change this number here; i don't know
    if e.code == 53:
        global x
        x = e.value
    #this one too
    if e.code == 54:
        global y
        y = e.value
        
def mapFromTo(x,a,b,c,d):
   # y=(x-a)//(b-a)*(d-c)+c
   y=(x-a)/(b-a)*(d-c)+c
   return y

x_pos =0
y_pos =0

mouse_controller = mouse.Controller()
for event in device.read_loop():
    #rows, cols = stdscr.getmaxyx()
    get_xy_coords(event)
    if event.code == 54:
        prev_x_pos = x_pos 
        prev_y_pos = y_pos 
        x_pos =math.floor(mapFromTo(x,0,touchpad_x_max,0,max_x))
        y_pos =math.floor(mapFromTo(y,0,touchpad_y_max,0,max_y))
        if (abs(prev_x_pos-x_pos)>15 or abs(prev_y_pos-y_pos)>15):
            mouse_controller.release(Button.left)
            mouse_controller.position = (x_pos,y_pos);
        mouse_controller.press(Button.left)
        mouse_controller.position = (x_pos,y_pos);

información relacionada