From ca1a74cafa8f75a20e42bbdf501f5c8e8f184920 Mon Sep 17 00:00:00 2001
From: Matthias Vogelgesang <matthias.vogelgesang@gmail.com>
Date: Wed, 13 Mar 2013 18:07:21 +0100
Subject: Use GInitable to pass properties to plugins

---
 CMakeLists.txt                 |   8 ++-
 plugins/mock/uca-mock-camera.c |  65 ++++++++++++-----
 plugins/mock/uca-mock-camera.h |   2 -
 plugins/pf/uca-pf-camera.c     | 158 ++++++++++++++++++++++++++++-------------
 src/uca-plugin-manager.c       |  27 ++++---
 src/uca-plugin-manager.h       |   4 +-
 test/test-mock.c               |   6 +-
 tools/benchmark.c              |   3 +-
 tools/gen-doc.c                |   2 +-
 tools/grab-async.c             |   2 +-
 tools/grab.c                   |   2 +-
 tools/gui/control.c            |   2 +-
 tools/perf-overhead.c          |   2 +-
 13 files changed, 193 insertions(+), 90 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1ed671b..26931b9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,17 +54,21 @@ find_program(GLIB2_MKENUMS glib-mkenums REQUIRED)
 pkg_check_modules(GLIB2 glib-2.0>=2.24 REQUIRED)
 pkg_check_modules(GOBJECT2 gobject-2.0>=2.24 REQUIRED)
 pkg_check_modules(GMODULE2 gmodule-2.0>=2.24 REQUIRED)
+pkg_check_modules(GIO2 gio-2.0>=2.24 REQUIRED)
 
 include_directories(
     ${CMAKE_CURRENT_BINARY_DIR}/src
     ${CMAKE_CURRENT_SOURCE_DIR}/src
     ${GLIB2_INCLUDE_DIRS}
-    ${GOBJECT2_INCLUDE_DIRS})
+    ${GOBJECT2_INCLUDE_DIRS}
+    ${GMODULE2_INCLUDE_DIRS}
+    ${GIO2_INCLUDE_DIRS})
 
 set(UCA_DEPS
     ${GLIB2_LIBRARIES}
     ${GOBJECT2_LIBRARIES}
-    ${GMODULE2_LIBRARIES})
+    ${GMODULE2_LIBRARIES}
+    ${GIO2_LIBRARIES})
 
 add_subdirectory(src)
 add_subdirectory(plugins)
diff --git a/plugins/mock/uca-mock-camera.c b/plugins/mock/uca-mock-camera.c
index 47e08aa..c7561ab 100644
--- a/plugins/mock/uca-mock-camera.c
+++ b/plugins/mock/uca-mock-camera.c
@@ -16,12 +16,17 @@
    Franklin St, Fifth Floor, Boston, MA 02110, USA */
 
 #include <gmodule.h>
+#include <gio/gio.h>
 #include <string.h>
 #include "uca-mock-camera.h"
 
 #define UCA_MOCK_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_MOCK_CAMERA, UcaMockCameraPrivate))
 
