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 timestamp
y code
, pero val
deberí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 event
es 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);