I am aiming a simple code which looks like this:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <poll.h> #include <linux/input.h> int main() { int fd, bytes; unsigned char data[3]; fd = open("/dev/input/mice", O_RDWR); int left; while(1) { bytes = read(fd, data, sizeof(data)); if(bytes > 0) { left = data[0] & 0x1; right = data[0] & 0x2; if(left==1){ goto reset_EVENT; } } reset_EVENT: printf("hey 1"); sleep(1); printf("hey 2"); sleep(1); printf("hey 3"); sleep(1); } return 0; }
My goal here is to restart the print sequence from “hey 1” immediately when left mouse is clicked. However, I am not able to achieve this without using “if” conditions before every sleep. a “goto” is not working for me across different functions too. Can anyone suggest an optimal solution for this one please ?
Advertisement
Answer
You could achieve this with some kind of state machine: a function which has an
internal static state to know whick was the last hey
printed
void print_event(int reset) { /* by default, print nothing */ static int state = 4; /* if reset, restart counting */ if (reset) state = 1; /* if state under 4, display `hey` */ if (state <= 3) printf("hey %dn", state++); } int main() { int fd, bytes; unsigned char data[3]; fd = open("/dev/input/mice", O_RDWR); int left, right; while(1) { /* by default, event is not reset */ int reset = 0; bytes = read(fd, data, sizeof(data)); if(bytes > 0) { left = data[0] & 0x1; right = data[0] & 0x2; if(left==1){ /* left click: reset event*/ reset = 1; } } /* ask function to print if needed */ print_event(reset); sleep(1); } return 0; }
EDIT
one problem in your loop is that you will wait a long time before reading new
value from fd
.
You can use signal to achieve this:
- continously reading input from mice, without sleeping
- when left click is detected, arm an alarm signal to display event:
Thus, your code could be:
/* print event function: can be called from alarm signal handler or directly from main function */ void print_event(int reset) { /* by default, print nothing */ static int state = 4; /* if reset, restart counting */ if (reset) state = 1; /* if state under 4, display `hey` */ if (state <= 3) { printf("hey %d", state++); /* if all `hey` have not been printed, prepare the next */ alarm(1); } } /* alarm signal receiver*/ void handle(int sig) { /* print event without reset */ print_event(0); } int main() { int fd, bytes; unsigned char data[3]; fd = open("/dev/input/mice", O_RDWR); int left; /* tell what function is to be called when alarm signal is raised */ signal(SIGALRM, handle); /* if you want to display one sequence before the first click, uncomment the following line */ /* print_event(1); */ while(1) { bytes = read(fd, data, sizeof(data)); if(bytes > 0) { left = data[0] & 0x1; if(left==1){ /* left click: reset event*/ print_event(1); } } } return 0; }