-G_DEFINE_TYPE(UcaMockCamera, uca_mock_camera, UCA_TYPE_CAMERA)
+static void uca_mock_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaMockCamera, uca_mock_camera, UCA_TYPE_CAMERA,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                                uca_mock_initable_iface_init))
 
 enum {
     PROP_FRAMERATE = N_BASE_PROPERTIES,
@@ -137,7 +142,8 @@ static const char g_digits[10][20] = {
 static const guint DIGIT_WIDTH = 4;
 static const guint DIGIT_HEIGHT = 5;
 
-static void print_number(gchar *buffer, guint number, guint x, guint y, guint width)
+static void
+print_number(gchar *buffer, guint number, guint x, guint y, guint width)
 {
     for (int i = 0; i < DIGIT_WIDTH; i++) {
         for (int j = 0; j < DIGIT_HEIGHT; j++) {
@@ -146,7 +152,8 @@ static void print_number(gchar *buffer, guint number, guint x, guint y, guint wi
     }
 }
 
-static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
+static void
+print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
 {
     guint number = priv->current_frame;
     guint divisor = 10000000;
@@ -160,7 +167,8 @@ static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
     }
 }
 
-static gpointer mock_grab_func(gpointer data)
+static gpointer
+mock_grab_func(gpointer data)
 {
     UcaMockCamera *mock_camera = UCA_MOCK_CAMERA(data);
     g_return_val_if_fail(UCA_IS_MOCK_CAMERA(mock_camera), NULL);
@@ -177,7 +185,8 @@ static gpointer mock_grab_func(gpointer data)
     return NULL;
 }
 
-static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
+static void
+uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
 {
     gboolean transfer_async = FALSE;
     UcaMockCameraPrivate *priv;
@@ -207,7 +216,8 @@ static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
     }
 }
 
-static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
+static void
+uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
 {
     gboolean transfer_async = FALSE;
     UcaMockCameraPrivate *priv;
@@ -227,11 +237,13 @@ static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
     }
 }
 
-static void uca_mock_camera_trigger (UcaCamera *camera, GError **error)
+static void
+uca_mock_camera_trigger (UcaCamera *camera, GError **error)
 {
 }
 
-static void uca_mock_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+static void
+uca_mock_camera_grab (UcaCamera *camera, gpointer *data, GError **error)
 {
     g_return_if_fail(UCA_IS_MOCK_CAMERA(camera));
     g_return_if_fail(data != NULL);
@@ -246,7 +258,8 @@ static void uca_mock_camera_grab(UcaCamera *camera, gpointer *data, GError **err
     priv->current_frame++;
 }
 
-static void uca_mock_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+static void
+uca_mock_camera_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 {
     g_return_if_fail(UCA_IS_MOCK_CAMERA(object));
     UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
@@ -279,7 +292,8 @@ static void uca_mock_camera_set_property(GObject *object, guint property_id, con
     }
 }
 
-static void uca_mock_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+static void
+uca_mock_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
 {
     UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
 
@@ -350,7 +364,8 @@ static void uca_mock_camera_get_property(GObject *object, guint property_id, GVa
     }
 }
 
-static void uca_mock_camera_finalize(GObject *object)
+static void
+uca_mock_camera_finalize(GObject *object)
 {
     UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
 
@@ -365,7 +380,23 @@ static void uca_mock_camera_finalize(GObject *object)
     G_OBJECT_CLASS(uca_mock_camera_parent_class)->finalize(object);
 }
 
-static void uca_mock_camera_class_init(UcaMockCameraClass *klass)
+static gboolean
+ufo_mock_camera_initable_init (GInitable *initable,
+                               GCancellable *cancellable,
+                               GError **error)
+{
+    g_return_val_if_fail (UCA_IS_MOCK_CAMERA (initable), FALSE);
+    return TRUE;
+}
+
+static void
+uca_mock_initable_iface_init (GInitableIface *iface)
+{
+    iface->init = ufo_mock_camera_initable_init;
+}
+
+static void
+uca_mock_camera_class_init(UcaMockCameraClass *klass)
 {
     GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
     gobject_class->set_property = uca_mock_camera_set_property;
@@ -394,7 +425,8 @@ static void uca_mock_camera_class_init(UcaMockCameraClass *klass)
     g_type_class_add_private(klass, sizeof(UcaMockCameraPrivate));
 }
 
-static void uca_mock_camera_init(UcaMockCamera *self)
+static void
+uca_mock_camera_init(UcaMockCamera *self)
 {
     self->priv = UCA_MOCK_CAMERA_GET_PRIVATE(self);
     self->priv->roi_x = 0;
@@ -415,9 +447,8 @@ static void uca_mock_camera_init(UcaMockCamera *self)
     uca_camera_register_unit (UCA_CAMERA (self), "frame-rate", UCA_UNIT_COUNT);
 }
 
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
 {
-    UcaCamera *camera = UCA_CAMERA (g_object_new (UCA_TYPE_MOCK_CAMERA, NULL));
-    return camera;
+    return UCA_TYPE_MOCK_CAMERA;
 }
diff --git a/plugins/mock/uca-mock-camera.h b/plugins/mock/uca-mock-camera.h
index 9ee9190..bfbd166 100644
--- a/plugins/mock/uca-mock-camera.h
+++ b/plugins/mock/uca-mock-camera.h
@@ -58,8 +58,6 @@ struct _UcaMockCameraClass {
     UcaCameraClass parent;
 };
 
-GType uca_mock_camera_get_type(void);
-
 G_END_DECLS
 
 #endif
diff --git a/plugins/pf/uca-pf-camera.c b/plugins/pf/uca-pf-camera.c
index 473ffd3..085fde5 100644
--- a/plugins/pf/uca-pf-camera.c
+++ b/plugins/pf/uca-pf-camera.c
@@ -15,6 +15,7 @@
    with this library; if not, write to the Free Software Foundation, Inc., 51
    Franklin St, Fifth Floor, Boston, MA 02110, USA */
 
+#include <gio/gio.h>
 #include <gmodule.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -32,7 +33,6 @@
             g_set_error(error, UCA_PF_CAMERA_ERROR,         \
                     UCA_PF_CAMERA_ERROR_FG_GENERAL,         \
                     "%s", Fg_getLastErrorDescription(fg));  \
-            g_object_unref(camobj);                         \
             return NULL;                                    \
         } }
 
