giovedì 20 novembre 2025

Keyer VBand e LearnMorsewithGoogle

Partendo dal precedente post ho modificato il programma per essere compatibile con VBand Trainer oltre che con LearnMorsewithGoogle aggiungendo anche la ripetizione se il paddle viene mantenuto premuto

il  programma puo' essere usato solo con privilegi di root (o sudo) 

il primo parametro e' il device

il secondo e' il tempo di ripetizione in millisecondi

il terzo il tipo di configurazione (0=VBand con tasti parentesi quadre, 1=Google con tasti . e / ed infine 3=VBand con tasti CTRL-LEFT e CTRL-RIGHT)  

 sudo ./autokey /dev/input/event19 300 0

 

#include <linux/uinput.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/select.h>
#include <signal.h>

volatile sig_atomic_t running = 1;

void signal_handler(int sig) {
running = 0;
}

void send_key(int ufd, int keycode) {
struct input_event ev;
memset(&ev, 0, sizeof(ev));
// Key press
ev.type = EV_KEY;
ev.code = keycode;
ev.value = 1;
write(ufd, &ev, sizeof(ev));
// Sync
ev.type = EV_SYN;
ev.code = SYN_REPORT;
ev.value = 0;
write(ufd, &ev, sizeof(ev));
// Key release
ev.type = EV_KEY;
ev.code = keycode;
ev.value = 0;
write(ufd, &ev, sizeof(ev));
// Sync
ev.type = EV_SYN;
ev.code = SYN_REPORT;
ev.value = 0;
write(ufd, &ev, sizeof(ev));
}

int main(int argc, char *argv[]) {
if (argc < 4) {
printf("Usage: %s /dev/input/eventX <delay_ms> <mode>\n", argv[0]);
printf("\nModes:\n");
printf(" 0: LEFT='[' RIGHT=']' (VBand)\n");
printf(" 1: LEFT='.' RIGHT='/' (Learn Morse Google)\n");
printf(" 2: LEFT=CTRL_LEFT RIGHT=CTRL_RIGHT (VBand2)\n");
printf("\nExample: %s /dev/input/event4 100 0\n", argv[0]);
return 1;
}
const char *mouse_dev = argv[1];
int delay_ms = atoi(argv[2]);
int mode = atoi(argv[3]);
if (delay_ms <= 0) {
printf("Error: delay must be positive\n");
return 1;
}
if (mode < 0 || mode > 2) {
printf("Error: mode must be 0, 1, or 2\n");
return 1;
}
// Define key mappings based on mode
int left_key, right_key;
const char *left_label, *right_label;
switch (mode) {
case 0:
left_key = KEY_LEFTBRACE;
right_key = KEY_RIGHTBRACE;
left_label = "'['";
right_label = "']'";
break;
case 1:
left_key = KEY_DOT;
right_key = KEY_SLASH;
left_label = "'.'";
right_label = "'/'";
break;
case 2:
left_key = KEY_LEFTCTRL;
right_key = KEY_RIGHTCTRL;
left_label = "CTRL_LEFT";
right_label = "CTRL_RIGHT";
break;
}
// Open mouse device
int mfd = open(mouse_dev, O_RDONLY | O_NONBLOCK);
if (mfd < 0) {
perror("Mouse open");
return 1;
}
// GRAB EXCLUSIVE ACCESS
if (ioctl(mfd, EVIOCGRAB, 1) < 0) {
perror("Cannot grab mouse device");
close(mfd);
return 1;
}
printf("Mouse device grabbed successfully\n");
// Open uinput
int ufd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if (ufd < 0) {
perror("uinput open");
ioctl(mfd, EVIOCGRAB, 0);
close(mfd);
return 1;
}
// Setup virtual keyboard - register all possible keys
ioctl(ufd, UI_SET_EVBIT, EV_KEY);
ioctl(ufd, UI_SET_KEYBIT, KEY_DOT);
ioctl(ufd, UI_SET_KEYBIT, KEY_COMMA);
ioctl(ufd, UI_SET_KEYBIT, KEY_SLASH);
ioctl(ufd, UI_SET_KEYBIT, KEY_LEFTBRACE);
ioctl(ufd, UI_SET_KEYBIT, KEY_RIGHTBRACE);
ioctl(ufd, UI_SET_KEYBIT, KEY_LEFTCTRL);
ioctl(ufd, UI_SET_KEYBIT, KEY_RIGHTCTRL);
struct uinput_setup usetup;
memset(&usetup, 0, sizeof(usetup));
snprintf(usetup.name, UINPUT_MAX_NAME_SIZE, "mouse2key-mode%d", mode);
usetup.id.bustype = BUS_USB;
usetup.id.vendor = 0x1;
usetup.id.product = 0x1;
usetup.id.version = 1;
ioctl(ufd, UI_DEV_SETUP, &usetup);
ioctl(ufd, UI_DEV_CREATE);
// Setup signal handler
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
printf("Mode %d selected - Delay: %dms\n", mode, delay_ms);
printf(" Hold LEFT button = send %s repeatedly\n", left_label);
printf(" Hold RIGHT button = send %s repeatedly\n", right_label);
printf("Press Ctrl+C to exit\n\n");
struct input_event ev;
fd_set readfds;
struct timeval timeout;
int left_pressed = 0;
int right_pressed = 0;
while (running) {
// Setup select with timeout
FD_ZERO(&readfds);
FD_SET(mfd, &readfds);
int ret;
// Only use timeout if a button is held
if (left_pressed || right_pressed) {
// Send keystroke(s) immediately
if (left_pressed) {
send_key(ufd, left_key);
//if (mode < 2) printf(".");
fflush(stdout);
}
if (right_pressed) {
send_key(ufd, right_key);
//if (mode < 2) printf(",");
fflush(stdout);
}
// NOW wait for the delay
timeout.tv_sec = delay_ms / 1000;
timeout.tv_usec = (delay_ms % 1000) * 1000;
ret = select(mfd + 1, &readfds, NULL, NULL, &timeout);
if (ret < 0) {
perror("select");
break;
}
} else {
// No button held, just wait for events (blocking)
ret = select(mfd + 1, &readfds, NULL, NULL, NULL);
if (ret < 0) {
perror("select");
break;
}
}
// Check for mouse events
if (FD_ISSET(mfd, &readfds)) {
while (read(mfd, &ev, sizeof(ev)) > 0) {
if (ev.type == EV_KEY) {
if (ev.code == BTN_LEFT) {
if (ev.value == 1) {
// Left button pressed
left_pressed = 1;
//printf("\n[LEFT pressed - sending %s]\n", left_label);
} else if (ev.value == 0) {
// Left button released
left_pressed = 0;
//printf("\n[LEFT released]\n");
}
} else if (ev.code == BTN_RIGHT) {
if (ev.value == 1) {
// Right button pressed
right_pressed = 1;
//printf("\n[RIGHT pressed - sending %s]\n", right_label);
} else if (ev.value == 0) {
// Right button released
right_pressed = 0;
//printf("\n[RIGHT released]\n");
}
}
}
}
}
}
// Cleanup
printf("\nCleaning up...\n");
ioctl(ufd, UI_DEV_DESTROY);
ioctl(mfd, EVIOCGRAB, 0);
close(ufd);
close(mfd);
return 0;
}

 

Nessun commento:

Posta un commento

Algoritmo Reed Solomon

 Sto progettando una trasmissione radio di immagini ed uno dei vincoli e' che non e' garantita la perfetta qualita' della trasmi...