summaryrefslogtreecommitdiffstats
path: root/system/esekeyd/keyboard_detection.diff
diff options
context:
space:
mode:
Diffstat (limited to 'system/esekeyd/keyboard_detection.diff')
-rw-r--r--system/esekeyd/keyboard_detection.diff101
1 files changed, 101 insertions, 0 deletions
diff --git a/system/esekeyd/keyboard_detection.diff b/system/esekeyd/keyboard_detection.diff
new file mode 100644
index 0000000000..97e93bcdce
--- /dev/null
+++ b/system/esekeyd/keyboard_detection.diff
@@ -0,0 +1,101 @@
+diff -Naur esekeyd-esekeyd-1.2.7/src/input.c esekeyd-esekeyd-1.2.7.patched/src/input.c
+--- esekeyd-esekeyd-1.2.7/src/input.c 2010-07-04 16:23:51.000000000 -0400
++++ esekeyd-esekeyd-1.2.7.patched/src/input.c 2020-11-01 20:22:49.777498592 -0500
+@@ -10,6 +10,14 @@
+
+ #include "esekey.h"
+
++#include <dirent.h>
++#define CLASS_DIR "/sys/class/input"
++#define DEV_DIR "/dev/input"
++
++#ifndef PATH_MAX
++# define PATH_MAX 1024
++#endif
++
+ signed char check_handlers (void)
+ {
+ FILE *fp = NULL;
+@@ -45,32 +53,63 @@
+ return 0;
+ }
+
+-signed char find_input_dev (void)
++/* return true if /dev/input/event<devno> is a keyboard.
++ This could also have been done by way of ioctls instead of reading
++ from /sys files. Hopefully the /sys API doesn't change...
++ It's documented thoroughly here:
++ https://unix.stackexchange.com/questions/74903/explain-ev-in-proc-bus-input-devices-data
++ */
++int is_keyboard(int devno)
+ {
+- FILE *fp = NULL;
+- signed char have_evdev = -2;
++ char filename[PATH_MAX + 1];
++ char *buf = NULL;
++ size_t len = 0, caps = 0;
++ size_t wantcaps = (1 << EV_SYN | 1 << EV_KEY | 1 << EV_MSC | 1 << EV_LED | 1 << EV_REP);
++ FILE *fp;
++
++ sprintf(filename, "%s/event%d/device/capabilities/ev", CLASS_DIR, devno);
++ if(!(fp = fopen(filename, "r"))) return 0;
++
++ getline(&buf, &len, fp);
++ fclose(fp);
++ if(!buf) return 0;
+
+- fp = fopen (INPUT_DEVICES, "r");
++ caps = strtol(buf, NULL, 16);
++ free(buf);
+
+- if (!fp)
++ return (caps & wantcaps) == wantcaps;
++}
++
++/* returns the highest-numbered keyboard found. The common case is
++ that the internal keyboard on a laptop is numbered lower than an external
++ keyboard, and we assume that if there's an external, it's the one the
++ user actually uses. If no keyboards are found, returns -1. */
++signed char find_input_dev (void)
++{
++ DIR *dir;
++ struct dirent *entry;
++ int last_kbd = -1;
++ char buf[PATH_MAX + 1];
++
++ dir = opendir(CLASS_DIR);
++ if(!dir) {
++ perror(CLASS_DIR);
+ return -1;
++ }
+
+- while (!feof (fp))
+- {
+- char *buff = NULL;
+- size_t len = 0;
+- short int number = -2;
+- getline (&buff, &len, fp);
+- sscanf (buff, "H: Handlers=kbd event%hu", &number);
+- free (buff);
+- if (number > -1)
+- {
+- have_evdev = number;
+- break;
++ while( (entry = readdir(dir)) ) {
++ sprintf(buf, "%s/%s", CLASS_DIR, entry->d_name);
++ if(strncmp(entry->d_name, "event", 5) == 0) {
++ int devno = atoi(entry->d_name + 5);
++ if(is_keyboard(devno)) {
++ fprintf(stderr, "event%d is a keyboard\n", devno);
++ if(devno > last_kbd) last_kbd = devno;
++ }
+ }
+ }
++ closedir(dir);
+
+- fclose (fp);
++ fprintf(stderr, "Autodetected keyboard: %s/event%d\n", DEV_DIR, last_kbd);
+
+- return have_evdev;
++ return last_kbd;
+ }