@@ -46,7 +46,11 @@
 
 #define UCA_PF_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PF_CAMERA, UcaPfCameraPrivate))
 
-G_DEFINE_TYPE(UcaPfCamera, uca_pf_camera, UCA_TYPE_CAMERA)
+static void uca_pf_camera_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaPfCamera, uca_pf_camera, UCA_TYPE_CAMERA,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                                uca_pf_camera_initable_iface_init))
 
 /**
  * UcaPfCameraError:
@@ -91,6 +95,7 @@ enum {
 
 
 struct _UcaPfCameraPrivate {
+    GError *construct_error;
     guint roi_width;
     guint roi_height;
     guint last_frame;
@@ -107,7 +112,8 @@ struct {
     UcaCamera *camera;
 } fg_apc_data;
 
-static int me4_callback(frameindex_t frame, struct fg_apc_data *apc)
+static int
+me4_callback(frameindex_t frame, struct fg_apc_data *apc)
 {
     UcaCamera *camera = UCA_CAMERA(apc);
     UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
@@ -115,7 +121,8 @@ static int me4_callback(frameindex_t frame, struct fg_apc_data *apc)
     return 0;
 }
 
-static void uca_pf_camera_start_recording(UcaCamera *camera, GError **error)
+static void
+uca_pf_camera_start_recording(UcaCamera *camera, GError **error)
 {
     g_return_if_fail(UCA_IS_PF_CAMERA(camera));
     UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
@@ -155,7 +162,8 @@ static void uca_pf_camera_start_recording(UcaCamera *camera, GError **error)
     FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_ACQUISITION);
 }
 
-static void uca_pf_camera_stop_recording(UcaCamera *camera, GError **error)
+static void
+uca_pf_camera_stop_recording(UcaCamera *camera, GError **error)
 {
     g_return_if_fail(UCA_IS_PF_CAMERA(camera));
     UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
@@ -168,14 +176,16 @@ static void uca_pf_camera_stop_recording(UcaCamera *camera, GError **error)
         g_print(" Unable to unblock all\n");
 }
 
-static void uca_pf_camera_start_readout(UcaCamera *camera, GError **error)
+static void
+uca_pf_camera_start_readout(UcaCamera *camera, GError **error)
 {
     g_return_if_fail(UCA_IS_PF_CAMERA(camera));
     g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_IMPLEMENTED,
             "This photon focus camera does not support recording to internal memory");
 }
 
-static void uca_pf_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+static void
+uca_pf_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
 {
     g_return_if_fail(UCA_IS_PF_CAMERA(camera));
     UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
@@ -195,7 +205,8 @@ static void uca_pf_camera_grab(UcaCamera *camera, gpointer *data, GError **error
     memcpy((gchar *) *data, (gchar *) frame, priv->roi_width * priv->roi_height);
 }
 
-static void uca_pf_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+static void
+uca_pf_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 {
     switch (property_id) {
         default:
@@ -204,7 +215,8 @@ static void uca_pf_camera_set_property(GObject *object, guint property_id, const
     }
 }
 
-static void uca_pf_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+static void
+uca_pf_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
 {
     switch (property_id) {
         case PROP_SENSOR_WIDTH:
@@ -263,7 +275,8 @@ static void uca_pf_camera_get_property(GObject *object, guint property_id, GValu
     }
 }
 
-static void uca_pf_camera_finalize(GObject *object)
+static void
+uca_pf_camera_finalize(GObject *object)
 {
     UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(object);
 
@@ -274,10 +287,54 @@ static void uca_pf_camera_finalize(GObject *object)
         Fg_FreeGrabber(priv->fg);
     }
 
+    g_clear_error (&priv->construct_error);
+
     G_OBJECT_CLASS(uca_pf_camera_parent_class)->finalize(object);
 }
 
-static void uca_pf_camera_class_init(UcaPfCameraClass *klass)
+static gboolean
+uca_pf_camera_initable_init (GInitable *initable,
+                             GCancellable *cancellable,
+                             GError **error)
+{
+    UcaPfCamera *camera;
+    UcaPfCameraPrivate *priv;
+
+    g_return_val_if_fail (UCA_IS_PF_CAMERA (initable), FALSE);
+
+    if (cancellable != NULL) {
+        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                             "Cancellable initialization not supported");
+        return FALSE;
+    }
+
+    camera = UCA_PF_CAMERA (initable);
+    priv = camera->priv;
+
+    if (priv->construct_error != NULL) {
+        if (error)
+            *error = g_error_copy (priv->construct_error);
+
+        return FALSE;
+    }
+
+    if (priv->fg == NULL) {
+        g_set_error (error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT,
+                     "%s", Fg_getLastErrorDescription (NULL));
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void
+uca_pf_camera_initable_iface_init (GInitableIface *iface)
+{
+    iface->init = uca_pf_camera_initable_init;
+}
+
+static void
+uca_pf_camera_class_init(UcaPfCameraClass *klass)
 {
     GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
     gobject_class->set_property = uca_pf_camera_set_property;
@@ -296,57 +353,56 @@ static void uca_pf_camera_class_init(UcaPfCameraClass *klass)
     g_type_class_add_private(klass, sizeof(UcaPfCameraPrivate));
 }
 
-static void uca_pf_camera_init(UcaPfCamera *self)
+static gboolean
+try_fg_param (UcaPfCameraPrivate *priv,
+              int param,
+              const gpointer value)
 {
-    self->priv = UCA_PF_CAMERA_GET_PRIVATE(self);
-    self->priv->fg = NULL;
-    self->priv->fg_mem = NULL;
-    self->priv->last_frame = 0;
+    if (Fg_setParameter (priv->fg, param, value, priv->fg_port) != FG_OK) {
+        g_set_error (&priv->construct_error, UCA_PF_CAMERA_ERROR,
+                     UCA_PF_CAMERA_ERROR_FG_GENERAL,
+                     "%s", Fg_getLastErrorDescription (priv->fg));
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
+static void
+uca_pf_camera_init (UcaPfCamera *self)
 {
+    UcaPfCameraPrivate *priv;
     static const gchar *so_file = "libFullAreaGray8.so";
-    static const int camera_link_type = FG_CL_8BIT_FULL_8;
-    static const int camera_format = FG_GRAY;
-
-    /*
-    gint num_ports;
-    if (pfPortInit(&num_ports) < 0) {
-        g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT,
-                "Could not initialize ports");
-        return NULL;
-    }
+    static const int link_type = FG_CL_8BIT_FULL_8;
+    static const int format = FG_GRAY;
 
-    if (pfDeviceOpen(0) < 0) {
-        g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT,
-                "Could not open device");
-        return NULL;
-    }
-    */
-
-    UcaPfCamera *camera = g_object_new(UCA_TYPE_PF_CAMERA, NULL);
-    UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
+    self->priv = priv = UCA_PF_CAMERA_GET_PRIVATE(self);
 
