Як сказати, яку клавіатуру використовували для натискання клавіші?


16

Я часто працюю на парних станціях, де встановлено кілька клавіатур. Я можу використовувати setxkbmapз , -device <ID>щоб встановити макет для конкретної клавіатури (використовуючи ідентифікатор зxinput ), але часто це не очевидно , яка клавіатура я в. Було б краще уникати спроб обох клавіатур, тому я хотів би написати швидкий інструмент для отримання цієї інформації дляsetxkbmap . Я очікую типового випадку використання, наприклад:

$ setxkbmap -device "$(get-keyboard-id)" -layout gb
Press Enter to detect keyboard ID

Який інтерфейс надає цю інформацію в Linux? В ідеалі він повинен працювати без X, але це не є вимогою (не здається, що існує багато інструментів, які підтримують це без X).


Результати наразі:

  • Linux повинен знати, на якій клавіатурі я набираю для підтримки різних макетів для декількох клавіатур одночасно.
  • xinput→ list.c → list_xi2XIQueryDeviceнадає ідентифікатори пристрою, якими можна скористатися setxkbmap.
  • showkeyі xevне друкувати ідентифікатори клавіатури
  • xinput list-props $IDпоказує, куди надсилаються події на клавіатурі . Однак, використовуючи код з іншої відповіді, схоже, цей пристрій нічого не друкує для ідентифікації клавіатури.
  • Одне майже можливе рішення - запустити xinput --test <ID> &кожен ідентифікатор клавіатури і побачити, хто з них повертає щось першим. Проблема в тому, що з'ясувати, які "клавіатури" є насправді клавіатурами:

    $ xinput | grep keyboard
    ⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
        ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
        ↳ Power Button                              id=6    [slave  keyboard (3)]
        ↳ Video Bus                                 id=7    [slave  keyboard (3)]
        ↳ Power Button                              id=8    [slave  keyboard (3)]
        ↳ Sleep Button                              id=9    [slave  keyboard (3)]
        ↳ WebCam SC-13HDL10931N                     id=10   [slave  keyboard (3)]
        ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    

1
Можливо, ви шукаєте MPX.
Ігнасіо Васкес-Абрамс

@ IgnacioVazquez-Abrams Хіба це не набагато складніше рішення?
l0b0

Це залежить від проблеми.
Ігнасіо Васкес-Абрамс

"Здається, цей пристрій не друкує нічого для ідентифікації клавіатури": що ви маєте на увазі? Якщо ви less -f /dev/input/eventXнатиснете клавішу на відповідній клавіатурі, ви побачите "сміття", що відображається, тож ваші натискання клавіш дійсно спрямовані в один файл розробників, а не в інші.
Л. Леврель

Ви пробували це (посилаючись на іншу відповідь на інше питання, яке ви цитуєте)?
Л. Леврель

Відповіді:


4

Вимкнути пристрій

Ось одна ідея щодо визначення, яка саме клавіатура. Ви можете використовувати команду xinput для включення та відключення пристроїв.

Приклад

