Puis-je empêcher Linux d'écouter un périphérique d'entrée USB comme un clavier, mais toujours capturer des événements avec un programme?

11

J'ai un lecteur de codes-barres USB sur /dev/input/event0( /dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd), et la numérisation d'un code-barres provoque l'envoi d'événements de pression de touche. Je capture ces touches à l'aide de la bibliothèque Libdevinput Ruby, qui fonctionne très bien. Le problème est que chaque code-barres est également entré en tant que nom d'utilisateur, puis mot de passe sur le Raspberry Pi, ce qui entraîne de nombreuses tentatives de connexion infructueuses. (Le Raspberry Pi sera sans tête et à l'intérieur d'un micro-ondes.)

Comment puis-je empêcher Linux de voir le scanner de codes-barres comme un périphérique d'entrée et que mon programme soit le seul consommateur d'événements? Ou existe-t-il une solution différente et meilleure?

ndbroadbent
la source
4
Je ne recommande pas de mettre l'électronique dans un micro-ondes. Certainement pas en cours d'exécution.
Ignacio Vazquez-Abrams
1
C'est certainement la partie la plus "wtf" de cette question.
Bratchley
1
Cage de Faraday pas chère? Peut-être qu'il y a beaucoup de RF dans la région.
charlesbridge
4
Hahaha, pas au micro-ondes. Tout se trouve derrière le PCB du contrôleur du micro-ondes, et je n'ai pas l'intention de cuisiner mon Raspberry Pi. J'ajoute un scanner de codes-barres pour les instructions de cuisson, ainsi qu'une commande vocale et un pavé tactile repensé.
ndbroadbent

Réponses:

6

J'ai découvert que je devais envoyer un ioctl EVIOCGRAB à l'appareil, qui le saisit pour un usage exclusif .

Voici comment le faire dans 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

Remarque : vous devrez installer les en- têtes libdevinputgem ffi, et Linux. Si vous utilisez une version Linux entre 3.2.0et 3.6.11, vous pouvez remplacer la FFI::ConstGeneratorpièce par EVIOCGRAB = 1074021776, puis vous n'avez pas besoin d'en ffi-têtes Linux.

ndbroadbent
la source
2

Cela ressemble quelque peu à ce problème , alors j'essaierais cette solution  : si je comprends bien votre problème, le scanner de code-barres devrait apparaître comme un pointeur esclave du "clavier virtuel" lorsque vous le faites.

xinput --list

Alors peut-être obtenir son ID et le forcer à flotter pourrait aider:

xinput float <id>
Skippy le Grand Gourou
la source
Je pense que OP les voit sur la console, pas sur X. Mais dans X, cela devrait fonctionner.
derobert
Ah, c'est vrai. De plus, il a déjà trouvé une solution…
Skippy le Grand Gourou