Могу ли я остановить Linux от прослушивания USB-устройства ввода в качестве клавиатуры, но при этом сохранять события с помощью программы?

11

У меня есть сканер штрих-кода USB в /dev/input/event0( /dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd), и сканирование штрих-кода заставляет его отправлять события нажатия клавиш. Я фиксирую эти нажатия клавиш с помощью библиотеки Ruby libdevinput , которая прекрасно работает. Проблема заключается в том, что каждый штрих-код также вводится как имя пользователя, а затем пароль на Raspberry Pi, что вызывает множество неудачных попыток входа в систему. (Raspberry Pi будет без головы и внутри микроволновки.)

Как я могу запретить Linux видеть сканер штрих-кода в качестве устройства ввода, и чтобы моя программа была единственным потребителем событий? Или есть другое, лучшее решение?

ndbroadbent
источник
4
Я не рекомендую класть электронику в микроволновку. Конечно, не работает.
Игнасио Васкес-Абрамс
1
Это, безусловно, самая «веская» часть этого вопроса.
Братчли
1
Дешевая клетка Фарадея? Может быть, в этом районе много РФ.
Чарльзбридж
4
Хахаха, не в микроволновке. Все находится за печатной платой контроллера микроволновой печи, и я не собираюсь готовить мой Raspberry Pi. Я добавляю сканер штрих-кода для инструкций по приготовлению пищи, а также голосовое управление и переработанную сенсорную панель.
ndbroadbent

Ответы:

6

Я обнаружил, что мне нужно отправить EVIOCGRAB ioctl на устройство, которое захватывает его для эксклюзивного использования .

Вот как это сделать в 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

Примечание : вам нужно установить libdevinputгем ffiи заголовки Linux. Если вы используете версию Linux между 3.2.0и 3.6.11, вы можете заменить FFI::ConstGeneratorдеталь на EVIOCGRAB = 1074021776, и тогда вам не нужны ffiзаголовки Linux или.

ndbroadbent
источник
2

Звучит как-то похоже на эту проблему , поэтому я бы попробовал это решение  : если я правильно понимаю вашу проблему, сканер штрих-кода должен появиться как ведомый указатель «Виртуальная клавиатура ядра», когда вы делаете

xinput --list

Тогда, возможно, получение его идентификатора и принудительное плавание может помочь:

xinput float <id>
Скиппи ле Гран Гуру
источник
Я думаю, что OP видит их на консоли, а не X. Но в X это должно работать.
Дероберт
Ах, верно. Кроме того, он уже нашел решение ...
Skippy le Grand Gourou