Kann ich Linux daran hindern, ein USB-Eingabegerät als Tastatur anzuhören, aber dennoch Ereignisse mit einem Programm erfassen?

11

Ich habe einen USB-Barcode-Scanner unter /dev/input/event0( /dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd), und beim Scannen eines Barcodes werden Tastendruckereignisse gesendet. Ich nehme diese Tastendrücke mit der libdevinput Ruby-Bibliothek auf, die hervorragend funktioniert. Das Problem ist, dass jeder Barcode auch als Benutzername und anschließend als Passwort auf dem Raspberry Pi eingegeben wird, was zu vielen fehlgeschlagenen Anmeldeversuchen führt. (Der Raspberry Pi ist kopflos und befindet sich in einer Mikrowelle.)

Wie kann ich verhindern, dass Linux den Barcode-Scanner als Eingabegerät sieht, und mein Programm ist der einzige Event-Konsument? Oder gibt es eine andere, bessere Lösung?

ndbroadbent
quelle
4
Ich empfehle nicht, Elektronik in eine Mikrowelle zu stellen. Mit Sicherheit kein laufender.
Ignacio Vazquez-Abrams
1
Das ist definitiv der "wtf" Teil dieser Frage.
Bratchley
1
Günstiger Faradayscher Käfig? Vielleicht gibt es viel RF in der Gegend.
Charles Bridge
4
Hahaha, nicht in der Mikrowelle. Alles befindet sich hinter der Controller-Platine der Mikrowelle, und ich habe nicht vor, meinen Raspberry Pi zu kochen. Ich füge einen Barcode-Scanner für Kochanweisungen sowie Sprachsteuerung und ein neu gestaltetes Touchpad hinzu.
ndbroadbent

Antworten:

6

Ich habe herausgefunden, dass ich ein EVIOCGRAB ioctl an das Gerät senden muss, das es zur ausschließlichen Verwendung abruft .

So geht's in 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

Hinweis : Sie müssen die libdevinputgem- ffiund Linux-Header installieren . Wenn Sie eine Linux-Version zwischen 3.2.0und verwenden 3.6.11, können Sie das FFI::ConstGeneratorTeil durch ersetzen EVIOCGRAB = 1074021776, und dann benötigen Sie keine ffiLinux-Header.

ndbroadbent
quelle
2

Klingt irgendwie ähnlich wie dieses Problem , daher würde ich diese Lösung ausprobieren  : Wenn ich Ihr Problem richtig verstehe, sollte der Barcode-Scanner in diesem Fall als Slave-Zeiger auf "Virtual Core Keyboard" angezeigt werden

xinput --list

Dann könnte es vielleicht helfen, seine ID zu erhalten und sie zum Schweben zu zwingen:

xinput float <id>
Skippy le Grand Gourou
quelle
Ich denke, OP sieht diese auf der Konsole, nicht auf X. Aber in X sollte dies funktionieren.
Derobert
Ah richtig. Außerdem hat er bereits eine Lösung gefunden…
Skippy le Grand Gourou