Στο παρόν οδηγό θα καταλάβουμε πως λειτουργεί το σύστημα κάτω από το καπάκι και τι συμβαίνει στον υπολογιστή όταν πατήσουμε κάποιο κουμπί στο πληκτρολόγιο ή κουνήσουμε το mouse. θα δούμε με εντολές τις ακριβώς συμβαίνει. Στο τέλος θα φτιάξουμε τον υπολογιστή έτσι ώστε να δουλεύει δυο mouse ανεξάρτητα το ένα από το άλλο.
libinput, evdev, xinput και udev
Με το hardware τον kernel και το linux να εξελίσσετε συνεχώς, οι παλιές μας γνώσεις θέλουν και αυτές αναβάθμιση. Θα προσπαθήσω αρχικά να περιγράψω (ελπίζω χωρίς πολλά λάθη) πως είναι διαμορφωμένο ένα μοντέρνο σύστημα Linux όσον αφορά τον χειρισμό των συσκευών εισόδου. Η πλήρης κάλυψη όλων αυτών απαιτεί πολλά άρθρα, και είναι δύσκολο να τα καλύψω όλα. Ελπίζω όμως να είναι ένας χρησιμός μπούσουλας.
1. kernel και evdev
O kernel έχει δύο κομμάτια τον οδηγό της συσκευής, και τον οδηγό παραγωγής γεγονότων (events). Ο οδηγός θα πάρει την είσοδο της συσκευής και θα την στείλει στο υποσύστημα evdev
που είναι κάποια αρχεία τις μορφής /dev/input/eventN
. (Δείτε τις μς την εντολή ls
)
Με το πρόγραμμα evtest
μπορούμε να δούμε αυτά τα γεγονότα. Αρχικά θα δούμε ποιες είναι οι συσκευές εισόδου.
cat /proc/bus/input/devices
και θα δούμε πολλά, αλλά ας εντοπίσουμε κάποιο mouse
I: Bus=0003 Vendor=0c45 Product=7e0a Version=0100
N: Name="Areson SPEEDLINK SCELUS"
P: Phys=usb-0000:00:12.0-2/input0
S: Sysfs=/devices/pci0000:00/0000:00:12.0/usb4/4-2/4-2:1.0/0003:0C45:7E0A.0001/input/input2
U: Uniq=
H: Handlers=mouse0 event2
B: PROP=0
B: EV=17
B: KEY=1f0000 0 0 0 0
B: REL=1943
B: MSC=10
Βλέπετε πως μιλάμε για το event2` ; Για να δούμε τι γεγονότα παράγει αυτή η πηγή με την εντολή
sudo evtest /dev/input/event2
και θα δούμε κάτι σαν το παρακάτω (με ControlC) την σταματάμε
Input device ID: bus 0x3 vendor 0xc45 product 0x7e0a version 0x100
Input device name: "Areson SPEEDLINK SCELUS"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 272 (BTN_LEFT)
Event code 273 (BTN_RIGHT)
Event code 274 (BTN_MIDDLE)
Event code 275 (BTN_SIDE)
Event code 276 (BTN_EXTRA)
Event type 2 (EV_REL)
Event code 0 (REL_X)
Event code 1 (REL_Y)
Event code 6 (REL_HWHEEL)
Event code 8 (REL_WHEEL)
Event code 11 (?)
Event code 12 (?)
Event type 4 (EV_MSC)
Event code 4 (MSC_SCAN)
Properties:
Testing ... (interrupt to exit)
Event: time 1567086747.726498, type 2 (EV_REL), code 0 (REL_X), value -2
Event: time 1567086747.726498, -------------- SYN_REPORT ------------
Event: time 1567086747.900510, type 2 (EV_REL), code 0 (REL_X), value 2
Ένας απλός τρόπος να δούμε αν όλα τα κουμπιά λειτουργούν. To ίδιο αρχείο θα το βρούμε με πολλά άλλα ονόματα. Οι παρακάτω εντολές είναι ισοδύναμες στο σύστημα μου.
sudo evtest /dev/input/by-id/usb-Areson_SPEEDLINK_SCELUS-event-mouse
sudo evtest /dev/input/by-path/pci-0000:00:12.0-usb-0:2:1.0-event-mouse
Για την πλάκα: αντικατέστησε την εντολή evtest
με την cat
Μπορούμε επίσης να βρούμε το αρχείο με την εντολή
sudo libinput list-devices
2. udev
Το υποσύστημα udev είναι αυτό που θα αναλάβει να φτιάξει αυτά τα αρχεία. Μόλις λάβει ένα σήμα πως συνδέθηκε μια συσκευή θα φτιάξει αυτά τα αρχεία, θα τους δώσει τα κατάλληλα δικαιώματα και θα κάνει μια πρώτη ρύθιση της συσκευής. Τα αρχεία ρυθμίσεων υπάρχουν στον φάκελο /lib/udev/rules.d/
και αν θέλουμε να τα πειράξουμε θα το κάνουμε στα αρχεία στο φάκελο /etc/udev/rules.d
. Αν θέλεις να τρέχει ένα πρόγραμμα κάθε φορά που θα συνδέεις μια συσκευή, ή αν δεν θέλεις κάποιος χρήσης να έχει πρόσβαση σε κάποια άλλη, τώρα ξέρεις τουλάχιστον που να κοιτάξεις.
3. libevdev και libinput
H χρήση απευθείας των συσκευών του kernel είναι δύσκολη και για αυτό φτιάχτηκε μια βιβλιοθήκη για να κάνει την χρήση τους ευκολότερη. Αυτή είναι η libevdev
. Μια άλλη βιβλιοθήκη ή libinput
την χρησιμοποεί για να δώσει αυτά τα γεγονότα στο γραφικό περιβάλλον (wayland ή Χ11).
Με την εντολή
sudo libinput debug-events
θα δούμε τα γεγονότα όπως τα βλέπε το libinput.
-event1 DEVICE_ADDED Power Button seat0 default group1 cap:k
-event0 DEVICE_ADDED Power Button seat0 default group2 cap:k
-event18 DEVICE_ADDED HDA NVidia HDMI/DP,pcm=3 seat0 default group3 cap:
-event19 DEVICE_ADDED HDA NVidia HDMI/DP,pcm=7 seat0 default group3 cap:
-event20 DEVICE_ADDED HDA NVidia HDMI/DP,pcm=8 seat0 default group3 cap:
-event2 DEVICE_ADDED Areson SPEEDLINK SCELUS seat0 default group4 cap:p left scroll-nat scroll-button
-event3 DEVICE_ADDED Areson SPEEDLINK SCELUS seat0 default group4 cap:k
-event6 DEVICE_ADDED Areson SPEEDLINK SCELUS Consumer Control seat0 default group4 cap:kp scroll-nat
-event7 DEVICE_ADDED HID 0430:0005 seat0 default group5 cap:k
-event10 DEVICE_ADDED HDA ATI SB Front Mic seat0 default group3 cap:
-event11 DEVICE_ADDED HDA ATI SB Rear Mic seat0 default group3 cap:
-event12 DEVICE_ADDED HDA ATI SB Line seat0 default group3 cap:
-event13 DEVICE_ADDED HDA ATI SB Line Out Front seat0 default group3 cap:
-event14 DEVICE_ADDED HDA ATI SB Line Out Surround seat0 default group3 cap:
-event15 DEVICE_ADDED HDA ATI SB Line Out CLFE seat0 default group3 cap:
-event16 DEVICE_ADDED HDA ATI SB Line Out Side seat0 default group3 cap:
-event17 DEVICE_ADDED HDA ATI SB Front Headphone seat0 default group3 cap:
-event9 DEVICE_ADDED Logitech K330 seat0 default group6 cap:kp scroll-nat
-event8 DEVICE_ADDED Logitech M585/M590 seat0 default group7 cap:kp left scroll-nat scroll-button
-event7 KEYBOARD_KEY +7.62s *** (-1) pressed
event7 KEYBOARD_KEY +7.66s *** (-1) released
event7 KEYBOARD_KEY +8.86s *** (-1) pressed
event7 KEYBOARD_KEY +9.11s *** (-1) pressed
4. Χ11 και Wayland
Το Χ11 θα την χρησιμοποιήσει μέσα από το υποσύστημα του xf86-input-libinput
. Πριν λίγα χρόνια μιλούσε άμεσα με το libinput
μέσα από το xf86-input-evdev
και κάποιοι χρησιμοποιούν αυτό ακόμα. Δες και εδώ.
H ροή των γεγονότων δείχνετε στο σχήμα :
Στο Χ11 τα πράγματα είναι ποιο πολύπλοκα, μιας και ο κώδικας του έχει πολύ παρελθόν, και πρέπει και να υποστηρίζει και άλλα λειτουργικά που δεν έχουν το evdev
με το synaptic
για το touchpad να έχει ακόμα χρήση σε κάποιες περιπτώσεις. Είχε δημιουγηθεί πριν τα wacom tablets
που δίνουν πιέσεις μεταξύ άλλων, δεν έχει άμεση υποστήριξη για joysticks
, multitouch
και gestures
πράγματα που προστέθηκαν αργότερα. Στην βάση του έχει υποστήριξη μόνο για ένα mouse και ένα πληκτρολόγιο και αν έχεις πολλά τα ενοποιεί όπως θα δούμε σε μια εικονική συσκευή.
Ευτυχώς για μας, μια μοντέρνα διανομή τα έχει όλα αυτά πολύ καλά ρυθμισμένα, και σπάνια θα πρέπει να τα σκαλίσουμε εμείς με το χέρι. Κάθε “σωστό” γραφικό περιβάλλον θα έχει κάποια γραφικά εργαλεία για να ρυθμίσουμε με ευκολία το mouse το πληκτρολόγιο και την ταμπλέτα.
Αρκετά με την θεωρία ας δούμε πώς μπορούμε να κάνουμε κάποια cool πράγματα ρυθμίζοντας το libinput. Σε άλλο άρθρο θα δούμε πως να κάνουμε ποιο χρήσιμα πράγματα.
Για τις συσκευές και την ιεραρχία τους
Ας δούμε πρώτα τι πληκτρολόγια και mouse έχουμε με την εντολή xinput list
σε ένα τερματικό . Θα δούμε κάτι σαν το παρακάτω.
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Areson SPEEDLINK SCELUS id=8 [slave pointer (2)]
⎜ ↳ Areson SPEEDLINK SCELUS Consumer Control id=10 [slave pointer (2)]
⎜ ↳ Logitech K330 id=12 [slave pointer (2)]
⎜ ↳ Logitech M585/M590 id=13 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Power Button id=7 [slave keyboard (3)]
↳ Areson SPEEDLINK SCELUS id=9 [slave keyboard (3)]
↳ HID 0430:0005 id=11 [slave keyboard (3)]
↳ Areson SPEEDLINK SCELUS Consumer Control id=14 [slave keyboard (3)]
↳ Logitech K330 id=15 [slave keyboard (3)]
↳ Logitech M585/M590 id=16 [slave keyboard (3)]
Το σύστημα βλέπει πολλές συσκευές σίγουρα πολύ περισσότερες από αυτές που νομίζατε πως είχατε, και τις ομαδοποιείς κάτω από δυο εικονικές συσκευές. Ένα εικονικό ποντίκι το Virtual core pointer
και ένα εικονικό πληκτρολόγιο το Virtual core keyboard
. Γιατί τόσες πολλές; Ένα ποντίκι μπορεί να έχει δυνατότητα μακροεντολών, ένα πληκτρολόγιο ένα ενσωματωμένο touchpad κλπ
Κάθε συσκευή είτε πραγματική είτε εικονική έχει ένα μοναδικό αριθμό id. Για να ρυθμίσω μια συσκευή θα πρέπει να χρησιμοποιήσω είτε τον αριθμό τής (που όμως τίποτα δεν μας εγγυάται πως θα είναι πάντα ο ίδιος) είτε το όνομα της. Στην δεύτερη περίπτωση πρέπει να πω αν θέλω το "πληκτρολόγιο¨ ή το “mouse” μιας συσκευής. Για παράδειγμα ’'keyboard:Logitech K330'
ή 'pointer:Logitech K330'
.
Πειράζοντας την ιεραρχία
Ας ξεκινήσουμε με κάτι που σίγουρα θα σας τραβήξει το ενδιαφέρον. Ή που μπορεί να κολλήσει το γραφικό περιβάλλον, οπότε και πάλι θα σας τραβήξει ελπίζω το ενδιαφέρον λίγο περισσότερο . Σε αυτήν την περίπτωση το ControlAlt←BS καλό είναι να είναι ενεργό σαν δυνατότητα.
Αν έχεις δυο οθόνες, και διπλά mouse και πληκτρολόγια, μπορείς να δώσεις το ένα mouse σε ένα φίλο να κάνει ότι θέλει στην δεύτερη οθόνη, χωρίς να σε απασχολεί. Η λύση αυτή δεν κάνει τον υπολογιστή multiseat, δηλαδή να είναι οι δύο οθόνες ανεξάρτητες με την μια να τρέχει cinnamon και την άλλη mate, με διαφορετικούς χρήστες στην κάθε μια, κάτι που είναι δυνατόν. Αλλά έστω και έτσι παραμένει χρήσιμη. Το τελευταίο cinnamon παθαίνει κάποιες φορές την πλάκα του, κάτι καλύτερο από παλιά που απλά κατέρεε, αλλά στο enligtment δουλεύει μια χαρά. Σε άλλα γραφικά περιβάλλοντα δεν το έχω δοκιμάσει, οπότε πείτε στα σχόλια.
Για να το κάνω αυτό θα δώσω τις παρακάτω εντολές
xinput create-master secondary
xinput reattach 'pointer:Logitech M585/M590' 'secondary pointer'
xinput reattach 12 17
Δείχνω και τους δύο τρόπους. Νέα ιεραρχία που θα προκύψει είναι η παρακάτω
Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Areson SPEEDLINK SCELUS id=8 [slave pointer (2)]
⎜ ↳ Areson SPEEDLINK SCELUS Consumer Control id=10 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Power Button id=7 [slave keyboard (3)]
↳ Areson SPEEDLINK SCELUS id=9 [slave keyboard (3)]
↳ HID 0430:0005 id=11 [slave keyboard (3)]
↳ Areson SPEEDLINK SCELUS Consumer Control id=14 [slave keyboard (3)]
↳ Logitech K330 id=15 [slave keyboard (3)]
↳ Logitech M585/M590 id=16 [slave keyboard (3)]
⎡ secondary pointer id=17 [master pointer (18)]
⎜ ↳ Logitech K330 id=12 [slave pointer (17)]
⎜ ↳ Logitech M585/M590 id=13 [slave pointer (17)]
⎜ ↳ secondary XTEST pointer id=19 [slave pointer (17)]
⎣ secondary keyboard id=18 [master keyboard (17)]
↳ secondary XTEST keyboard id=20 [slave keyboard (18)]
Πλέον (αν το περιβάλλον το υποστηρίζει) έχεις δύο διαφορετικά ποντίκια. Μπορείς να το δοκιμάσεις να παίξεις διπλό στο αγαπημένο σου παιγνίδι.