web-dev-qa-db-ja.com

Linuxがキーボード入力としてUSB入力デバイスをリッスンするのを止めても、プログラムでイベントをキャプチャできますか?

USBバーコードスキャナーを/dev/input/event0/dev/input/by-id/usb-Metrologic_Metrologic_Scanner-event-kbd)に設置しています。バーコードをスキャンすると、キープレスイベントが送信されます。 libdevinput Rubyライブラリを使用してこれらのキー押下をキャプチャしています。これはうまく機能します。問題は、各バーコードがユーザー名として入力され、続いてパスワードも入力されることです。 Raspberry Piは、多くのログイン試行の失敗を引き起こします(Raspberry Piはヘッドレスで、電子レンジ内にあります)。

Linuxがバーコードスキャナーを入力デバイスとして認識しないようにするにはどうすればよいですか?また、私のプログラムを唯一のイベントコンシューマーにすることはできますか?または別のより良い解決策はありますか?

11
ndbroadbent

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 gem、ffi、およびLinuxヘッダーをインストールする必要があります。 3.2.03.6.11の間のLinuxバージョンを使用している場合は、FFI::ConstGeneratorの部分をEVIOCGRAB = 1074021776に置き換えることができ、ffiは必要ありません。またはLinuxヘッダー。

6
ndbroadbent

この問題 に似ているように聞こえる この問題 を試してみる:問題が正しく理解できれば、バーコードスキャナーは「仮想コアキーボード」のスレーブポインターとして表示されます。 「あなたがするとき

xinput --list

次に、IDを取得して強制的にフロートさせると、次のようになります。

xinput float <id>