here's a cheap example: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <linux/input.h> #include <linux/uinput.h> #define die(str, args...) do { \ perror(str); \ exit(EXIT_FAILURE); \ } while(0) int main(void) { int fd; struct uinput_user_dev uidev; struct input_event ev; int dx, dy; int i; fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); if(fd < 0) die("error: open"); ioctl(fd, UI_SET_EVBIT, (void*)EV_KEY); ioctl(fd, UI_SET_EVBIT, (void*)EV_MSC); ioctl(fd, UI_SET_EVBIT, (void*)EV_REP); ioctl(fd, UI_SET_EVBIT, (void*)EV_REL); memset(&uidev, 0, sizeof(uidev)); snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "Remote Control"); uidev.id.bustype = BUS_USB; uidev.id.vendor = 0x1; uidev.id.product = 0x1; uidev.id.version = 1; for (i=0; i < 248; i++) { if (i==240) continue; ioctl(fd, UI_SET_KEYBIT, i); } for(i=0x160;i<=0x214;i++) { if (i>0x20b && i<0x210) continue; if (i>0x1fa && i<0x200) continue; if (i>0x1e4 && i<0x1f1) continue; if (i>0x1c3 && i<0x1d0) continue; if (i>0x1ba && i<0x1c0) continue; ioctl(fd, UI_SET_KEYBIT, i); } if(write(fd, &uidev, sizeof(uidev)) < 0) die("error: write"); if(ioctl(fd, UI_DEV_CREATE) < 0) die("error: ioctl"); sleep(200); if(ioctl(fd, UI_DEV_DESTROY) < 0) die("error: ioctl"); close(fd); return 0; } cat /proc/bus/input/devices I: Bus=0003 Vendor=0001 Product=0001 Version=0001 N: Name="Sundtek Remote Control" P: Phys= S: Sysfs=/devices/virtual/input/input3 U: Uniq= H: Handlers=sysrq rfkill kbd <----- eventN is missing! B: PROP=0 B: EV=100017 B: KEY=1f0fff 7fe001f ffff000f 7ffffff ffffffff ffffffff 0 0 0 feffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe B: REL=0 B: MSC=0 eventN is missing in the Handlers: section if I modify the following loop: for(i=0x160;i<=0x214;i++) { if (i>0x20b && i<0x210) continue; if (i>0x1fa && i<0x200) continue; if (i>0x1e4 && i<0x1f1) continue; if (i>0x1c3 && i<0x1d0) continue; if (i>0x1ba && i<0x1c0) continue; if (i>0x200) <<<-------- continue; <<<<------ ioctl(fd, UI_SET_KEYBIT, i); } this will create a node again (and if the previous version was started without this modification they will also suddenly get an event node in the proc input devices file: I: Bus=0003 Vendor=0001 Product=0001 Version=0001 N: Name="Remote Control" P: Phys= S: Sysfs=/devices/virtual/input/input8 U: Uniq= H: Handlers=sysrq rfkill kbd event1 <---- event1 B: PROP=0 B: EV=100017 B: KEY=1 7fe001f ffff000f 7ffffff ffffffff ffffffff 0 0 0 feffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe B: REL=0 B: MSC=0 this event is related to /dev/input nodes (compared with regular input devices they don't even have a node id in sysfs (unless the userspace modification to handle less keys is made). This behaviour has been different until 4.4.9 (according to a customer). Tested on a Raspberry PI
It does not matter which keys we remove, we just have to remove some UI_SET_KEYBIT calls. ioctl(fd, UI_SET_KEYBIT, i);