+    priv->construct_error = NULL;
     priv->fg_port = PORT_A;
-    priv->fg = Fg_Init(so_file, priv->fg_port);
-
-    /* TODO: get this from the camera */
+    priv->fg = Fg_Init (so_file, priv->fg_port);
+    priv->fg_mem = NULL;
+    priv->last_frame = 0;
     priv->roi_width = 1280;
     priv->roi_height = 1024;
 
-    if (priv->fg == NULL) {
-        g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT,
-                "%s", Fg_getLastErrorDescription(priv->fg));
-        g_object_unref(camera);
-        return NULL;
-    }
+    if (priv->fg != NULL) {
+        if (!try_fg_param (priv, FG_CAMERA_LINK_CAMTYP, (const gpointer) &link_type))
+            return;
 
-    FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &camera_link_type, priv->fg_port);
-    FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &camera_format, priv->fg_port);
-    FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &priv->roi_width, priv->fg_port);
-    FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &priv->roi_height, priv->fg_port);
+        if (!try_fg_param (priv, FG_FORMAT, (const gpointer) &format))
+            return;
 
-    return UCA_CAMERA (camera);
+        if (!try_fg_param (priv, FG_WIDTH, &priv->roi_width))
+            return;
+
+        if (!try_fg_param (priv, FG_HEIGHT, &priv->roi_height))
+            return;
+    }
+}
+
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
+{
+    return UCA_TYPE_PF_CAMERA;
 }
