3

This other question, Accessing Keys from Linux Input Device

provided working C code on how to recognize a modifier key press in the Linux text console when no other keys are being pressed.

However, to apply the trick you have to know the specific file /dev/input/event* that logs keyboard events.

How do I determine the name of that file?

Community
  • 1
  • 1
frank99
  • 39
  • 1
  • 2

2 Answers2

2

I prefer next solution because it parses devices file internally.
If we check contents of /proc/bus/input/devices we can found something like this:

# cat /proc/bus/input/devices
I: Bus=0019 Vendor=0002 Product=0001 Version=0100
N: Name="vmouse"
P: Phys=vmouse/input0
S: Sysfs=/devices/virtual/input/input0
U: Uniq=
H: Handlers=mouse0 event0
B: PROP=0
B: EV=7
B: KEY=70400 0 0 0 0 0 0 0 0
B: REL=143

I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="sunxi-ths"
P: Phys=sunxiths/input0
S: Sysfs=/devices/virtual/input/input3
U: Uniq=
H: Handlers=event3
B: PROP=0
B: EV=9
B: ABS=100 0

I: Bus=0003 Vendor=1220 Product=0008 Version=0100
N: Name="HID 1220:0008"
P: Phys=usb-sunxi-ohci-1/input0
S: Sysfs=/devices/platform/sunxi-ohci.3/usb7/7-1/7-1:1.0/input/input6
U: Uniq=
H: Handlers=sysrq kbd event1
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=1f

I: Bus=0003 Vendor=1220 Product=0008 Version=0100
N: Name="HID 1220:0008"
P: Phys=usb-sunxi-ohci-1/input1
S: Sysfs=/devices/platform/sunxi-ohci.3/usb7/7-1/7-1:1.1/input/input7
U: Uniq=
H: Handlers=kbd mouse1 event2
B: PROP=0
B: EV=1f
B: KEY=4837fff 72ff32d bf544446 0 0 1f0001 20f90 8b17c000 677bfa d941dfed 9ed680 4400 0 10000002
B: REL=143
B: ABS=1 0
B: MSC=10

So the only thing we need is to find event device number in block where "EV=120013" string appeared:

#include <fcntl.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <unistd.h>

using namespace std;

string getInputDeviceName() {
    int rd;
    std::string devName;
    const char* pdevsName = "/proc/bus/input/devices";

    int devsFile = open(pdevsName, O_RDONLY);
    if (devsFile == -1) {
        printf("[ERR] Open input devices file: '%s' is FAILED\n", pdevsName);
    }
    else {
        char devs[2048];

        if ((rd = read(devsFile, devs, sizeof(devs) - 1)) < 6) {
            printf("[ERR] Wrong size was read from devs file\n");
        }
        else {
            devs[rd] = 0;

            char *pHandlers, *pEV = devs;
            do {
                pHandlers = strstr(pEV, "Handlers=");
                pEV = strstr(pHandlers, "EV=");
            }
            while (pHandlers && pEV && 0 != strncmp(pEV + 3, "120013", 6));

            if (pHandlers && pEV) {
                char* pevent = strstr(pHandlers, "event");
                if (pevent) {
                    devName = string("/dev/input/event");
                    devName.push_back(pevent[5]);
                }
                else {
                    printf("[ERR] Abnormal keyboard event device\n");
                }
            }
            else {
                printf("[ERR] Keyboard event device not found\n");
            }
        }
    }

    return devName;
}

NOTE1: This code works on event devices with numbers less than 10.
NOTE2: Please check "devs" buffer size, on your system 2048 bytes may be not enough.

Kiirk
  • 21
  • 3
0

I had this exact same problem. Here's my solution:

#include <iostream>
#include <string>
#include <stdio.h>

static const std::string COMMAND_GET_INPUT_DEVICE_EVENT_NUMBER =
    "grep -E 'Handlers|EV=' /proc/bus/input/devices |"
    "grep -B1 'EV=120013' |"
    "grep -Eo 'event[0-9]+' |"
    "grep -Eo '[0-9]+' |"
    "tr -d '\n'";

std::string executeCommand(const char *cmd) {
  FILE *pipe = popen(cmd, "r");
  char buffer[128];
  std::string result = "";
  while (!feof(pipe))
    if (fgets(buffer, 128, pipe) != NULL)
      result += buffer;
  pclose(pipe);
  return result;
}

std::string getInputDevicePath() {
  return "/dev/input/event" +
         executeCommand(COMMAND_GET_INPUT_DEVICE_EVENT_NUMBER.c_str());
}

int main() {
  std::cout << getInputDevicePath() << std::endl;
  return 0;
}
Kamil Pajak
  • 340
  • 2
  • 13