GNU/Linux >> Znalost Linux >  >> Linux

Jediná klávesa na klávesnici vytváří další stisknutí kláves pro každou současně stisknutou klávesu

Snažil jsem se na tuto chybu udělat pořádný patch. Je to problém spíše v jádře než v klávesnici, i když by se dalo namítnout, že se klávesnice chová zvláštně. Každopádně patch je odeslán do seznamu linux-input ke kontrole, ale zatím k němu nejsou žádné komentáře.

To by mělo vyřešit problém zmíněný zde u QPAD MK-85, ale stejný problém existuje u Corsair K70, Gigabyte Osmium a dalších podobných klávesnic. Pokud máte klávesnici, která má chybu, bylo by skvělé, kdybyste mohli otestovat opravu. Pokud to otestujete, dejte mi vědět, zda to funguje a také jakou máte klávesnici, důležité je také to, jakou jazykovou verzi používáte, americké a neamerické klávesnice se budou chovat jinak. Upozorňujeme, že klávesa zpětného lomítka na amerických klávesnicích bude mít na jiných verzích klávesnice jiné popisky.

Zde je pošta z linux-input s opravou:

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


Dobře, podařilo se mi dát dohromady hack, který problém řeší. Napíšu to sem pro případ, že by někdo narazil na stejný problém.

Za prvé, pokud nemáte zájem o vyladění zdrojového kódu jádra, můžete mít jinou možnost:http://kbd-mangler.sourceforge.net/ - Netestoval jsem to, ale popis vypadá docela slibně. Umožňuje vám vyladit vstup předtím, než je předán systému.

Mým řešením bylo upravit soubor drivers/hid/hid-input.c. Na začátek souboru jsem přidal tři nové definice proměnných;

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

Najděte funkci

void hidinput_hid_event

V dolní části této funkce je

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

Vstup je ovladač, typ odkazuje na typ události (1 je stisknutí klávesy. 2 je pohyb myši?), kód je kód klávesy a hodnota je buď 0 pro stisknuté a 1 pro stisknuté.

Při každém stisku klávesy HID systém 4krát projde všemi klávesami klávesnice. Proč to dělá 4x, nevím, ale 4 odpovídá počtu dalších stisků kláves, které jsem dostal s mou problematickou klávesou. V první smyčce má stisknutá klávesa hodnotu 0, ve druhé 1 a ve třetí a čtvrté opět hodnotu 0.

Řešením bylo upravit tuto funkci tak, aby neumožňovala opětovné stisknutí problematické klávesy při stisku jiných kláves NEBO do 4 smyček od původního stisku klávesy. Toho bylo dosaženo následujícím kódem (Zmínil jsem se, že jsem nekódoval C alespoň deset let? Omlouváme se)

/* 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);

Pokud to implementujete, možná budete chtít odstranit příkazy printk, jakmile ověříte, že funguje podle očekávání. Jsou tu jen proto, aby pomohli s laděním.


Linux
  1. Jak určit optimální hodnotu parametru Bs k Dd?

  2. Zjistit, zda je klávesa stisknuta ze skriptu?

  3. Ssh Soukromá-veřejná mapa klíčů pro klienta?

  1. Cloud hosting je pro vývojáře klíčem ke kostře IT

  2. Ekvivalent/alternativy pro Alt+Dot v systému Mac

  3. Nastavení pipefail pro jeden pipetovaný příkaz

  1. 3 způsoby, jak konfiguruji SSH pro soukromí

  2. Jak importovat soukromý klíč do FileZilla pro SFTP

  3. Oprávnění pro klíč SSL?