在发生鼠标事件时重新启动无尽的while循环?

时间:2018-09-26 07:55:22

标签: c linux while-loop mouseevent

我的目标是一个看起来像这样的简单代码:

#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;
}

我的目标是在单击鼠标左键后立即从“嘿1”重新开始打印顺序。 但是,如果没有在每次睡眠前使用“ if”条件,我将无法实现这一目标。 “ goto”在不同功能上也不适用于我。 有人可以为这个建议一个最佳解决方案吗?

1 个答案:

答案 0 :(得分:2)

您可以使用某种状态机来实现:具有 知道晶须是最后印刷的hey的内部静态状态

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\n", 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;
}

编辑

循环中的一个问题是您将等待很长时间才能阅读新书 fd中的值。

您可以使用信号来实现这一点:

  • 不间断地连续读取小鼠的输入
  • 检测到左键单击时,发出警报信号以显示事件:

因此,您的代码可能是:

/* 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;
}