0

I wrote the following code to handle a joystick on Linux:

static int fd;

int joystick_init(void)
{
    struct js_event event;

    if((fd = open("/dev/input/js1", O_RDONLY | O_NONBLOCK)) == -1)
        return ERROR;

    //ignore all init events
    while(read(fd, &event, sizeof(struct js_event)) == sizeof(struct js_event)){
    }

    return SUCCESS;
}

void joystick_end(void)
{
    close(fd);
}

const struct js_event *joystick_get_event(void)
{
    static struct js_event event;

    if(read(fd, &event, sizeof(struct js_event)) == sizeof(struct js_event))
        return &event;

    return NULL;
}

And the following to print the events:

void joy_input(const struct js_event *event)
{
    switch(event->type){
        case JS_EVENT_BUTTON:
            printf("button number = %d\n", event->number);
            break;
    
        case JS_EVENT_AXIS:
            printf("axis number = %d\n", event->number);
            break;
    }

    printf("event time = %d\n", event->time);
    printf("event value = %d\n", event->value);
    printf("event type = %d\n", event->type);
    puts("joy_input called");
}

And this is what is printed every time a button is pressed:

event time = 6348112

event value = 0

event type = 0

joy_input called

What's the problem? Why doesn't it report JS_EVENT_BUTTON or JS_EVENT_AXIS? Why doesn't time change?

Edit:

//void * can't point to functions
typedef struct Joystick_Listener {
    void (*cb)(const struct js_event *event);
} Joystick_Listener;

static void dispatch_joy_events(Node *node, void *arg)
{
    Joystick_Listener *listener = node->content;
    listener->cb(arg);
}

void video_and_input_run(void)
{
    const struct js_event *event;

    while(1){
        /* ... */
    
        //Call joystick listeners
        pthread_mutex_lock(&joy_listener_lock);
    
        while((event = joystick_get_event()) != NULL)
            list_iterate_arg(&joy_listener, dispatch_joy_events, &event);
        
        pthread_mutex_unlock(&joy_listener_lock);
    
        /* ... */
    }
}

void list_iterate_arg(const List *list, void(*function)(Node*, void *), void *arg)
{
    Node *next; //store in case the node changes
    for(Node *ite = list->first; ite != NULL; ite = next){
        next = ite->next;
        function(ite, arg);
    }
}
Community
  • 1
  • 1
2013Asker
  • 2,008
  • 3
  • 25
  • 36

1 Answers1

0

Silly mistake, I was passing the address of event but it's already a pointer to the event and not the event itself, so it makes no sense.

void video_and_input_run(void)
{
    const struct js_event *event;

    while(1){
        /* ... */

        //Call joystick listeners
        pthread_mutex_lock(&joy_listener_lock);

        while((event = joystick_get_event()) != NULL)
            list_iterate_arg(&joy_listener, dispatch_joy_events, event);

        pthread_mutex_unlock(&joy_listener_lock);

        /* ... */
    }
}
2013Asker
  • 2,008
  • 3
  • 25
  • 36