diff --git a/src/uca-plugin-manager.c b/src/uca-plugin-manager.c
index e99f478..e1bfb9e 100644
--- a/src/uca-plugin-manager.c
+++ b/src/uca-plugin-manager.c
@@ -32,6 +32,7 @@
  *
  * @Since: 1.1
  */
+#include <gio/gio.h>
 #include <gmodule.h>
 #include "uca-plugin-manager.h"
 
@@ -45,7 +46,7 @@ struct _UcaPluginManagerPrivate {
 
 static const gchar *MODULE_PATTERN = "libuca([A-Za-z]+)";
 
-typedef UcaCamera * (*GetCameraFunc) (GError **error);
+typedef GType (*GetTypeFunc) (void);
 
 /**
  * UcaPluginManagerError:
@@ -217,20 +218,25 @@ find_camera_module_path (GList *search_paths, const gchar *name)
  * Create a new camera instance with camera @name.
  *
  * Returns: (transfer full): A new #UcaCamera object.
+ * @Since: 1.2: Pass construction properties.
  */
 UcaCamera *
-uca_plugin_manager_get_camera (UcaPluginManager   *manager,
-                               const gchar        *name,
-                               GError            **error)
+uca_plugin_manager_get_camera (UcaPluginManager *manager,
+                               const gchar *name,
+                               GError **error,
+                               const gchar *first_prop_name,
+                               ...)
 {
     UcaPluginManagerPrivate *priv;
     UcaCamera *camera;
     GModule *module;
-    GetCameraFunc *func;
     gchar *module_path;
+    GetTypeFunc *func;
+    GType type;
+    va_list var_args;
     GError *tmp_error = NULL;
 
-    const gchar *symbol_name = "uca_camera_impl_new";
+    const gchar *symbol_name = "uca_camera_get_type";
 
     g_return_val_if_fail (UCA_IS_PLUGIN_MANAGER (manager) && (name != NULL), NULL);
 
@@ -252,7 +258,7 @@ uca_plugin_manager_get_camera (UcaPluginManager   *manager,
         return NULL;
     }
 
-    func = g_malloc0 (sizeof (GetCameraFunc));
+    func = g_malloc0 (sizeof (GetTypeFunc));
 
     if (!g_module_symbol (module, symbol_name, (gpointer *) func)) {
         g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND,
@@ -265,7 +271,12 @@ uca_plugin_manager_get_camera (UcaPluginManager   *manager,
         return NULL;
     }
 
-    camera = (*func) (&tmp_error);
+    type = (*func) ();
+
+    va_start (var_args, first_prop_name);
+    camera = (UcaCamera *) g_initable_new (type, NULL, &tmp_error,
+                                           first_prop_name, var_args);
+    va_end (var_args);
 
     if (tmp_error != NULL) {
         g_propagate_error (error, tmp_error);
diff --git a/src/uca-plugin-manager.h b/src/uca-plugin-manager.h
index 6c3ab4e..3103684 100644
--- a/src/uca-plugin-manager.h
+++ b/src/uca-plugin-manager.h
@@ -57,7 +57,9 @@ GList               *uca_plugin_manager_get_available_cameras
                                                     (UcaPluginManager   *manager);
 UcaCamera           *uca_plugin_manager_get_camera  (UcaPluginManager   *manager,
                                                      const gchar        *name,
-                                                     GError            **error);
+                                                     GError            **error,
+                                                     const gchar        *first_prop_name,
+                                                     ...);
 GType                uca_plugin_manager_get_type    (void);
 
 G_END_DECLS
diff --git a/test/test-mock.c b/test/test-mock.c
index 50997f2..7876f5b 100644
--- a/test/test-mock.c
+++ b/test/test-mock.c
@@ -31,7 +31,8 @@ fixture_setup (Fixture *fixture, gconstpointer data)
     g_free (plugin_path);
 
     fixture->manager = uca_plugin_manager_new ();
-    fixture->camera = uca_plugin_manager_get_camera (fixture->manager, "mock", &error);
+    fixture->camera = uca_plugin_manager_get_camera (fixture->manager,
+                                                     "mock", &error, NULL);
     g_assert (error == NULL);
     g_assert (fixture->camera);
 }
@@ -54,7 +55,8 @@ static void
 test_factory (Fixture *fixture, gconstpointer data)
 {
     GError *error = NULL;
-    UcaCamera *camera = uca_plugin_manager_get_camera (fixture->manager, "fox994m3a0yxmy", &error);
+    UcaCamera *camera = uca_plugin_manager_get_camera (fixture->manager,
+                                                       "fox994m3a0yxmy", &error, NULL);
     g_assert_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND);
     g_assert (camera == NULL);
 }
diff --git a/tools/benchmark.c b/tools/benchmark.c
index e062e61..170a96c 100644
--- a/tools/benchmark.c
+++ b/tools/benchmark.c
@@ -140,7 +140,6 @@ grab_frames_async (UcaCamera *camera, gpointer buffer, guint n_frames)
         ;
 
     uca_camera_stop_recording (camera, &error);
-
 }
 
 static void
