कैसे बताएं कि किस कीबोर्ड का उपयोग कुंजी दबाने के लिए किया गया था?


16

मैं अक्सर उन स्टेशनों को बाँधने का काम करता हूँ जहाँ कई कीबोर्ड स्थापित होते हैं। मैं उपयोग कर सकते हैं setxkbmapके साथ -device <ID>एक विशिष्ट कुंजीपटल (एक प्रयोग करने के लिए लेआउट सेट करने के लिए से आईडीxinput ), लेकिन अक्सर यह स्पष्ट नहीं है जो कुंजीपटल मैं यहां हूं। दोनों कीबोर्ड की कोशिश करने से आगे और पीछे से बचना बेहतर होगा, इसलिए मैं इस जानकारी को प्राप्त करने के लिए एक त्वरित उपकरण लिखना चाहूंगा setxkbmap। मुझे निम्नलिखित की तरह एक सामान्य उपयोग के मामले की उम्मीद है:

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

कौन सा इंटरफ़ेस लिनक्स पर यह जानकारी प्रदान करता है? आदर्श रूप से इसे एक्स के बिना काम करना चाहिए, लेकिन यह एक आवश्यकता नहीं है (एक्स के बिना इसका समर्थन करने वाले कई उपकरण प्रतीत नहीं होते हैं)।


अब तक की खोजें:

  • लिनक्स को पता होना चाहिए कि मैं एक साथ कई कीबोर्ड के लिए अलग-अलग लेआउट का समर्थन करने के लिए किस कीबोर्ड पर टाइप कर रहा हूं।
  • 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)]

उपरोक्त आउटपुट विभिन्न उपकरणों को दिखाता है जो मेरे थिंकपैड लैपटॉप पर हैं। मेरे पास केवल 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

@ लब्बो - यह जवाब इनाम नहीं मिल रहा है, इसलिए इसके बारे में चिंता न करें, आपके पास बाउंटी शुरू करने से पहले इसके वोट थे। stackoverflow.com/help/bounty । इसके अलावा मेरे प्रति आपका गुस्सा यहाँ आपकी मदद करने की कोशिश कर रहा है? मैंने आपको एक आदर्श समाधान नहीं दिया, लेकिन आपके कार्य को पूरा करने का 1 तरीका है। मैंने इसे 2+ साल पहले प्रदान किया था और यह Q यहाँ w / 0 विकल्प के रूप में बैठा है। मुझे लगता है कि आपको अपने आप से पूछने की ज़रूरत है कि क्या यह समस्या है। जाहिर है मेरे $ 0.02 लेकिन यह पहले से ही पर्याप्त है।
SLM

मेरा बुरा x 2: मैंने "बाउंटी शुरू होने के बाद बनाई गई" के बारे में थोड़ा ध्यान नहीं दिया, और मैं सराहना करता हूं कि आपने बहुत अच्छी तरह से तैयार किया गया उत्तर लिखा। लेकिन मैं ऐसा समाधान नहीं निकाल सकता, जो मूल से अधिक जटिल हो, और मुझे समझ नहीं आता कि दूसरे क्यों करते हैं।
l0b0

1
@ l0b0 मेरे उत्थान का कारण: यह एक एकल आदेश है जिसका उपयोग मैं अपने संदेह को जल्दी और आसानी से करने के लिए उपयोग कर सकता हूं कि यह कौन सा कीबोर्ड था, इसके बजाय एक संपूर्ण स्क्रिप्ट को पढ़ने की ज़रूरत है ताकि यह सुनिश्चित हो सके कि यह मेरी हार्ड ड्राइव को मिटा नहीं है, फिर इसे सहेजें: इसे निष्पादित करो। या, अब तक के सबसे अधिक वोट किए गए उत्तर के मामले में, सी कोड संकलित करें। इसके अलावा, इस तरह के रचनात्मक विचार upvotes के लायक हैं।
फाबियन रोलिंग

4

सवाल थोड़ा विरोधाभासी लग रहा है क्योंकि आप एक्स टूल्स का हवाला दे रहे हैं लेकिन एक समाधान के लिए पूछें कि "आदर्श रूप से एक्स के बिना काम करना चाहिए"।

आपके 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


पहला चरण: C में कीबोर्ड ईवेंट डिवाइस का पता लगाना

#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 का उपयोग करें

उपरोक्त C स्रोत संकलित करें और इस तरह से उपयोग करें:

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


वहाँ भी है/dev/input/by-id
15

पारितोषिक के लिए धन्यवाद। मैंने केवल एक्स टूल का हवाला दिया है क्योंकि अधिकांश टूल को एक्स की आवश्यकता लगती है। मुझे नहीं पता कि कैसे काम करना है /dev/input/event*- मैंने tailटिंग की कोशिश की लेकिन कोई फायदा नहीं हुआ।
l0b0

बाय-आईडी बिना कतार की घटना के लिए डिवाइस नाम को
सहानुभूति

@jthill मशीन पर मैं वर्तमान में हूँ, इस dir में केवल माउस के लिए लिंक हैं।
एल। लेवलर

Hunh। ठीक है, जियो और सीखो, मेरा कीबोर्ड मेरे सभी सुंदर सूचीबद्ध है।
jthill

1

अधिक खुदाई से सादे बैश और एक सामान्य उपयोगकर्ता खाते का उपयोग करके एक और समाधान का पता चला । स्क्रिप्ट :

#!/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 Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.