$ xinput list
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=12   [slave  pointer  (2)]
⎜   ↳ TPPS/2 IBM TrackPoint                     id=13   [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                     id=9    [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                     id=10   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Sleep Button                              id=8    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    ↳ ThinkPad Extra Buttons                    id=14   [slave  keyboard (3)]

Наведений вище результат показує різні пристрої, які у мене на ноутбуці Thinkpad. У мене додана лише 1 клавіатура, ця:

    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]

Тепер подивіться властивості, доступні через цей пристрій:

$ xinput list-props "AT Translated Set 2 keyboard"
Device 'AT Translated Set 2 keyboard':
    Device Enabled (124):   1
    Coordinate Transformation Matrix (126): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.

З вищесказаного ви бачите, що він включений, тому давайте відключимо його:

$ xinput set-prop "AT Translated Set 2 keyboard" "Device Enabled" 0

Щоб увімкнути це:

$ xinput set-prop "AT Translated Set 2 keyboard" "Device Enabled" 1

Ідея?

Ви можете ввімкнути вимкнення однієї з клавіатур за допомогою цієї команди, щоб визначити, на якій саме ви перебуваєте.

Список літератури


Хіба це не більше роботи? Мій підхід передбачає як мінімум одну команду, максимум три. Цей підхід завжди включає три команди - відключити, увімкнути, а потім встановити макет (плюс можливо перемикач клавіатури).
l0b0

@ l0b0 - так, я теж не в захваті від такого підходу. Я продовжую шукати, але ставлю цей метод тут як "1 шлях". Я не погоджуюся.
slm

@lobo - Ця відповідь не отримає щедрість, тому не хвилюйтеся з цього приводу, голоси мали ще до того, як ви розпочали баунті. stackoverflow.com/help/bounty . Крім того, який ваш гнів до мене намагається допомогти вам тут? Я дав вам не ідеальне рішення, а 1 спосіб здійснити ваше завдання. Я надав це більше 2 років тому, і цей Q сів тут без альтернатив. Я думаю, вам потрібно запитати себе, чи не в цьому питання / підхід. Очевидно лише мої 0,02 долара, але цього вже достатньо.
slm

Мій поганий х 2: Я не помітив трохи про "створений після того, як почався щедрий", і я ціную, що ви написали дуже добре сформульовану відповідь. Але я не можу прийняти рішення, яке складніше, ніж оригінальне, і я не розумію, чому це роблять інші.
l0b0

1
@ l0b0 Моя причина звернення: Це єдина команда, яку я можу використовувати, щоб швидко і легко підтвердити свою підозру, на якій клавіатурі це було, замість того, щоб прочитати весь сценарій, щоб переконатися, що він не стирає мій жорсткий диск, а потім збережіть і виконати його. Або, у разі найбільшої відповіді на сьогодні, складіть код С. Крім того, такі творчі ідеї заслуговують на користь.
Фабіан Рьолінг

4

Питання звучить трохи суперечливо, оскільки ви цитуєте інструменти X, але просите рішення, яке "в ідеалі має працювати без X".

Про ваш 4- й висновок: xinputдасть вам листування

$ xinput list-props 11
Device 'AT Translated Set 2 keyboard':
    Device Enabled (145):   1
    Coordinate Transformation Matrix (147): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
    Device Product ID (266):    1, 1
    Device Node (267):  "/dev/input/event0"

принаймні із наступною версією

$ xinput --version
xinput version 1.6.1
XI version on server: 2.3


Перший крок: виявлення пристрою події клавіатури в С

#include <stdio.h>
//#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>

// typical use : sudo ./a.out /dev/input/event*
int main (int argc, char *argv[])
{
  struct input_event ev[64];
  int fd[argc],rd,idev,value, size = sizeof (struct input_event);
  char name[256] = "Unknown";

  if(argc==1) return -1;

  int ndev=1;
  while(ndev<argc && (fd[ndev] = open (argv[ndev], O_RDONLY|O_NONBLOCK)) != -1){
    ndev++;
  }
  fprintf (stderr,"Found %i devices.\n", ndev);
  if(ndev==1) return -1;

  while (1){
    for(idev=1; idev<argc; idev++){
      if( (rd=read (fd[idev], ev, size * 64)) >= size){
      value = ev[0].value;
      if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){
        ioctl (fd[idev], EVIOCGNAME (sizeof (name)), name);
        printf ("%s\n", name);
        return idev;
      }
      }
    }
//    sleep(1);
  }
  return -1;
}

Велике спасибі цій сторінці . Я зняв більшість перевірок безпеки з коду, який я там запозичив, для наочності, в реальному коді ви їх, мабуть, хочете.

Зауважте, що натискання клавіш перегукується, тому ви, можливо, бажаєте люб’язно попросити користувача натиснути клавішу модифікатора (Shift, Control ...), а не будь-яку клавішу.

Другий крок: використовуйте xinput для отримання ідентифікатора X від імені пристрою

Складіть вищевказане джерело C та скористайтеся цим способом:

xinput list --id-only "keyboard:$(sudo ./a.out /dev/input/event*)"


Там же/dev/input/by-id
jthill

Дякую за пораду. Я цитував X інструменти лише тому, що, здається, більшість інструментів вимагає X. Я не знаю, як працювати /dev/input/event*- я спробував tailting, але безрезультатно.
l0b0

by-id дає посилання на відображення імені пристрою в чергу подій, не вимагаючи X.
jthill

@jthill На машині, на якій я зараз перебуваю, цей рейтинг має посилання лише для миші.
Л. Леврель

Хун. Гаразд, живи та вчися, у мене на клавіатурі перераховано все гарненько.
jthill

1

Більше копання виявило ще одне рішення, використовуючи звичайний Bash та звичайний обліковий запис користувача. Сценарій :

#!/usr/bin/env bash

set -o errexit -o nounset -o noclobber -o pipefail

# Remove leftover files and processes on exit
trap 'rm --recursive -- "$dir"; kill -- -$$' EXIT
dir="$(mktemp --directory)"
cd "$dir"

# Log key presses to file
xinput --list --id-only | while read id
do
    # Only check devices linked to an event source
    if xinput --list-props "$id" | grep --quiet --extended-regexp '^\s+Device Node.*/dev/input/event'
    then
        xinput test "$id" > "$id" &
    fi
done

# Check for key presses
while sleep 0.1
do
    for file in *
    do
        if [[ -s "$file" ]]
        then
            echo "$file"
            exit
        fi
    done
done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.