GNU/Linux >> Linux の 問題 >  >> Linux

キーボードの単一のキーは、同時に押されたキーごとに追加のキープレスを生成します

このバグに対する適切なパッチを作成しようとしました。これはキーボードの問題ではなく、カーネルの問題ですが、キーボードの動作がおかしいという意見もあるかもしれません。とにかく、パッチはレビューのために linux-input リストに提出されていますが、まだコメントはありません.

これにより、ここで説明した QPAD MK-85 の問題は修正されますが、Corsair K70、Gigabyte Osmium、およびその他の類似のキーボードにも同じ問題が存在します。バグのあるキーボードをお持ちの場合は、パッチをテストしていただければ幸いです。テストする場合は、動作するかどうか、また使用しているキーボードを教えてください。また、使用している言語バージョンも重要です。US キーボードと非 US キーボードでは動作が異なります。 US キーボードのバックスラッシュ キーには、他のバージョンのキーボードでは別のラベルが付いていることに注意してください。

以下はパッチを含む linux-input からのメールです:

http://article.gmane.org/gmane.linux.kernel.input/37583


さて、問題を解決するハックをまとめることができました。誰かが同じ問題に遭遇した場合に備えて、ここに書きます。

最初に、カーネル ソースの微調整に興味がない場合は、別のオプションがあるかもしれません:http://kbd-mangler.sourceforge.net/ - 私はそれをテストしませんでしたが、説明はかなり有望に見えます。システムに渡される前に、入力を微調整できます。

私の解決策は、ファイル drivers/hid/hid-input.c を編集することでした。ファイルの先頭に、3 つの新しい変数定義を追加しました。

static bool CODE43TRUE = 0; // If true, code43 has been pressed
static bool CODEXXTRUE = 0; // If true, any other key has been pressed
static int  CODESKIP = 0;   // Counter for skipping extra code43 events

関数を見つける

void hidinput_hid_event

この関数の一番下は

です
input_event(input, usage->type, usage->code, value);

入力はコントローラー、タイプはイベント タイプを参照 (1 はキー押下..2 はマウス モーション?)、コードはキーコードで、値は押された場合は 0、押された場合は 1 です。

どのキーを押しても、HID システムはすべてのキーボード キーを 4 回ループします。なぜそれが4回行われるのかはわかりませんが、4回は問題のあるキーで得た余分なキープレスの量に対応しています.最初のループでは押されたキーの値は 0、2 番目のループでは 1、3 番目と 4 番目のループでは値 0 です。

解決策は、この関数を変更して、他のキーが押されたとき、または元のキー押下の 4 ループ内で問題のあるキーが再度押されないようにすることでした。これは、次のコードによって達成されました (少なくとも 10 年間 C をコーディングしていないことを言いましたか? 申し訳ありません)

/* report the usage code as scancode if the key status has changed */
if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
    input_event(input, EV_MSC, MSC_SCAN, usage->hid);

// NEW CODE STARTS HERE
if (usage->type == 1 && value == 1) // Keypress ahead
{
    if (usage->code == 43) { // Keypress is code 43
        if (CODE43TRUE == 0) {  // Key not yet pressed 
            CODE43TRUE = 1;
            printk(KERN_INFO "CODE43 SET TRUE\n");
        }
    else { // Key already pressed, so force value 1
        printk(KERN_INFO "CODE43 ALREADY TRUE SET VALUE 1\n");
        value = 0;
    }
}
else { // Some other key pressed, set XX true
    CODEXXTRUE = 1;
    printk(KERN_INFO "CODEXX SET TRUE\n");  
}
printk(KERN_INFO "Keypress type:%u code:%u value%d\n", (unsigned int) usage->type, (unsigned int) usage->code, (int) value);
}

if (usage->type == 1 && value == 0) { // Non-pressed key ahead
    if (usage->code == 43) { // If its a 43
        printk(KERN_INFO "43 call..\n");
        if (CODE43TRUE == 1) { // And 43 is fake pressed still
            if (CODEXXTRUE == 1 || CODESKIP < 4) { // If other buttons are pressed OR we are less than 5 ticks into the press..
                printk(KERN_INFO "FAKE PRESS 43. CODESKIP %d\n",CODESKIP);
                value = 0;
                CODESKIP ++;
            }
            else { // No other buttons pressed and over five ticks have passed
                printk(KERN_INFO "43 RELEASED\n");
                CODE43TRUE = 0;
                CODESKIP = 0;   
            }
        }
        // Reset the CODEXXTRUE (next time we get info about 43, we have looped through all the other keys so we know if something is pressed)
        CODEXXTRUE = 0;
    }   
}

// NEW CODE ENDS HERE
input_event(input, usage->type, usage->code, value);

これを実装している場合は、意図したとおりに機能していることを確認したら、printk ステートメントを削除することをお勧めします。デバッグに役立つだけです。


Linux
  1. キーボード入力とテキスト出力はどのように機能しますか?

  2. DdへのBsパラメータの最適値を決定する方法は?

  3. Linux –単一のLinuxプロセスのメモリ使用量を制限しますか?

  1. 単一のパイプ コマンドの pipefail の設定

  2. SSL キーのアクセス許可?

  3. 単一の Linux プロセスのメモリ使用量を制限する

  1. プライバシーのためにSSHを構成する3つの方法

  2. SFTP用にFileZillaに秘密鍵をインポートする方法

  3. シェルダブル対の良いニーモニックは何ですか。一重引用符?