タッチパッドの絶対座標を取得するにはどうすればいいですか

タッチパッドの絶対座標を取得するにはどうすればいいですか

私の理解では、Ubuntu の Synaptic ドライバーの以前のバージョンには、トラックパッドの「絶対モード」があり、ユーザーは相対座標だけでなく絶対座標にもアクセスできました。しかし、Synaptic はそれを削除することを決定し (理由は不明)、現在は利用できません。Ubuntu 20.04 LTS で絶対モードにアクセスする方法はありますか? C/C++ プログラムでこれらの座標を取得できるようにしたいのですが、他のソリューション (Rust、シェル スクリプトなど、機能するもの) があれば教えてください。同様の投稿に遭遇しましたが、まだ満足のいく解決策を見つけることができません。ほとんどの人が、絶対モードを備えているものの、他の機能 (2 本指スクロールなど) が欠けている 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座標であるべきです。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 でのみ機能します。wayland(gnome) では、これにより 2 つのカーソルが取得されます。1 つは絶対カーソル、もう 1 つは相対カーソルで、それらの間をジャンプします...


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

関連情報