Posso impedir que o Linux ouça um dispositivo de entrada USB como um teclado, mas ainda capturar eventos com um programa?

10

Eu tenho um scanner de código de barras USB em /dev/input/event0 ( /dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd ), e a digitalização de um código de barras faz com que ele envie eventos de pressionamento de tecla. Estou capturando esses keypresses usando a biblioteca Ruby do libdevinput , que funciona muito bem. A questão é que cada código de barras também é inserido como um nome de usuário e, subsequentemente, uma senha no Raspberry Pi, causando muitas tentativas de login com falha. (O Raspberry Pi ficará sem cabeça e dentro de um microondas.)

Como posso impedir que o Linux veja o leitor de código de barras como um dispositivo de entrada e que meu programa seja o único consumidor de eventos? Ou existe uma solução diferente e melhor?

    
por ndbroadbent 31.05.2013 / 13:18

2 respostas

6

Descobri que preciso enviar um ioctl EVIOCGRAB para o dispositivo, que o coleta para uso exclusivo .

Veja como fazer isso em 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

Observação : você precisará instalar os cabeçalhos libdevinput gem, ffi e Linux. Se você estiver usando uma versão do Linux entre 3.2.0 e 3.6.11 , poderá substituir a FFI::ConstGenerator por EVIOCGRAB = 1074021776 e, em seguida, você não precisará de ffi ou cabeçalhos do Linux.

    
por 01.06.2013 / 07:17
2

Soa de alguma forma semelhante a problema , então eu tentaria esta solução : se eu entendi corretamente o seu problema, o scanner de código de barras deve aparecer como um ponteiro escravo do "Virtual core keyboard" quando você faz

xinput --list

Então, talvez receber sua identificação e forçá-la a flutuar pode ajudar:

xinput float <id>
    
por 04.10.2013 / 15:54