Czy mogę powstrzymać Linuksa przed słuchaniem urządzenia wejściowego USB jako klawiatury, ale nadal przechwytywać zdarzenia za pomocą programu?


11

Mam skaner kodów kreskowych USB w /dev/input/event0( /dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd), a zeskanowanie kodu kreskowego powoduje wysłanie zdarzenia naciśnięcia klawisza. Rejestruję te naciśnięcia klawiszy za pomocą biblioteki Ruby libdevinput , która działa świetnie. Problem polega na tym, że każdy kod kreskowy jest również wprowadzany jako nazwa użytkownika, a następnie hasło do Raspberry Pi, co powoduje wiele nieudanych prób logowania. (Raspberry Pi będzie bezgłowy i będzie w kuchence mikrofalowej.)

Jak mogę powstrzymać Linuksa przed postrzeganiem skanera kodów kreskowych jako urządzenia wejściowego i pozwolić, aby mój program był jedynym konsumentem zdarzeń? A może istnieje inne, lepsze rozwiązanie?


4
Nie polecam wkładania elektroniki do kuchenki mikrofalowej. Na pewno nie działa.
Ignacio Vazquez-Abrams

1
To zdecydowanie najbardziej „wtf” część tego pytania.
Bratchley

1
Tania klatka Faradaya? Może w okolicy jest dużo RF.
charlesbridge

4
Hahaha, nie w kuchence mikrofalowej. Wszystko znajduje się za płytką kontrolną kuchenki mikrofalowej i nie zamierzam gotować mojego Raspberry Pi. Dodaję skaner kodów kreskowych do instrukcji gotowania, a także sterowanie głosowe i przeprojektowany panel dotykowy.
ndbroadbent

Odpowiedzi:


6

Dowiedziałem się, że muszę wysłać ioctl EVIOCGRAB do urządzenia, które pobiera je do wyłącznego użytku .

Oto jak to zrobić w Ruby:

#!/usr/bin/env ruby
BARCODE_SCANNER = "/dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd"

require 'rubygems'
require 'libdevinput'
require 'ffi'
require 'ffi/tools/const_generator'

# We need access to the file
DevInput.class_eval { attr_reader :dev }

# Look up value of EVIOCGRAB constant
cg = FFI::ConstGenerator.new('input') do |gen|
  gen.include('linux/input.h')
  gen.const(:EVIOCGRAB, '%u', '(unsigned)')
end
EVIOCGRAB = cg['EVIOCGRAB'].to_i

scanner = DevInput.new(BARCODE_SCANNER)
# Send EVIOCGRAB to scanner, which grabs it for exclusive use by our process
scanner.dev.ioctl(EVIOCGRAB, 1)


puts "Waiting for events..."
scanner.each do |event|
  # Ignore everything except key press events
  next unless event.type == 1 && event.value == 1
  puts "Key: #{event.code_str}"
end

Uwaga : musisz zainstalować nagłówki libdevinputgem ffii Linux. Jeśli używasz wersji Linux między 3.2.0i 3.6.11, możesz zamienić FFI::ConstGeneratorczęść na EVIOCGRAB = 1074021776, a następnie nie potrzebujesz ffinagłówków Linux.


2

Brzmi trochę podobnie do tego problemu , więc wypróbuję to rozwiązanie  : jeśli dobrze rozumiem twój problem, skaner kodów kreskowych powinien pojawić się jako wskaźnik slave „Wirtualnej klawiatury rdzenia”, kiedy to zrobisz

xinput --list

Wtedy może uzyskanie jego identyfikatora i zmuszenie go do unoszenia się na wodzie może pomóc:

xinput float <id>

Myślę, że OP widzi je na konsoli, a nie X. Ale w X to powinno działać.
derobert

Ah, tak. Dodatkowo znalazł już rozwiązanie…
Skippy le Grand Gourou
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.