Linuxキーボードロギング - キーマップ変換[閉じる]

Linuxキーボードロギング - キーマップ変換[閉じる]

私はLinuxで入力イベントを監視するクラスを書いています。これは、GUIプログラムでユーザーのキーストロークに基づいてUSB LEDデバイスに視覚的なフィードバックを提供するデーモンによって使用されます。

私は/dev/input/event*から読み取った入力イベントを使用します。私が使っていますが、<linux/input.h>キーコードを受け取りました。

ベルギーのキーボードを使用しています。キーボードの「A」キーを押して離すと、現在のログに次のように表示されます。

29/09/2019 - 14:14:48.751 [Info] Event: time 1569759288.751445, type 4 (Misc), code 4 (ScanCode), value 0x10
29/09/2019 - 14:14:48.751 [Info] Event: time 1569759288.751445, type 1 (Key), code 16 (Q), value 1
29/09/2019 - 14:14:48.751 [Info] Event: time 1569759288.751445, -------------- Report Sync ------------
29/09/2019 - 14:14:48.792 [Info] Event: time 1569759288.792115, type 4 (Misc), code 4 (ScanCode), value 0x10
29/09/2019 - 14:14:48.792 [Info] Event: time 1569759288.792115, type 1 (Key), code 16 (Q), value 0
29/09/2019 - 14:14:48.792 [Info] Event: time 1569759288.792115, -------------- Report Sync ------------

修飾キーがない場合、実際に画面に印刷されるのは小さな「a」です。

注「コード16(Q)」 - 数字16は10ベースのキーコードです。

「Q」をキーボードレイアウトにマップする必要があります。この場合、「a」を記録する必要があります。これを行うには、dumpkeysプログラムを使用してカーネルの現在の変換テーブルを取得します。

この特定の例の場合、出力される短縮データ(4列のみ表示)は次のとおりです。

keycode  16 = +a               +A               at               VoidSymbol

またはより適切なフォーマット:

keycode  16 = +0x0b61          +0x0b41          0x0040           0x0200 

+は基本的に移動可能であることを意味します。現段階では、これが考慮すべき事項であるかどうかはわかりませんでした。

私が理解したのは、dumpkeysプログラムが正しい数に0xb00を追加するため、+を削除して0x0b61から0x0b00を引くことによって0x0061を取得します。

0x0061は「a」のUnicode番号U + 0061で、対応するQStringをベクトルの位置0に格納します。ダンプキーに関する限り、最初の列です。

今質問は次のとおりです。

いくつかのキーは大丈夫です。キーボードの「1」「&」「|」文字を含む物理キーでデータを解釈すると、これらはすべて修飾キーで確認されます。

ただし、この例(物理キーには大文字の「A」のみがあります)では機能しません。

keymaps(5) - Linux のマニュアルページに記載されている修飾子の規則に応じて、以下が発生する必要があります。

修飾キーなしでキーコード16を押すと、U + 0061または「a」 - > ok - ジョブ番号0(最初の列で)が表示されます。

Shift補助キーでキーコード16を押して、U + 0041または「A」 - > OKを取得します。 Shift補助キーの重みは1なので、最初の動作(2番目の列で)

AltGr修飾キーでキーコード16を押して、U + 0040または「@」を取得します。 -> OK、AltGr重み2 - したがって、2番目の動作(3番目の列で)

キーコード16とShiftとAltGrを同時に押すと、重みが最大3になるため、3番目の動作(列4から始まる)はVoidSymbolなので何も起こりません。私が得たのはオメガの大文字「Ω」でした。なぜ?

VoidSymbolの場合、U + 0200は実際にはş(二重墓のあるラテン大文字a)です。 VoidSymbolとして使用する場合、Unicode値をどのように印刷しますか?

他の問題もあります。

別の例は、「§」、「6」、「^」の物理キーです。キーマップダンプキーは、「§」文字(U + 00A7)の兆候を提供しません。しかし、それでも入力できます...

基本的に移動可能なものは何ですか?

編集:追加の質問

#define modifierShift 1;    //why the difference between ShiftL and ShiftR -> there is no 'shift' key
#define modifierControl 4;  //why the difference between ControlL and ControlR -> there is no 'control' key
#define modifierShiftL 16;  //code 42
#define modifierShiftR 32;  //code 54
#define modifierCtrlL 64;   //code 29
#define modifierCtrlR 128;  //code 97

誰かが私がこれを明確にするのを助けることができますか?

答え1

Linux は 2 セットのキーマップを使用します。 1つはカーネル入力階層レベルで機能し、キーコードをスキャンコードに割り当てます。このマッピングを変更するために使用できますloadkeys。これがで見ることができるものですevtest

もう1つはXサーバーレベルで動作します。 Xevdevには、カーネル入力層から入力イベントを収集し、これらのイベントをいわゆるキーシンボルにマッピングする汎用ドライバがあります。これがで見ることができるものですxevxmodmapxkbd拡張を使用してより一般的な方法で変更できます。

したがって、ユーザーがカーネルで使用せず、ユーザーに背中をloadkeys使用して目的のキーマップをロードするように指示する場合

どちらの方法も「信頼可能」ですが、意味が非常に異なります。

関連情報