ELECOM Trackball EX-G Modelle haben ein neues Chipset, das (mal wieder) die Anzahl Buttons falsch meldet. Für einige Chipsets gibt es dafür schon Workaround-Code im Linux Kernel. Wenn dein extra Button nicht geht, kannst Du seine Clicks mit diesem Beispiel C-Programm (kompilieren mit gcc) detektieren und vllt. irgendwas machen:
#define _GNU_SOURCE
#include <fcntl.h>
#include <unistd.h>
#include <linux/hiddev.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <spawn.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
void sigio_handler(int signo) {
// Dummy handler to "nudge" the process
//write(STDERR_FILENO, "SIGIO received\n", 15);
}
int main(int argc, char *argv[] /*, char *envp[]*/) {
if (argc != 2 ) {
printf("Usage: %s /dev/usb/hiddev?\nWhere \"?\" is a number.\n", argv[0]);
return 1;
}
int fd = open(argv[1], O_RDONLY);
if (fd < 0) { perror("open"); return 1; }
char *xdotoolargs[] = { "pxdotool", "key", "p", NULL };
extern char **environ;
struct hiddev_event ev;
int buttonNr=0;
bool pressed=false;
int status=-1;
pid_t pid;
// Set up dummy SIGIO handler
struct sigaction sa;
sa.sa_handler = sigio_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGIO, &sa, NULL) < 0) {
perror("sigaction");
close(fd);
return 1;
}
// Set ownership and signal
if (fcntl(fd, F_SETOWN, getpid()) < 0) {
perror("fcntl F_SETOWN");
close(fd);
return 1;
}
if (fcntl(fd, F_SETSIG, SIGIO) < 0) {
perror("fcntl F_SETSIG");
close(fd);
return 1;
}
// Enable asynchronous I/O
int flags = fcntl(fd, F_GETFL);
if (fcntl(fd, F_SETFL, flags | O_ASYNC) < 0) {
perror("fcntl F_SETFL O_ASYNC");
close(fd);
return 1;
}
int ev_size = sizeof(ev);
while (1) {
ssize_t n = read(fd, &ev, ev_size);
if (n < 0 || n < ev_size) {
if (errno == EINTR) continue; // Interrupted by signal
perror("read");
break;
}
if ( ev.hid == 589829) {
if ( buttonNr == 1) {
if ( ev.value == 1 ) {
if (!pressed) {
// extra button mouse down
printf(">>> HID event: button=%d, type=%d, value=%d\n",
buttonNr, ev.hid, ev.value);
fflush(stdout);
if(status==0){
waitpid(pid, &status, 0);
}
status = posix_spawn(&pid, "/usr/bin/xdotool", NULL, NULL, xdotoolargs, environ);
pressed=true;
}
} else if(pressed) {
// extra button mouse up
//printf("<<< HID event: button=%d, type=%d, value=%d\n",
// buttonNr, ev.hid, ev.value);
//fflush(stdout);
pressed=false;
}
//} else {
// // some other button with same event ID the kernel/X/wayland can handle (up or down)
// printf("--- HID event: button=%d, type=%d, value=%d\n",
// buttonNr, ev.hid, ev.value);
// fflush(stdout);
}
buttonNr++;
} else {
// more buttons or mouse events, but with different IDs
//printf(" HID event: button=%d, type=%d, value=%d\n",
// buttonNr, ev.hid, ev.value);
//fflush(stdout);
buttonNr=0;
}
}
if(status==0){
waitpid(pid, &status, 0);
}
printf("Read all. Closing.");
close(fd);
return 0;
}
//edit: fixed read stalling after a while; launching xdotool as an example directly
you'll probably also have to register them to be able to use the distributed tracking network. so you will even link second hand tags to the phone you're using.