From fa9ed6c5d0d3ce282524d11f4e99f5b6916093ca Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Tue, 5 May 2020 20:46:59 +0200 Subject: Use a source in dummy driver, reorder includes --- src/cli.c | 6 +++-- src/device.h | 15 +++++++---- src/device_manager.c | 26 ++++++++++++++++--- src/device_manager.h | 12 ++++++++- src/dummy.c | 73 +++++++++++++++++++++++++++++++++++++++++++--------- src/gui_app.c | 1 + src/gui_app_window.c | 7 ++--- src/gui_app_window.h | 6 ++--- src/image.c | 7 ++--- src/image.h | 4 +-- src/main.c | 4 +-- src/moticam.c | 9 ++++--- src/options.c | 5 ++-- src/options.h | 2 +- src/usb_source.c | 4 +-- src/usb_source.h | 2 +- src/utils.c | 4 +-- 17 files changed, 138 insertions(+), 49 deletions(-) diff --git a/src/cli.c b/src/cli.c index 608aa58..41bd9d2 100644 --- a/src/cli.c +++ b/src/cli.c @@ -20,12 +20,14 @@ * Web: http://ni.fr.eu.org/ * Email: */ -#include - #include "cli.h" + +#include "device.h" #include "device_manager.h" #include "utils.h" +#include + static bool cli_read_images(struct device *device, int count, bool raw, const char *out, GError **error) diff --git a/src/device.h b/src/device.h index 904e21b..61ecf71 100644 --- a/src/device.h +++ b/src/device.h @@ -24,16 +24,18 @@ * Web: http://ni.fr.eu.org/ * Email: */ +#include "image.h" + +#include #include +#include #include -#include - -#include "image.h" /* Error domain for device related errors. */ #define DEVICE_ERROR device_error_quark() struct device; +struct device_manager; /* USB poll function. If the device is handled by this driver, it should * return a dynamically allocated string naming this device. */ @@ -43,7 +45,10 @@ typedef char *(*device_driver_usb_poll_f)( /* USB open function. The device driver previously declared that it handles * this device. */ typedef struct device *(*device_driver_usb_open_f)( - libusb_context *usb, libusb_device *usb_device, GError **error); + struct device_manager *dm, + libusb_context *usb, + libusb_device *usb_device, + GError **error); /* Poll function. If a device is handled by this driver, it should return a * dynamically allocated string naming this device. */ @@ -52,7 +57,7 @@ typedef char *(*device_driver_poll_f)(void); /* Open function. The device driver previously declared that it handles a * device. */ typedef struct device *(*device_driver_open_f)( - GError **error); + struct device_manager *dm, GError **error); /* Information on a device driver. */ struct device_driver { diff --git a/src/device_manager.c b/src/device_manager.c index ee570d4..dc6abf4 100644 --- a/src/device_manager.c +++ b/src/device_manager.c @@ -21,6 +21,7 @@ * Email: */ #include "device_manager.h" + #include "usb_source.h" #include @@ -30,6 +31,7 @@ struct device_manager { + GMainContext *context; libusb_context *usb; GSource *usb_source; device_manager_callback_f callback; @@ -50,8 +52,7 @@ device_manager_usb_source_cb(gpointer user_data) tv.tv_sec = 0; tv.tv_usec = 0; libusb_handle_events_timeout(dm->usb, &tv); - if (dm->callback) - dm->callback(dm->user_data); + device_manager_driver_call_callback(dm); return G_SOURCE_CONTINUE; } @@ -60,6 +61,7 @@ device_manager_new(GMainContext *context) { /* Create context. */ struct device_manager *dm = g_new(struct device_manager, 1); + dm->context = context; dm->usb = NULL; dm->usb_source = NULL; dm->callback = NULL; @@ -124,7 +126,7 @@ device_manager_open(struct device_manager *dm, GError **error) struct device *device = NULL; if (found_usb_device) { g_free(found_device_name); - device = found_device_driver->usb_open(dm->usb, found_usb_device, + device = found_device_driver->usb_open(dm, dm->usb, found_usb_device, error); } else { for (const struct device_driver **dd = drivers; @@ -139,7 +141,7 @@ device_manager_open(struct device_manager *dm, GError **error) } if (found_device_name) { g_free(found_device_name); - device = found_device_driver->open(error); + device = found_device_driver->open(dm, error); } else { g_set_error(error, DEVICE_ERROR, DEVICE_ERROR_LIST, "no device found"); @@ -160,3 +162,19 @@ device_manager_destroy(struct device_manager *dm) /* Free context. */ g_free(dm); } + +void +device_manager_driver_source_attach(struct device_manager *dm, + GSource *source) +{ + g_assert(dm); + g_source_attach(source, dm->context); +} + +void +device_manager_driver_call_callback(struct device_manager *dm) +{ + g_assert(dm); + if (dm->callback) + dm->callback(dm->user_data); +} diff --git a/src/device_manager.h b/src/device_manager.h index 1db5d81..decda3a 100644 --- a/src/device_manager.h +++ b/src/device_manager.h @@ -22,8 +22,9 @@ * Web: http://ni.fr.eu.org/ * Email: */ -#include "device.h" +#include +struct device; struct device_manager; typedef void (*device_manager_callback_f) (void *user_data); @@ -46,4 +47,13 @@ device_manager_open(struct device_manager *dm, GError **error); void device_manager_destroy(struct device_manager *dm); +/* To be called by a driver, attach a source. */ +void +device_manager_driver_source_attach(struct device_manager *dm, + GSource *source); + +/* To be called by a driver, call the user callback. */ +void +device_manager_driver_call_callback(struct device_manager *dm); + #endif /* device_manager_h */ diff --git a/src/dummy.c b/src/dummy.c index 834f212..ab3c1bc 100644 --- a/src/dummy.c +++ b/src/dummy.c @@ -24,21 +24,27 @@ */ #include "dummy.h" +#include "device_manager.h" + struct dummy_device { struct device device; + struct device_manager *dm; int width; int height; int stride; double exposure_ms; double gain; + bool ready; + int n; struct image *image; + GSource *source; }; static char * dummy_poll(void); static struct device * -dummy_open(GError **error); +dummy_open(struct device_manager *dm, GError **error); const struct device_driver dummy_device_driver = { "Dummy camera", @@ -63,6 +69,15 @@ static const struct device_info dummy_device_info = { .resolution = dummy_device_info_resolution, }; +static gboolean +dummy_source_cb(gpointer user_data) +{ + struct dummy_device *mdev = user_data; + mdev->ready = true; + device_manager_driver_call_callback(mdev->dm); + return G_SOURCE_CONTINUE; +} + static const struct device_info * dummy_get_info(struct device *device) { @@ -102,7 +117,13 @@ dummy_start(struct device *device, GError **error) g_return_val_if_fail(error == NULL || *error == NULL, false); struct dummy_device *mdev = (struct dummy_device *) device; g_assert(!mdev->image); - /* Nothing to do. */ + g_assert(!mdev->source); + /* Add source. */ + mdev->source = g_timeout_source_new(1000 / 10); + g_source_set_callback(mdev->source, dummy_source_cb, mdev, NULL); + device_manager_driver_source_attach(mdev->dm, mdev->source); + /* Done. */ + mdev->ready = true; return true; } @@ -111,18 +132,38 @@ dummy_read(struct device *device, GError **error) { g_return_val_if_fail(error == NULL || *error == NULL, NULL); struct dummy_device *mdev = (struct dummy_device *) device; + if (!mdev->ready) + return NULL; + mdev->ready = false; /* Prepare image. */ - if (!mdev->image) { + if (!mdev->image) mdev->image = image_new(mdev->width, mdev->height, mdev->stride, IMAGE_FORMAT_XBGR32); - uint8_t *p = mdev->image->pixels; - for (int y = 0; y < mdev->height; y++) { - for (int x = 0; x < mdev->width; x++) { - *p++ = (x ^ y) & 0xffffff; - *p++ = 0; - *p++ = 0; - *p++ = 0xff; - } + uint8_t *p = mdev->image->pixels; + int mb = 0; + int mg = 0; + int mr = 0; + int n = mdev->n % (3 * 255); + if (n < 255) { + mb = 255 - n; + mg = n; + } else if (n < 510) { + n -= 255; + mg = 255 - n; + mr = n; + } else { + n -= 510; + mr = 255 - n; + mb = n; + } + mdev->n += 4; + for (int y = 0; y < mdev->height; y++) { + for (int x = 0; x < mdev->width; x++) { + int g = (x ^ y) & 0xff; + *p++ = g * mb / 255; + *p++ = g * mg / 255; + *p++ = g * mr / 255; + *p++ = 0xff; } } image_ref(mdev->image); @@ -137,6 +178,10 @@ dummy_stop(struct device *device, GError **error) if (mdev->image) { image_unref(mdev->image); mdev->image = NULL; + g_assert(mdev->source); + g_source_destroy(mdev->source); + g_source_unref(mdev->source); + mdev->source = NULL; } return true; } @@ -160,7 +205,7 @@ dummy_poll(void) } static struct device * -dummy_open(GError **error) +dummy_open(struct device_manager *dm, GError **error) { g_return_val_if_fail(error == NULL || *error == NULL, NULL); /* Create context. */ @@ -173,12 +218,16 @@ dummy_open(GError **error) mdev->device.read = &dummy_read; mdev->device.stop = &dummy_stop; mdev->device.close = &dummy_close; + mdev->dm = dm; mdev->width = 0; mdev->height = 0; mdev->stride = 0; mdev->exposure_ms = dummy_device_info.exposure_default_ms; mdev->gain = dummy_device_info.gain_default; + mdev->ready = false; + mdev->n = 0; mdev->image = NULL; + mdev->source = NULL; /* Done. */ return &mdev->device; } diff --git a/src/gui_app.c b/src/gui_app.c index 1a2f501..a910ebe 100644 --- a/src/gui_app.c +++ b/src/gui_app.c @@ -21,6 +21,7 @@ * Email: */ #include "gui_app.h" + #include "device_manager.h" #include "gui_app_window.h" #include "options.h" diff --git a/src/gui_app_window.c b/src/gui_app_window.c index 980daaa..1068556 100644 --- a/src/gui_app_window.c +++ b/src/gui_app_window.c @@ -20,12 +20,13 @@ * Web: http://ni.fr.eu.org/ * Email: */ -#include -#include - #include "gui_app_window.h" + #include "utils.h" +#include +#include + struct _GuiAppWindow { GtkApplicationWindow parent; }; diff --git a/src/gui_app_window.h b/src/gui_app_window.h index 2f886db..4428d47 100644 --- a/src/gui_app_window.h +++ b/src/gui_app_window.h @@ -22,10 +22,10 @@ * Web: http://ni.fr.eu.org/ * Email: */ -#include - -#include "gui_app.h" #include "device.h" +#include "gui_app.h" + +#include #define GUI_APP_WINDOW_TYPE (gui_app_window_get_type()) G_DECLARE_FINAL_TYPE(GuiAppWindow, gui_app_window, GUI, APP_WINDOW, diff --git a/src/image.c b/src/image.c index ec29751..2b8be93 100644 --- a/src/image.c +++ b/src/image.c @@ -20,13 +20,14 @@ * Web: http://ni.fr.eu.org/ * Email: */ +#include "image.h" + +#include "utils.h" + #include #include #include -#include "image.h" -#include "utils.h" - typedef uint8_t u8x16 __attribute__((vector_size(16))); typedef uint16_t u16x8 __attribute__((vector_size(16))); diff --git a/src/image.h b/src/image.h index 0e36c02..9704676 100644 --- a/src/image.h +++ b/src/image.h @@ -22,9 +22,9 @@ * Web: http://ni.fr.eu.org/ * Email: */ -#include -#include #include +#include +#include /* Error domain for image related errors. */ #define IMAGE_ERROR image_error_quark() diff --git a/src/main.c b/src/main.c index 2abeeda..7233484 100644 --- a/src/main.c +++ b/src/main.c @@ -20,10 +20,10 @@ * Web: http://ni.fr.eu.org/ * Email: */ -#include - #include "gui_app.h" +#include + int main(int argc, char **argv) { diff --git a/src/moticam.c b/src/moticam.c index c628c6f..9c13cfa 100644 --- a/src/moticam.c +++ b/src/moticam.c @@ -23,6 +23,7 @@ * Email: */ #include "moticam.h" + #include "utils.h" #define ID_VENDOR 0x232f @@ -52,8 +53,8 @@ static char * moticam_usb_poll(struct libusb_device_descriptor *desc); static struct device * -moticam_usb_open(libusb_context *usb, libusb_device *usb_device, - GError **error); +moticam_usb_open(struct device_manager *dm, libusb_context *usb, + libusb_device *usb_device, GError **error); static bool moticam_stop(struct device *device, GError **error); @@ -433,8 +434,8 @@ moticam_usb_poll(struct libusb_device_descriptor *desc) } static struct device * -moticam_usb_open(libusb_context *usb, libusb_device *usb_device, - GError **error) +moticam_usb_open(struct device_manager *dm, libusb_context *usb, + libusb_device *usb_device, GError **error) { g_return_val_if_fail(error == NULL || *error == NULL, NULL); /* Create context. */ diff --git a/src/options.c b/src/options.c index d95b6a9..d8683a5 100644 --- a/src/options.c +++ b/src/options.c @@ -21,12 +21,13 @@ * Email: */ #define _GNU_SOURCE -#include - #include "options.h" + #include "cli.h" #include "utils.h" +#include + void options_add(GApplication *app) { diff --git a/src/options.h b/src/options.h index 7a08619..49f78d0 100644 --- a/src/options.h +++ b/src/options.h @@ -22,8 +22,8 @@ * Web: http://ni.fr.eu.org/ * Email: */ -#include #include +#include /* Runtime options. */ struct options { diff --git a/src/usb_source.c b/src/usb_source.c index 761d103..8f2ba11 100644 --- a/src/usb_source.c +++ b/src/usb_source.c @@ -20,10 +20,10 @@ * Web: http://ni.fr.eu.org/ * Email: */ -#include - #include "usb_source.h" +#include + struct fd_tag { int fd; gpointer tag; diff --git a/src/usb_source.h b/src/usb_source.h index 0b76ce8..a4e0b97 100644 --- a/src/usb_source.h +++ b/src/usb_source.h @@ -23,7 +23,7 @@ * Email: */ #include -#include +#include GSource * usb_source_new(libusb_context *usb); diff --git a/src/utils.c b/src/utils.c index ddd044f..365dc1d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -21,13 +21,13 @@ * Email: */ #define _GNU_SOURCE +#include "utils.h" + #include #include #include #include -#include "utils.h" - void utils_fatal(const char *fmt, ...) { -- cgit v1.2.3