From 3ea28e334d2acfa0f988dbc155b4f9618a5b5fb2 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 26 Feb 2008 22:40:38 +0000 Subject: [PATCH] Provide access to fd set Includes notifications when the set changes. --- libfprint/core.c | 1 + libfprint/fp_internal.h | 1 + libfprint/fprint.h | 12 +++++++ libfprint/poll.c | 78 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 86 insertions(+), 6 deletions(-) diff --git a/libfprint/core.c b/libfprint/core.c index e1382fa..f16c6ca 100644 --- a/libfprint/core.c +++ b/libfprint/core.c @@ -776,6 +776,7 @@ API_EXPORTED int fp_init(void) return r; register_drivers(); + fpi_poll_init(); return 0; } diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index 6a365c1..26f679f 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -328,6 +328,7 @@ int fpi_img_compare_print_data_to_gallery(struct fp_print_data *print, /* polling and timeouts */ +void fpi_poll_init(void); void fpi_poll_exit(void); typedef void (*fpi_timeout_fn)(void *data); diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 4cebba3..8ad8b2b 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -267,8 +267,20 @@ struct fp_minutia **fp_img_get_minutiae(struct fp_img *img, int *nr_minutiae); void fp_img_free(struct fp_img *img); /* Polling and timing */ + +struct fp_pollfd { + int fd; + short events; +}; + int fp_handle_events_timeout(struct timeval *timeout); int fp_handle_events(void); +size_t fp_get_pollfds(struct fp_pollfd **pollfds); + +typedef void (*fp_pollfd_added_cb)(int fd, short events); +typedef void (*fp_pollfd_removed_cb)(int fd); +void fp_set_pollfd_notifiers(fp_pollfd_added_cb added_cb, + fp_pollfd_removed_cb removed_cb); /* Library */ int fp_init(void); diff --git a/libfprint/poll.c b/libfprint/poll.c index 6355f5c..5e371bf 100644 --- a/libfprint/poll.c +++ b/libfprint/poll.c @@ -61,18 +61,16 @@ * is expiring soonest at the head. */ static GSList *active_timers = NULL; +/* notifiers for added or removed poll fds */ +static fp_pollfd_added_cb fd_added_cb = NULL; +static fp_pollfd_removed_cb fd_removed_cb = NULL; + struct fpi_timeout { struct timeval expiry; fpi_timeout_fn callback; void *data; }; -void fpi_poll_exit(void) -{ - g_slist_free(active_timers); - active_timers = NULL; -} - static int timeout_sort_fn(gconstpointer _a, gconstpointer _b) { struct fpi_timeout *a = (struct fpi_timeout *) _a; @@ -245,3 +243,71 @@ API_EXPORTED int fp_handle_events(void) return fp_handle_events_timeout(&tv); } +/** \ingroup poll + * Retrieve a list of file descriptors that should be polled for events + * interesting to libfprint. This function is only for users who wish to + * combine libfprint's file descriptor set with other event sources - more + * simplistic users will be able to call fp_handle_events() or a variant + * directly. + * + * \param pollfds output location for a list of pollfds. If non-NULL, must be + * released with free() when done. + * \returns the number of pollfds in the resultant list, or negative on error. + */ +API_EXPORTED size_t fp_get_pollfds(struct fp_pollfd **pollfds) +{ + struct libusb_pollfd *usbfds; + struct fp_pollfd *ret; + size_t cnt; + size_t i; + + cnt = libusb_get_pollfds(&usbfds); + if (cnt <= 0) { + *pollfds = NULL; + return cnt; + } + + ret = g_malloc(sizeof(struct libusb_pollfd) * cnt); + for (i = 0; i < cnt; i++) { + ret[i].fd = usbfds[i].fd; + ret[i].events = usbfds[i].events; + } + + *pollfds = ret; + return cnt; +} + +/* FIXME: docs */ +API_EXPORTED void fp_set_pollfd_notifiers(fp_pollfd_added_cb added_cb, + fp_pollfd_removed_cb removed_cb) +{ + fd_added_cb = added_cb; + fd_removed_cb = removed_cb; +} + +static void add_pollfd(int fd, short events) +{ + if (fd_added_cb) + fd_added_cb(fd, events); +} + +static void remove_pollfd(int fd) +{ + if (fd_removed_cb) + fd_removed_cb(fd); +} + +void fpi_poll_init(void) +{ + libusb_set_pollfd_notifiers(add_pollfd, remove_pollfd); +} + +void fpi_poll_exit(void) +{ + g_slist_free(active_timers); + active_timers = NULL; + fd_added_cb = NULL; + fd_removed_cb = NULL; + libusb_set_pollfd_notifiers(NULL, NULL); +} +