@@ -255,7 +254,7 @@ main (int argc, char *argv[])
     g_log_set_handler (NULL, G_LOG_LEVEL_MASK, log_handler, log_channel);
 
     manager = uca_plugin_manager_new ();
-    camera = uca_plugin_manager_get_camera (manager, argv[1], &error);
+    camera = uca_plugin_manager_get_camera (manager, argv[1], &error, NULL);
 
     if (camera == NULL) {
         g_error ("Initialization: %s", error->message);
diff --git a/tools/gen-doc.c b/tools/gen-doc.c
index eb61cc9..d27bdd8 100644
--- a/tools/gen-doc.c
+++ b/tools/gen-doc.c
@@ -205,7 +205,7 @@ int main(int argc, char *argv[])
     }
     else {
         name = argv[1];
-        camera = uca_plugin_manager_get_camera (manager, name, &error);
+        camera = uca_plugin_manager_get_camera (manager, name, &error, NULL);
     }
 
     if (camera == NULL) {
diff --git a/tools/grab-async.c b/tools/grab-async.c
index 2c4bf04..00f2879 100644
--- a/tools/grab-async.c
+++ b/tools/grab-async.c
@@ -94,7 +94,7 @@ main(int argc, char *argv[])
     }
 
     manager = uca_plugin_manager_new ();
-    camera = uca_plugin_manager_get_camera (manager, argv[1], &error);
+    camera = uca_plugin_manager_get_camera (manager, argv[1], &error, NULL);
 
     if (camera == NULL) {
         g_print("Error during initialization: %s\n", error->message);
diff --git a/tools/grab.c b/tools/grab.c
index 1518997..b020279 100644
--- a/tools/grab.c
+++ b/tools/grab.c
@@ -75,7 +75,7 @@ int main(int argc, char *argv[])
     }
 
     manager = uca_plugin_manager_new ();
-    camera = uca_plugin_manager_get_camera (manager, argv[1], &error);
+    camera = uca_plugin_manager_get_camera (manager, argv[1], &error, NULL);
 
     if (camera == NULL) {
         g_print("Error during initialization: %s\n", error->message);
diff --git a/tools/gui/control.c b/tools/gui/control.c
index c2ea59c..192859c 100644
--- a/tools/gui/control.c
+++ b/tools/gui/control.c
@@ -456,7 +456,7 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
     guint width, height;
     GError  *error = NULL;
 
-    camera = uca_plugin_manager_get_camera (plugin_manager, camera_name, &error);
+    camera = uca_plugin_manager_get_camera (plugin_manager, camera_name, &error, NULL);
 
     if ((camera == NULL) || (error != NULL)) {
         g_error ("%s\n", error->message);
diff --git a/tools/perf-overhead.c b/tools/perf-overhead.c
index 6735e6f..7661dbc 100644
--- a/tools/perf-overhead.c
+++ b/tools/perf-overhead.c
@@ -163,7 +163,7 @@ main (int argc, char *argv[])
     }
 
     manager = uca_plugin_manager_new ();
-    camera = uca_plugin_manager_get_camera (manager, argv[1], &error);
+    camera = uca_plugin_manager_get_camera (manager, argv[1], &error, NULL);
 
     if (camera == NULL) {
         g_print ("Error during initialization: %s\n", error->message);
-- 
cgit v1.2.3