I am aiming a simple code which looks like this:
JavaScript
x
#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
JavaScript
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:
JavaScript
/* 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;
}