절대 터치패드 좌표를 얻으려면 어떻게 해야 합니까?

절대 터치패드 좌표를 얻으려면 어떻게 해야 합니까?

내가 이해한 바로는 Ubuntu의 이전 버전의 Synaptic 드라이버에는 트랙패드에 대한 '절대 모드'가 있어 사용자가 절대 좌표와 상대 좌표에 액세스할 수 있었습니다. 그러나 Synaptic은 이를 제거하기로 결정했으며(이유는 확실하지 않음) 더 이상 사용할 수 없습니다. Ubuntu 20.04 LTS에서 절대 모드에 액세스할 수 있는 방법이 있습니까? 나는 C/C++ 프로그램에서 이러한 좌표를 얻을 수 있지만 다른 솔루션(Rust, 쉘 스크립트 등 작동하는 모든 것)에 열려 있기를 원합니다. 비슷한 게시물을 봤지만 여전히 만족스러운 해결책을 찾을 수 없습니다. 대부분은 절대 모드를 사용하지만 다른 기능(두 손가락 스크롤 등)이 부족한 evtest 드라이버를 권장합니다. 이전 버전의 Synaptic 드라이버로 되돌리는 것이 도움이 될 것이라고 생각하지만, 제가 놓치고 있는 것이 무엇인지 알고 싶었습니다. 즉, 최신 Synaptic 드라이버에는 절대 모드의 이전 드라이버에는 없는 중요한 기능이 있습니까?

편집: 조금 더 조사한 결과 이 ​​페이지를 발견했습니다 -->http://manpages.ubuntu.com/manpages/bionic/man1/python-evdev.1.html

Python 라이브러리인 evdev를 사용하는 방법과 이를 사용하여 시스템 입력 이벤트에 액세스하는 방법을 보여줍니다. 예제에 따라 트랙패드 이벤트를 보도록 설정했는데 손가락을 움직이자 불행하게도 이해할 수 없는 정보의 벽 전체가 표시되었습니다. ABS_X, ABS_Y와 같은 용어를 발견했지만 아무 것도 만들 수 없었습니다. 그럼에도 불구하고 이 라이브러리를 통해 절대 좌표와 관련된 정보를 포함하여 많은 트랙패드 정보에 액세스할 수 있는 것 같습니다. 이 정보를 어떻게 사용합니까? 누구든지 evdev를 사용하여 간단한 Python 함수를 작성하는 방법을 보여줄 수 있습니까?

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

(x,y)는 트랙패드에서 내 손가락 위치를 나타냅니다.

편집 2: 내 트랙패드를 모니터링하는 evdev의 샘플 출력입니다. 절대 좌표를 얻는 데 이 중 하나를 사용할 수 있습니까?

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

답변1

사용

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

지금은 timestamp및 를 출력 code하지만 val좌표가 되어야 합니다.https://python-evdev.readthedocs.io/en/latest/_modules/evdev/events.html.

답변2

늦은 답변 죄송합니다. 이것이 여전히 어느 정도 도움이 되기를 바랍니다. 어쨌든, 나는 이것을 알아 내려고 노력해 왔습니다. 게시한 링크의 "튜토리얼"을 따랐다면 아마도 print(evdev.categorize(event))비슷한 내용을 갖게 될 것입니다.

이제 나는 categorize가 무엇을 하는지는 모르지만 categorize 기능을 제거하면 당신이 찾고 있는 것을 인쇄하는 것 같습니다. 원시 x 및 y 위치.

from evdev import InputDevice

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

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

출력은 event다음과 같습니다.

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

코드 53과 54에 올바른 데이터가 포함되어 있는 것 같습니다. 적어도 나에게는. 하지만 스스로 알아내려면 몇 가지 추론을 해야 할 수도 있습니다. 그리고 귀하의 터치패드가 저와 마찬가지로 evdev에서도 동일한 방식으로 작동하는지 전혀 알 수 없으므로 이것이 작동하지 않을 수도 있습니다.

복사하여 붙여넣을 수 있는 몇 가지 코드를 빠르게 만들어 보겠습니다.

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)

여기. 이 정확한 코드는 모든 읽기 루프마다 x와 y를 각각의 좌표로 설정합니다. 1년 뒤에 이 글을 게시했음에도 불구하고 도움이 되었으면 좋겠습니다.

답변3

@Greyson Phipps 답변을 바탕으로 터치패드가 드로잉 태블릿처럼 작동하도록 하는 간단한 스크립트를 만들었습니다. https://github.com/Vaisakhkm2625/touchpaddraw

나는 주로 Python 개발자가 아니고 이것은 해키 솔루션이지만 작동하기 때문에 이상적이지는 않습니다. xorg.in wayland(gnome)에서만 작동합니다. 커서는 2개입니다. 하나는 절대 커서이고 다른 하나는 상대 커서와 그 사이의 점입니다....


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);

관련 정보