diff options
| author | Matthias Vogelgesang <matthias.vogelgesang@gmail.com> | 2012-09-21 14:29:50 +0200 | 
|---|---|---|
| committer | Matthias Vogelgesang <matthias.vogelgesang@gmail.com> | 2012-09-21 14:29:50 +0200 | 
| commit | 6eaadaa0e4ad8ce906aa8ccee63d91f0d9cb28ea (patch) | |
| tree | 1b37a1eb40ad1fdec0a2bebc167f7f8128497748 | |
| parent | e6a6eb9aede59a1f7441b926b36afefd9c42b91d (diff) | |
| parent | 9f262857d13a3e0d7ee214b33b90359c51227718 (diff) | |
Merge branch 'plugins'
| -rw-r--r-- | NEWS | 20 | ||||
| -rw-r--r-- | docs/manual.md | 43 | ||||
| -rw-r--r-- | docs/style.css | 95 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 113 | ||||
| -rw-r--r-- | src/cameras/uca-mock-camera.c | 30 | ||||
| -rw-r--r-- | src/cameras/uca-mock-camera.h | 2 | ||||
| -rw-r--r-- | src/cameras/uca-pco-camera.c | 304 | ||||
| -rw-r--r-- | src/cameras/uca-pco-camera.h | 2 | ||||
| -rw-r--r-- | src/cameras/uca-pf-camera.c | 102 | ||||
| -rw-r--r-- | src/cameras/uca-pf-camera.h | 2 | ||||
| -rw-r--r-- | src/cameras/uca-ufo-camera.c | 6 | ||||
| -rw-r--r-- | src/cameras/uca-ufo-camera.h | 2 | ||||
| -rw-r--r-- | src/uca-camera.c | 122 | ||||
| -rw-r--r-- | src/uca-plugin-manager.c | 327 | ||||
| -rw-r--r-- | src/uca-plugin-manager.h | 65 | ||||
| -rw-r--r-- | test/CMakeLists.txt | 18 | ||||
| -rw-r--r-- | test/benchmark.c | 32 | ||||
| -rw-r--r-- | test/control.c | 234 | ||||
| -rw-r--r-- | test/enum.c | 88 | ||||
| -rw-r--r-- | test/grab-async.c | 44 | ||||
| -rw-r--r-- | test/grab.c | 40 | ||||
| -rw-r--r-- | test/grab_pylon.c | 96 | ||||
| -rwxr-xr-x | test/run.py | 31 | ||||
| -rw-r--r-- | test/test-mock.c | 181 | 
24 files changed, 1107 insertions, 892 deletions
@@ -1,3 +1,23 @@ +Changes in libuca 1.1 +===================== + +Plugin System +------------- + +A new plugin manager is used to instantiate camera objects from a shared +library. Instead of calling `uca_camera_new`, a plugin manager is created that +looks in pre- and user-defined directories for DSOs that match +`libuca[A-Za-z].so` and used to instantiate: + +    UcaPluginManager *manager; +    UcaCamera *camera; + +    manager = uca_plugin_manager_new (); +    camera = uca_plugin_manager_new_camera (manager, "foo", &error); + +The plugin manager adds a dependency on GModule (pkg-config package +`gmodule-2.0`) that is part of GLib. +  Changes in libuca 1.0 aka 0.6  ============================= diff --git a/docs/manual.md b/docs/manual.md index 0373010..5600d3f 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -107,6 +107,7 @@ necessary header files:  ~~~ {.c}  #include <glib-object.h> +#include <uca-plugin-manager.h>  #include <uca-camera.h>  ~~~ @@ -116,6 +117,7 @@ Then you need to setup the type system:  int  main (int argc, char *argv[])  { +    UcaPluginManager *manager;      UcaCamera *camera;      GError *error = NULL; /* this _must_ be set to NULL */ @@ -124,10 +126,12 @@ main (int argc, char *argv[])  Now you can instantiate new camera _objects_. Each camera is identified by a  human-readable string, in this case we want to access any pco camera that is -supported by [libpco][]: +supported by [libpco][]. To instantiate a camera we have to create a plugin +manager first:  ~~~ {.c} -    camera = uca_camera_new ("pco", &error); +    manager = uca_plugin_manager_new (); +    camera = uca_plugin_manager_new_camera (manager, "pco", &error);  ~~~  Errors are indicated with a returned value `NULL` and `error` set to a value @@ -252,38 +256,19 @@ communicate with the camera. Now we will go into more detail.  We have already seen how to instantiate a camera object from a name. If you have  more than one camera connected to a machine, you will most likely want the user  decide which to use. To do so, you can enumerate all camera strings with -`uca_camera_get_types`: +`uca_plugin_manager_get_available_cameras`:  ~~~ {.c} -    gchar **types; +    GList *types; -    types = uca_camera_get_types (); +    types = uca_camera_get_available_cameras (manager); -    for (guint i = 0; types[i] != NULL; i++) -        g_print ("%s\n", types[i]); +    for (GList *it = g_list_first; it != NULL; it = g_list_next (it)) +        g_print ("%s\n", (gchar *) it->data); -    /* free the string array */ -    g_strfreev (types); -~~~ - -If you _know_ which camera you want to use you can instantiate the sub-classed -camera object directly. In this case we create a pco-based camera: - -~~~ {.c} -#include <glib-object.h> -#include <uca/uca-camera-pco.h> - -int -main (int argc, char *argv[]) -{ -    UcaPcoCamera *camera; -    GError *error = NULL; - -    g_type_init (); -    camera = uca_pco_camera_new (&error); -    g_object_unref (camera); -    return 0; -} +    /* free the strings and the list */ +    g_list_foreach (types, (GFunc) g_free, NULL); +    g_list_free (types);  ~~~  [last section]: #first-look-at-the-api diff --git a/docs/style.css b/docs/style.css index a9fc9ca..646a097 100644 --- a/docs/style.css +++ b/docs/style.css @@ -1,35 +1,34 @@ -  /* --- Reset ------------------------------------------------------ */  body, div, dl, dt, dd, ul, ol, li,  h1, h2, h3, h4, h5, h6,  pre, form, fieldset, input, textarea, -p, blockquote, th, td {  -  margin: 0; +p, blockquote, th, td { +    margin: 0;      padding: 0;  }  table { -  border-collapse: collapse; +    border-collapse: collapse;      border-spacing: 0;  }  fieldset, img { -  border: 0; -  } -  address, caption, cite, dfn, th, var { +    border: 0; +} +address, caption, cite, dfn, th, var {      font-style: normal; -  font-weight: normal; -  } -  caption, th { +    font-weight: normal; +} +caption, th {      text-align: left;  }  h1, h2, h3, h4, h5, h6 { -  font-size: 100%; +    font-size: 100%;      font-weight: normal;  }  q:before, q:after { -  content: ''; -  } -  abbr, acronym { +    content: ''; +} +abbr, acronym {      border: 0;  } @@ -52,10 +51,6 @@ p {      margin-bottom: 24px;  } -/* p > code { */ -/*     font-size: 0.8em; */ -/* } */ -  h1, h2, h3, h4, h5, h6 {      margin-bottom: 24px;      font-family: "Droid Sans", sans-serif; @@ -65,6 +60,9 @@ h1, h2, h3, h4, h5, h6 {  h1 {      font-size: 1.5em;      line-height: 1em; +    margin-top: 2em; +    padding-bottom: 0.5em; +    border-bottom: 2px dotted #bbb;  }  h2 { @@ -87,11 +85,29 @@ h5, h6 {      line-height: 1.5em;  } -h1 > a, h2 > a, h3 > a, h4 > a, h5 > a, h6 > a { -    color: black; +h1 > a { +    color: #555; +    text-decoration: none; +} + +a { +    color: #8e3557;      text-decoration: none;  } +a:hover { +    color: #88a33e; +} + +h1:hover :after, +h2:hover :after, +h3:hover :after, +h4:hover :after, +h5:hover :after, +h6:hover :after { +    content: " \2191"; +} +  pre {      margin-bottom: 24px;      line-height: 1.2em; @@ -103,19 +119,58 @@ code {  }  ul, ol { +    list-style-position: inside; +    padding-left: 1em; +    text-indent: -1em; +    margin-left: 0;      margin-bottom: 24px;  } +li + li { +    margin-top: 0.1em; +} +  ul ul,  ol ol {      margin: 0 0 0 24px;  } +table { +    width: 100%; +    margin-bottom: 24px; +} + +th { +    color: #555; +    font-family: 'Droid Sans', sans-serif; +    font-weight: bold; +    border-bottom: 1px dotted #bbb; +} + +td, th { +    padding: 2px; +} + +dl { +    margin-bottom: 24px; +} + +dt { +    font-style: italic; +} + +dd { +    margin-top: 12px; +    padding-left: 1em; +} +  .title {      font-size: xx-large; +    color: #555;  }  .author {      font-size: 1.25em;      font-weight: normal; +    color: #555;  } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9508c5c..e186975 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,13 +3,17 @@ cmake_minimum_required(VERSION 2.8)  # --- Set sources -------------------------------------------------------------  set(uca_SRCS      uca-camera.c +    uca-plugin-manager.c      )  set(uca_HDRS -    uca-camera.h) +    uca-camera.h +    uca-plugin-manager.h)  set(cameras) +set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}") +  # --- Find packages and libraries ---------------------------------------------  set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) @@ -28,10 +32,25 @@ find_package(PkgConfig)  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) + +include_directories( +    ${CMAKE_CURRENT_BINARY_DIR} +    ${CMAKE_CURRENT_SOURCE_DIR} +    ${CMAKE_CURRENT_SOURCE_DIR}/cameras +    ${GLIB2_INCLUDE_DIRS} +    ${GOBJECT2_INCLUDE_DIRS}) + +# --- Configure step +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in +    ${CMAKE_CURRENT_BINARY_DIR}/config.h)  set(uca_LIBS -    ${GLIB2_LIBRARIES}  -    ${GOBJECT2_LIBRARIES}) +    ${GLIB2_LIBRARIES} +    ${GOBJECT2_LIBRARIES} +    ${GMODULE2_LIBRARIES}) + +set(uca_enum_hdrs uca-camera.h)  # --- Build options -----------------------------------------------------------  option(HAVE_MOCK_CAMERA "Camera: Dummy" ON) @@ -42,18 +61,20 @@ if (PF_FOUND)      option(HAVE_PHOTON_FOCUS "Camera: Photon Focus MV2-D1280-640-CL-8" ON)      if (HAVE_PHOTON_FOCUS AND CLSERME4_FOUND AND FGLIB5_FOUND) -        list(APPEND uca_SRCS cameras/uca-pf-camera.c) -        list(APPEND uca_HDRS cameras/uca-pf-camera.h) -        list(APPEND cameras "Pf") - -        set(uca_LIBS ${uca_LIBS}  -            ${CLSERME4_LIBRARY}  -            ${FGLIB5_LIBRARY}  -            ${PF_LIBRARIES}) +        list(APPEND uca_enum_hdrs cameras/uca-pf-camera.h) -        include_directories(${PF_INCLUDE_DIRS} +        include_directories( +            ${PF_INCLUDE_DIRS}              ${CLSERME4_INCLUDE_DIR}              ${FGLIB5_INCLUDE_DIR}) + +        add_library(ucapf SHARED cameras/uca-pf-camera.c) + +        target_link_libraries(ucapf +            ${uca_LIBS} +            ${CLSERME4_LIBRARY} +            ${FGLIB5_LIBRARY} +            ${PF_LIBRARIES})      endif()  endif() @@ -61,19 +82,23 @@ if (PCO_FOUND AND CLSERME4_FOUND AND FGLIB5_FOUND)      option(HAVE_PCO_CL "Camera: CameraLink-based pco" ON)      if (HAVE_PCO_CL) -        list(APPEND uca_SRCS cameras/uca-pco-camera.c) -        list(APPEND uca_HDRS cameras/uca-pco-camera.h) -        list(APPEND cameras "Pco") - -        set(uca_LIBS ${uca_LIBS} -            ${PCO_LIBRARIES} -            ${CLSERME4_LIBRARY} -            ${FGLIB5_LIBRARY}) +        list(APPEND uca_enum_hdrs cameras/uca-pco-camera.h)          include_directories(              ${PCO_INCLUDE_DIRS}              ${CLSERME4_INCLUDE_DIR}              ${FGLIB5_INCLUDE_DIR}) + +        add_library(ucapco SHARED cameras/uca-pco-camera.c) + +        target_link_libraries(ucapco +            ${uca_LIBS} +            ${PCO_LIBRARIES} +            ${CLSERME4_LIBRARY} +            ${FGLIB5_LIBRARY}) + +        install(TARGETS ucapco +            LIBRARY DESTINATION ${LIB_INSTALL_DIR}/uca)      endif()  endif() @@ -81,13 +106,18 @@ if (IPE_FOUND)      option(HAVE_UFO_CAMERA "Camera: Custom based on Xilinx FPGA" ON)      if (HAVE_UFO_CAMERA) -        list(APPEND uca_SRCS cameras/uca-ufo-camera.c) -        list(APPEND uca_HDRS cameras/uca-ufo-camera.h) -        list(APPEND cameras "Ufo") - -        set(uca_LIBS ${uca_LIBS} ${IPE_LIBRARIES}) +        list(APPEND uca_enum_hdrs cameras/uca-ufo-camera.h)          include_directories(${IPE_INCLUDE_DIRS}) + +        add_library(ucaufo SHARED cameras/uca-ufo-camera.c) +        target_link_libraries(ucaufo +            ${uca_LIBS} +            ${IPE_LIBRARIES} +            ) + +        install(TARGETS ucaufo +            LIBRARY DESTINATION ${LIB_INSTALL_DIR}/uca)      endif()  endif() @@ -107,9 +137,9 @@ if (PYLON_FOUND)  endif()  if (HAVE_MOCK_CAMERA) -    list(APPEND uca_SRCS cameras/uca-mock-camera.c) -    list(APPEND uca_HDRS cameras/uca-mock-camera.h) -    list(APPEND cameras "Mock") +    add_library(ucamock SHARED cameras/uca-mock-camera.c) +    install(TARGETS ucamock +        LIBRARY DESTINATION ${LIB_INSTALL_DIR}/uca)  endif()  # --- Generate enum file @@ -118,9 +148,9 @@ add_custom_command(      COMMAND ${GLIB2_MKENUMS}      ARGS          --template uca-enums.h.template -        ${uca_HDRS} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h +        ${uca_enum_hdrs} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -    DEPENDS ${uca_HDRS}  +    DEPENDS ${uca_enum_hdrs}              ${CMAKE_CURRENT_SOURCE_DIR}/uca-enums.h.template)  add_custom_command( @@ -128,29 +158,18 @@ add_custom_command(      COMMAND ${GLIB2_MKENUMS}      ARGS          --template uca-enums.c.template -        ${uca_HDRS} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c +        ${uca_enum_hdrs} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -    DEPENDS ${uca_HDRS}  +    DEPENDS ${uca_enum_hdrs}              ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h              ${CMAKE_CURRENT_SOURCE_DIR}/uca-enums.c.template      ) -# --- Configure step -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in -    ${CMAKE_CURRENT_BINARY_DIR}/config.h) - -include_directories( -    ${CMAKE_CURRENT_BINARY_DIR} -    ${CMAKE_CURRENT_SOURCE_DIR} -    ${CMAKE_CURRENT_SOURCE_DIR}/cameras -    ${GLIB2_INCLUDE_DIRS} -    ${GOBJECT2_INCLUDE_DIRS}) -  # --- Build target ------------------------------------------------------------  add_definitions("-std=c99 -Wall") -add_library(uca SHARED  -    ${uca_SRCS}  +add_library(uca SHARED +    ${uca_SRCS}      ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c)  set_target_properties(uca PROPERTIES @@ -171,7 +190,7 @@ if(GTK_DOC_FOUND)          set(docs_out "${docs_dir}/reference")          file(MAKE_DIRECTORY ${docs_out}) -        set(reference_files  +        set(reference_files              "${docs_out}/index.html"              "${docs_out}/api-index-full.html"              "${docs_out}/ch01.html" @@ -255,7 +274,7 @@ set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}")  install(TARGETS uca      LIBRARY DESTINATION ${LIB_INSTALL_DIR}) -install(FILES ${uca_HDRS}  +install(FILES ${uca_HDRS}      DESTINATION include/uca)  # --- install pkg-config file diff --git a/src/cameras/uca-mock-camera.c b/src/cameras/uca-mock-camera.c index 59c5ae8..7cd4689 100644 --- a/src/cameras/uca-mock-camera.c +++ b/src/cameras/uca-mock-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 <gmodule.h>  #include <string.h>  #include "uca-mock-camera.h" @@ -156,20 +157,6 @@ static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)      }  } -/** - * uca_mock_camera_new: - * @error: Location for error - * - * Create a new #UcaMockCamera object. - * - * Returns: A newly created #UcaMockCamera object - */ -UcaMockCamera *uca_mock_camera_new(GError **error) -{ -    UcaMockCamera *camera = g_object_new(UCA_TYPE_MOCK_CAMERA, NULL); -    return camera; -} -  static gpointer mock_grab_func(gpointer data)  {      UcaMockCamera *mock_camera = UCA_MOCK_CAMERA(data); @@ -208,7 +195,7 @@ static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error)      if (transfer_async) {          GError *tmp_error = NULL;          priv->thread_running = TRUE; -        priv->grab_thread = g_thread_create(mock_grab_func, camera, TRUE, &tmp_error);  +        priv->grab_thread = g_thread_create(mock_grab_func, camera, TRUE, &tmp_error);          if (tmp_error != NULL) {              priv->thread_running = FALSE; @@ -232,7 +219,7 @@ static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)              NULL);      if (transfer_async) { -        priv->thread_running = FALSE;     +        priv->thread_running = FALSE;          g_thread_join(priv->grab_thread);      }  } @@ -358,7 +345,7 @@ static void uca_mock_camera_finalize(GObject *object)      UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);      if (priv->thread_running) { -        priv->thread_running = FALSE;     +        priv->thread_running = FALSE;          g_thread_join(priv->grab_thread);      } @@ -383,7 +370,7 @@ static void uca_mock_camera_class_init(UcaMockCameraClass *klass)      for (guint i = 0; mock_overrideables[i] != 0; i++)          g_object_class_override_property(gobject_class, mock_overrideables[i], uca_camera_props[mock_overrideables[i]]); -    mock_properties[PROP_FRAMERATE] =  +    mock_properties[PROP_FRAMERATE] =          g_param_spec_float("frame-rate",                  "Frame rate",                  "Number of frames per second that are taken", @@ -413,3 +400,10 @@ static void uca_mock_camera_init(UcaMockCamera *self)      g_value_set_uint(&val, 1);      g_value_array_append(self->priv->binnings, &val);  } + +G_MODULE_EXPORT UcaCamera * +uca_camera_impl_new (GError **error) +{ +    UcaCamera *camera = UCA_CAMERA (g_object_new (UCA_TYPE_MOCK_CAMERA, NULL)); +    return camera; +} diff --git a/src/cameras/uca-mock-camera.h b/src/cameras/uca-mock-camera.h index 92030f8..9ee9190 100644 --- a/src/cameras/uca-mock-camera.h +++ b/src/cameras/uca-mock-camera.h @@ -58,8 +58,6 @@ struct _UcaMockCameraClass {      UcaCameraClass parent;  }; -UcaMockCamera *uca_mock_camera_new(GError **error); -  GType uca_mock_camera_get_type(void);  G_END_DECLS diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c index a56392f..8bf2936 100644 --- a/src/cameras/uca-pco-camera.c +++ b/src/cameras/uca-pco-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 <gmodule.h>  #include <stdlib.h>  #include <stdio.h>  #include <string.h> @@ -50,7 +51,7 @@                  "libpco error %x", err);            \          return;                                     \      } -     +  #define UCA_PCO_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCameraPrivate))  G_DEFINE_TYPE(UcaPcoCamera, uca_pco_camera, UCA_TYPE_CAMERA) @@ -186,7 +187,7 @@ struct _UcaPcoCameraPrivate {      guint current_image;  }; -static pco_cl_map_entry pco_cl_map[] = {  +static pco_cl_map_entry pco_cl_map[] = {      { CAMERATYPE_PCO_EDGE,       "libFullAreaGray8.so",  FG_CL_8BIT_FULL_10,        FG_GRAY,     30.0f, FALSE },      { CAMERATYPE_PCO4000,        "libDualAreaGray16.so", FG_CL_SINGLETAP_16_BIT,    FG_GRAY16,    5.0f, TRUE  },      { CAMERATYPE_PCO_DIMAX_STD,  "libFullAreaGray16.so", FG_CL_SINGLETAP_8_BIT,     FG_GRAY16, 1279.0f, TRUE  }, @@ -200,7 +201,7 @@ static pco_cl_map_entry *get_pco_cl_map_entry(int camera_type)      while (entry->camera_type != 0) {          if (entry->camera_type == camera_type)              return entry; -        entry++;  +        entry++;      }      return NULL; @@ -212,8 +213,8 @@ static guint fill_binnings(UcaPcoCameraPrivate *priv)      uint16_t *vertical = NULL;      guint num_horizontal, num_vertical; -    guint err = pco_get_possible_binnings(priv->pco,  -            &horizontal, &num_horizontal,  +    guint err = pco_get_possible_binnings(priv->pco, +            &horizontal, &num_horizontal,              &vertical, &num_vertical);      GValue val = {0}; @@ -246,7 +247,7 @@ static void fill_pixelrates(UcaPcoCameraPrivate *priv, guint32 rates[4], gint nu      priv->pixelrates = g_value_array_new(num_rates);      for (gint i = 0; i < num_rates; i++) { -        g_value_set_uint(&val, (guint) rates[i]);  +        g_value_set_uint(&val, (guint) rates[i]);          g_value_array_append(priv->pixelrates, &val);      }  } @@ -315,93 +316,6 @@ static gdouble get_suitable_timebase(gdouble time)      return TIMEBASE_INVALID;  } -UcaPcoCamera *uca_pco_camera_new(GError **error) -{ -    pco_handle pco = pco_init(); - -    if (pco == NULL) { -        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_INIT, -                "Initializing libpco failed"); -        return NULL; -    } - -    UcaPcoCamera *camera = g_object_new(UCA_TYPE_PCO_CAMERA, NULL); -    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); -    priv->pco = pco; - -    pco_get_resolution(priv->pco, &priv->width, &priv->height, &priv->width_ex, &priv->height_ex); -    pco_get_binning(priv->pco, &priv->binning_h, &priv->binning_v); -    pco_set_storage_mode(pco, STORAGE_MODE_RECORDER); -    pco_set_auto_transfer(pco, 1); - -    guint16 roi[4]; -    pco_get_roi(priv->pco, roi); -    pco_get_roi_steps(priv->pco, &priv->roi_horizontal_steps, &priv->roi_vertical_steps); - -    priv->roi_x = roi[0] - 1; -    priv->roi_y = roi[1] - 1; -    priv->roi_width = roi[2] - roi[0] + 1; -    priv->roi_height = roi[3] - roi[1] + 1; - -    guint16 camera_type, camera_subtype; -    pco_get_camera_type(priv->pco, &camera_type, &camera_subtype); -    pco_cl_map_entry *map_entry = get_pco_cl_map_entry(camera_type); -    priv->camera_description = map_entry; - -    if (map_entry == NULL) { -        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, -                "Camera type is not supported"); -        g_object_unref(camera); -        return NULL; -    } - -    priv->fg_port = PORT_A; -    priv->fg = Fg_Init(map_entry->so_file, priv->fg_port); - -    if (priv->fg == NULL) { -        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_FG_INIT, -                "%s", Fg_getLastErrorDescription(priv->fg)); -        g_object_unref(camera); -        return NULL; -    } - -    const guint32 fg_height = priv->height; -    const guint32 fg_width = camera_type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width; - -    FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &map_entry->cl_type, priv->fg_port); -    FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &map_entry->cl_format, priv->fg_port); -    FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &fg_width, priv->fg_port); -    FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &fg_height, priv->fg_port); - -    int val = FREE_RUN; -    FG_TRY_PARAM(priv->fg, camera, FG_TRIGGERMODE, &val, priv->fg_port); - -    fill_binnings(priv); - -    /* -     * Here we override property ranges because we didn't know them at property -     * installation time. -     */ -    GObjectClass *camera_class = G_OBJECT_CLASS (UCA_CAMERA_GET_CLASS (camera)); -    property_override_default_guint_value (camera_class, "roi-width", priv->width); -    property_override_default_guint_value (camera_class, "roi-height", priv->height); - -    guint32 rates[4] = {0}; -    gint num_rates = 0; - -    if (pco_get_available_pixelrates(priv->pco, rates, &num_rates) == PCO_NOERROR) { -        GObjectClass *pco_camera_class = G_OBJECT_CLASS (UCA_PCO_CAMERA_GET_CLASS (camera)); - -        fill_pixelrates(priv, rates, num_rates); -        property_override_default_guint_value (pco_camera_class, "sensor-pixelrate", rates[0]); -    } - -    override_temperature_range (priv); -    override_maximum_adcs (priv); - -    return camera; -} -  static int fg_callback(frameindex_t frame, struct fg_apc_data *apc)  {      UcaCamera *camera = UCA_CAMERA(apc); @@ -506,7 +420,7 @@ static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error)              Fg_FreeMemEx(priv->fg, priv->fg_mem);          const guint num_buffers = 2; -        priv->fg_mem = Fg_AllocMemEx(priv->fg,  +        priv->fg_mem = Fg_AllocMemEx(priv->fg,                  num_buffers * priv->frame_width * priv->frame_height * sizeof(uint16_t), num_buffers);          if (priv->fg_mem == NULL) { @@ -557,9 +471,9 @@ static void uca_pco_camera_start_readout(UcaCamera *camera, GError **error)      g_return_if_fail(UCA_IS_PCO_CAMERA(camera));      UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); -    /*  +    /*       * TODO: Check if readout mode is possible. This is not the case for the -     * edge.  +     * edge.       */      guint err = pco_get_active_segment(priv->pco, &priv->active_segment); @@ -582,7 +496,7 @@ static void uca_pco_camera_trigger(UcaCamera *camera, GError **error)      if (!success)          g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL, -                "Could not trigger frame acquisition");  +                "Could not trigger frame acquisition");  }  static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error) @@ -611,7 +525,7 @@ static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **erro      pco_request_image(priv->pco);      priv->last_frame = Fg_getLastPicNumberBlockingEx(priv->fg, priv->last_frame+1, priv->fg_port, MAX_TIMEOUT, priv->fg_mem); -     +      if (priv->last_frame <= 0) {          guint err = FG_OK + 1;          FG_SET_ERROR(err, priv->fg, UCA_PCO_CAMERA_ERROR_FG_GENERAL); @@ -620,7 +534,7 @@ static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **erro      guint16 *frame = Fg_getImagePtrEx(priv->fg, priv->last_frame, priv->fg_port, priv->fg_mem);      if (*data == NULL) -        *data = g_malloc0(priv->frame_width * priv->frame_height * priv->num_bytes);  +        *data = g_malloc0(priv->frame_width * priv->frame_height * priv->num_bytes);      if (priv->camera_description->camera_type == CAMERATYPE_PCO_EDGE)          pco_get_reorder_func(priv->pco)((guint16 *) *data, frame, priv->frame_width, priv->frame_height); @@ -635,7 +549,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons      switch (property_id) {          case PROP_SENSOR_EXTENDED:              { -                guint16 format = g_value_get_boolean (value) ? SENSORFORMAT_EXTENDED : SENSORFORMAT_STANDARD;  +                guint16 format = g_value_get_boolean (value) ? SENSORFORMAT_EXTENDED : SENSORFORMAT_STANDARD;                  pco_set_sensor_format(priv->pco, format);              }              break; @@ -651,7 +565,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons          case PROP_ROI_WIDTH:              {                  guint width = g_value_get_uint(value); -                 +                  if (width % priv->roi_horizontal_steps)                      g_warning("ROI width %i is not a multiple of %i", width, priv->roi_horizontal_steps);                  else @@ -662,7 +576,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons          case PROP_ROI_HEIGHT:              {                  guint height = g_value_get_uint(value); -                 +                  if (height % priv->roi_vertical_steps)                      g_warning("ROI height %i is not a multiple of %i", height, priv->roi_vertical_steps);                  else @@ -681,7 +595,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons          case PROP_EXPOSURE_TIME:              {                  const gdouble time = g_value_get_double(value); -                  +                  if (priv->exposure_timebase == TIMEBASE_INVALID)                      read_timebase(priv); @@ -692,7 +606,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons                  guint16 suitable_timebase = get_suitable_timebase(time);                  if (suitable_timebase == TIMEBASE_INVALID) { -                    g_warning("Cannot set such a small exposure time");  +                    g_warning("Cannot set such a small exposure time");                  }                  else {                      if (suitable_timebase != priv->exposure_timebase) { @@ -712,7 +626,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons          case PROP_DELAY_TIME:              {                  const gdouble time = g_value_get_double(value); -                  +                  if (priv->delay_timebase == TIMEBASE_INVALID)                      read_timebase(priv); @@ -733,7 +647,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons                              g_warning("Cannot set zero delay time");                      }                      else -                        g_warning("Cannot set such a small exposure time");  +                        g_warning("Cannot set such a small exposure time");                  }                  else {                      if (suitable_timebase != priv->delay_timebase) { @@ -752,7 +666,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons          case PROP_SENSOR_ADCS:              { -                const guint num_adcs = g_value_get_uint(value);  +                const guint num_adcs = g_value_get_uint(value);                  if (pco_set_adc_mode(priv->pco, num_adcs) != PCO_NOERROR)                      g_warning("Cannot set the number of ADCs per pixel\n");              } @@ -765,7 +679,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons                  for (guint i = 0; i < priv->pixelrates->n_values; i++) {                      if (g_value_get_uint(g_value_array_get_nth(priv->pixelrates, i)) == desired_pixel_rate) { -                        pixel_rate = desired_pixel_rate;     +                        pixel_rate = desired_pixel_rate;                          break;                      }                  } @@ -792,7 +706,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons          case PROP_COOLING_POINT:              { -                int16_t temperature = (int16_t) g_value_get_int(value);  +                int16_t temperature = (int16_t) g_value_get_int(value);                  pco_set_cooling_temperature(priv->pco, temperature);              }              break; @@ -856,11 +770,11 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons          case PROP_TIMESTAMP_MODE:              {                  guint16 modes[] = { -                    TIMESTAMP_MODE_OFF,             /* 0 */  -                    TIMESTAMP_MODE_BINARY,          /* 1 = 1 << 0 */  -                    TIMESTAMP_MODE_ASCII,           /* 2 = 1 << 1 */  -                    TIMESTAMP_MODE_BINARYANDASCII,  /* 3 = 1 << 0 | 1 << 1 */  -                };  +                    TIMESTAMP_MODE_OFF,             /* 0 */ +                    TIMESTAMP_MODE_BINARY,          /* 1 = 1 << 0 */ +                    TIMESTAMP_MODE_ASCII,           /* 2 = 1 << 1 */ +                    TIMESTAMP_MODE_BINARYANDASCII,  /* 3 = 1 << 0 | 1 << 1 */ +                };                  pco_set_timestamp_mode(priv->pco, modes[g_value_get_flags(value)]);              }              break; @@ -878,25 +792,25 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal      switch (property_id) {          case PROP_SENSOR_EXTENDED:              { -                guint16 format;  +                guint16 format;                  pco_get_sensor_format(priv->pco, &format);                  g_value_set_boolean(value, format == SENSORFORMAT_EXTENDED);              }              break; -        case PROP_SENSOR_WIDTH:  +        case PROP_SENSOR_WIDTH:              g_value_set_uint(value, priv->width);              break; -        case PROP_SENSOR_HEIGHT:  +        case PROP_SENSOR_HEIGHT:              g_value_set_uint(value, priv->height);              break; -        case PROP_SENSOR_WIDTH_EXTENDED:  +        case PROP_SENSOR_WIDTH_EXTENDED:              g_value_set_uint(value, priv->width_ex < priv->width ? priv->width : priv->width_ex);              break; -        case PROP_SENSOR_HEIGHT_EXTENDED:  +        case PROP_SENSOR_HEIGHT_EXTENDED:              g_value_set_uint(value, priv->height_ex < priv->height ? priv->height : priv->height_ex);              break; @@ -926,7 +840,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal          case PROP_SENSOR_TEMPERATURE:              { -                gint32 ccd, camera, power;                  +                gint32 ccd, camera, power;                  pco_get_temperature(priv->pco, &ccd, &camera, &power);                  g_value_set_double(value, ccd / 10.0);              } @@ -938,7 +852,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal                   * Up to now, the ADC mode corresponds directly to the number of                   * ADCs in use.                   */ -                pco_adc_mode mode;  +                pco_adc_mode mode;                  if (pco_get_adc_mode(priv->pco, &mode) != PCO_NOERROR)                      g_warning("Cannot read number of ADCs per pixel");                  g_value_set_uint(value, mode); @@ -958,7 +872,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal          case PROP_SENSOR_PIXELRATE:              { -                guint32 pixelrate;  +                guint32 pixelrate;                  pco_get_pixelrate(priv->pco, &pixelrate);                  g_value_set_uint(value, pixelrate);              } @@ -1048,7 +962,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal          case PROP_TRIGGER_MODE:              { -                guint16 mode;                  +                guint16 mode;                  pco_get_trigger_mode(priv->pco, &mode);                  switch (mode) { @@ -1091,7 +1005,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal              g_value_set_uint(value, priv->roi_vertical_steps);              break; -        case PROP_NAME:  +        case PROP_NAME:              {                  gchar *name = NULL;                  pco_get_name(priv->pco, &name); @@ -1102,7 +1016,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal          case PROP_COOLING_POINT:              { -                int16_t temperature;  +                int16_t temperature;                  if (pco_get_cooling_temperature(priv->pco, &temperature) != PCO_NOERROR)                      g_warning("Cannot read cooling temperature\n");                  g_value_set_int(value, temperature); @@ -1140,7 +1054,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal          case PROP_TIMESTAMP_MODE:              { -                guint16 mode;  +                guint16 mode;                  pco_get_timestamp_mode(priv->pco, &mode);                  switch (mode) { @@ -1151,7 +1065,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal                          g_value_set_flags(value, UCA_PCO_CAMERA_TIMESTAMP_BINARY);                          break;                      case TIMESTAMP_MODE_BINARYANDASCII: -                        g_value_set_flags(value,  +                        g_value_set_flags(value,                                  UCA_PCO_CAMERA_TIMESTAMP_BINARY | UCA_PCO_CAMERA_TIMESTAMP_ASCII);                          break;                      case TIMESTAMP_MODE_ASCII: @@ -1220,20 +1134,20 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass)       * #UcaPcoCamera:sensor-height-extended to query the resolution of the       * larger area.       */ -    pco_properties[PROP_SENSOR_EXTENDED] =  +    pco_properties[PROP_SENSOR_EXTENDED] =          g_param_spec_boolean("sensor-extended",              "Use extended sensor format",              "Use extended sensor format",              FALSE, G_PARAM_READWRITE); -    pco_properties[PROP_SENSOR_WIDTH_EXTENDED] =  +    pco_properties[PROP_SENSOR_WIDTH_EXTENDED] =          g_param_spec_uint("sensor-width-extended",              "Width of extended sensor",              "Width of the extended sensor in pixels",              1, G_MAXUINT, 1,              G_PARAM_READABLE); -    pco_properties[PROP_SENSOR_HEIGHT_EXTENDED] =  +    pco_properties[PROP_SENSOR_HEIGHT_EXTENDED] =          g_param_spec_uint("sensor-height-extended",              "Height of extended sensor",              "Height of the extended sensor in pixels", @@ -1248,21 +1162,21 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass)       * #UcaPcoCamera:sensor-pixelrates property. Any other value will be       * rejected by the camera.       */ -    pco_properties[PROP_SENSOR_PIXELRATE] =  +    pco_properties[PROP_SENSOR_PIXELRATE] =          g_param_spec_uint("sensor-pixelrate",              "Pixel rate",              "Pixel rate",              1, G_MAXUINT, 1,              G_PARAM_READWRITE); -    pco_properties[PROP_SENSOR_PIXELRATES] =  +    pco_properties[PROP_SENSOR_PIXELRATES] =          g_param_spec_value_array("sensor-pixelrates",              "Array of possible sensor pixel rates",              "Array of possible sensor pixel rates",              pco_properties[PROP_SENSOR_PIXELRATE],              G_PARAM_READABLE); -    pco_properties[PROP_NAME] =  +    pco_properties[PROP_NAME] =          g_param_spec_string("name",              "Name of the camera",              "Name of the camera", @@ -1275,38 +1189,38 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass)              -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,              G_PARAM_READABLE); -    pco_properties[PROP_HAS_DOUBLE_IMAGE_MODE] =  +    pco_properties[PROP_HAS_DOUBLE_IMAGE_MODE] =          g_param_spec_boolean("has-double-image-mode",              "Is double image mode supported by this model",              "Is double image mode supported by this model",              FALSE, G_PARAM_READABLE); -    pco_properties[PROP_DOUBLE_IMAGE_MODE] =  +    pco_properties[PROP_DOUBLE_IMAGE_MODE] =          g_param_spec_boolean("double-image-mode",              "Use double image mode",              "Use double image mode",              FALSE, G_PARAM_READWRITE); -    pco_properties[PROP_OFFSET_MODE] =  +    pco_properties[PROP_OFFSET_MODE] =          g_param_spec_boolean("offset-mode",              "Use offset mode",              "Use offset mode",              FALSE, G_PARAM_READWRITE); -    pco_properties[PROP_RECORD_MODE] =  -        g_param_spec_enum("record-mode",  +    pco_properties[PROP_RECORD_MODE] = +        g_param_spec_enum("record-mode",              "Record mode",              "Record mode",              UCA_TYPE_PCO_CAMERA_RECORD_MODE, UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE,              G_PARAM_READWRITE); -    pco_properties[PROP_ACQUIRE_MODE] =  -        g_param_spec_enum("acquire-mode",  +    pco_properties[PROP_ACQUIRE_MODE] = +        g_param_spec_enum("acquire-mode",              "Acquire mode",              "Acquire mode",              UCA_TYPE_PCO_CAMERA_ACQUIRE_MODE, UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO,              G_PARAM_READWRITE); -     +      pco_properties[PROP_DELAY_TIME] =          g_param_spec_double("delay-time",              "Delay time", @@ -1314,7 +1228,7 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass)              0.0, G_MAXDOUBLE, 0.0,              G_PARAM_READWRITE); -    pco_properties[PROP_NOISE_FILTER] =  +    pco_properties[PROP_NOISE_FILTER] =          g_param_spec_boolean("noise-filter",              "Noise filter",              "Noise filter", @@ -1327,42 +1241,42 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass)       * the camera and just don't know the cooling range. We override these       * values in #uca_pco_camera_new().       */ -    pco_properties[PROP_COOLING_POINT] =  +    pco_properties[PROP_COOLING_POINT] =          g_param_spec_int("cooling-point",              "Cooling point of the camera",              "Cooling point of the camera in degree celsius",              0, 10, 5, G_PARAM_READWRITE); -    pco_properties[PROP_COOLING_POINT_MIN] =  +    pco_properties[PROP_COOLING_POINT_MIN] =          g_param_spec_int("cooling-point-min",              "Minimum cooling point",              "Minimum cooling point in degree celsius",              G_MININT, G_MAXINT, 0, G_PARAM_READABLE); -    pco_properties[PROP_COOLING_POINT_MAX] =  +    pco_properties[PROP_COOLING_POINT_MAX] =          g_param_spec_int("cooling-point-max",              "Maximum cooling point",              "Maximum cooling point in degree celsius",              G_MININT, G_MAXINT, 0, G_PARAM_READABLE); -    pco_properties[PROP_COOLING_POINT_DEFAULT] =  +    pco_properties[PROP_COOLING_POINT_DEFAULT] =          g_param_spec_int("cooling-point-default",              "Default cooling point",              "Default cooling point in degree celsius",              G_MININT, G_MAXINT, 0, G_PARAM_READABLE); -     -    pco_properties[PROP_SENSOR_ADCS] =  + +    pco_properties[PROP_SENSOR_ADCS] =          g_param_spec_uint("sensor-adcs",              "Number of ADCs to use",              "Number of ADCs to use", -            1, 2, 1,  +            1, 2, 1,              G_PARAM_READWRITE); -    pco_properties[PROP_SENSOR_MAX_ADCS] =  +    pco_properties[PROP_SENSOR_MAX_ADCS] =          g_param_spec_uint("sensor-max-adcs",              "Maximum number of ADCs",              "Maximum number of ADCs that can be set with \"sensor-adcs\"", -            1, G_MAXUINT, 1,  +            1, G_MAXUINT, 1,              G_PARAM_READABLE);      pco_properties[PROP_TIMESTAMP_MODE] = @@ -1394,3 +1308,91 @@ static void uca_pco_camera_init(UcaPcoCamera *self)      self->priv->delay_timebase = TIMEBASE_INVALID;      self->priv->exposure_timebase = TIMEBASE_INVALID;  } + +G_MODULE_EXPORT UcaCamera * +uca_camera_impl_new (GError **error) +{ +    pco_handle pco = pco_init(); + +    if (pco == NULL) { +        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_INIT, +                "Initializing libpco failed"); +        return NULL; +    } + +    UcaPcoCamera *camera = g_object_new(UCA_TYPE_PCO_CAMERA, NULL); +    UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); +    priv->pco = pco; + +    pco_get_resolution(priv->pco, &priv->width, &priv->height, &priv->width_ex, &priv->height_ex); +    pco_get_binning(priv->pco, &priv->binning_h, &priv->binning_v); +    pco_set_storage_mode(pco, STORAGE_MODE_RECORDER); +    pco_set_auto_transfer(pco, 1); + +    guint16 roi[4]; +    pco_get_roi(priv->pco, roi); +    pco_get_roi_steps(priv->pco, &priv->roi_horizontal_steps, &priv->roi_vertical_steps); + +    priv->roi_x = roi[0] - 1; +    priv->roi_y = roi[1] - 1; +    priv->roi_width = roi[2] - roi[0] + 1; +    priv->roi_height = roi[3] - roi[1] + 1; + +    guint16 camera_type, camera_subtype; +    pco_get_camera_type(priv->pco, &camera_type, &camera_subtype); +    pco_cl_map_entry *map_entry = get_pco_cl_map_entry(camera_type); +    priv->camera_description = map_entry; + +    if (map_entry == NULL) { +        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, +                "Camera type is not supported"); +        g_object_unref(camera); +        return NULL; +    } + +    priv->fg_port = PORT_A; +    priv->fg = Fg_Init(map_entry->so_file, priv->fg_port); + +    if (priv->fg == NULL) { +        g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_FG_INIT, +                "%s", Fg_getLastErrorDescription(priv->fg)); +        g_object_unref(camera); +        return NULL; +    } + +    const guint32 fg_height = priv->height; +    const guint32 fg_width = camera_type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width; + +    FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &map_entry->cl_type, priv->fg_port); +    FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &map_entry->cl_format, priv->fg_port); +    FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &fg_width, priv->fg_port); +    FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &fg_height, priv->fg_port); + +    int val = FREE_RUN; +    FG_TRY_PARAM(priv->fg, camera, FG_TRIGGERMODE, &val, priv->fg_port); + +    fill_binnings(priv); + +    /* +     * Here we override property ranges because we didn't know them at property +     * installation time. +     */ +    GObjectClass *camera_class = G_OBJECT_CLASS (UCA_CAMERA_GET_CLASS (camera)); +    property_override_default_guint_value (camera_class, "roi-width", priv->width); +    property_override_default_guint_value (camera_class, "roi-height", priv->height); + +    guint32 rates[4] = {0}; +    gint num_rates = 0; + +    if (pco_get_available_pixelrates(priv->pco, rates, &num_rates) == PCO_NOERROR) { +        GObjectClass *pco_camera_class = G_OBJECT_CLASS (UCA_PCO_CAMERA_GET_CLASS (camera)); + +        fill_pixelrates(priv, rates, num_rates); +        property_override_default_guint_value (pco_camera_class, "sensor-pixelrate", rates[0]); +    } + +    override_temperature_range (priv); +    override_maximum_adcs (priv); + +    return UCA_CAMERA (camera); +} diff --git a/src/cameras/uca-pco-camera.h b/src/cameras/uca-pco-camera.h index fdb709a..73ae44e 100644 --- a/src/cameras/uca-pco-camera.h +++ b/src/cameras/uca-pco-camera.h @@ -84,8 +84,6 @@ struct _UcaPcoCameraClass {      UcaCameraClass parent;  }; -UcaPcoCamera *uca_pco_camera_new(GError **error); -  GType uca_pco_camera_get_type(void);  G_END_DECLS diff --git a/src/cameras/uca-pf-camera.c b/src/cameras/uca-pf-camera.c index 5bc8c6b..35b5edd 100644 --- a/src/cameras/uca-pf-camera.c +++ b/src/cameras/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 <gmodule.h>  #include <stdlib.h>  #include <stdio.h>  #include <string.h> @@ -99,52 +100,6 @@ struct _UcaPfCameraPrivate {      dma_mem *fg_mem;  }; -UcaPfCamera *uca_pf_camera_new(GError **error) -{ -    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; -    } - -    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); - -    priv->fg_port = PORT_A; -    priv->fg = Fg_Init(so_file, priv->fg_port); - -    /* TODO: get this from the camera */ -    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; -    } - -    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); - -    return camera; -} -  /*   * We just embed our private structure here.   */ @@ -226,7 +181,7 @@ static void uca_pf_camera_grab(UcaCamera *camera, gpointer *data, GError **error      UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);      priv->last_frame = Fg_getLastPicNumberBlockingEx(priv->fg, priv->last_frame+1, priv->fg_port, 5, priv->fg_mem); -     +      if (priv->last_frame <= 0) {          guint err = FG_OK + 1;          FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_GENERAL); @@ -252,10 +207,10 @@ 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)  {      switch (property_id) { -        case PROP_SENSOR_WIDTH:  +        case PROP_SENSOR_WIDTH:              g_value_set_uint(value, 1280);              break; -        case PROP_SENSOR_HEIGHT:  +        case PROP_SENSOR_HEIGHT:              g_value_set_uint(value, 1024);              break;          case PROP_SENSOR_BITDEPTH: @@ -298,7 +253,7 @@ static void uca_pf_camera_get_property(GObject *object, guint property_id, GValu          case PROP_ROI_HEIGHT_MULTIPLIER:              g_value_set_uint(value, 1);              break; -        case PROP_NAME:  +        case PROP_NAME:              g_value_set_string(value, "Photon Focus MV2-D1280-640-CL");              break;          default: @@ -347,3 +302,50 @@ static void uca_pf_camera_init(UcaPfCamera *self)      self->priv->fg_mem = NULL;      self->priv->last_frame = 0;  } + +G_MODULE_EXPORT UcaCamera * +uca_camera_impl_new (GError **error) +{ +    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; +    } + +    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); + +    priv->fg_port = PORT_A; +    priv->fg = Fg_Init(so_file, priv->fg_port); + +    /* TODO: get this from the camera */ +    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; +    } + +    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); + +    return UCA_CAMERA (camera); +} diff --git a/src/cameras/uca-pf-camera.h b/src/cameras/uca-pf-camera.h index 7e3fe2c..3a309aa 100644 --- a/src/cameras/uca-pf-camera.h +++ b/src/cameras/uca-pf-camera.h @@ -67,8 +67,6 @@ struct _UcaPfCameraClass {      UcaCameraClass parent;  }; -UcaPfCamera *uca_pf_camera_new(GError **error); -  GType uca_pf_camera_get_type(void);  G_END_DECLS diff --git a/src/cameras/uca-ufo-camera.c b/src/cameras/uca-ufo-camera.c index 5f59f4a..7542fdf 100644 --- a/src/cameras/uca-ufo-camera.c +++ b/src/cameras/uca-ufo-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 <gmodule.h>  #include <stdlib.h>  #include <stdio.h>  #include <string.h> @@ -143,7 +144,8 @@ static int event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info,      return PCILIB_STREAMING_CONTINUE;  } -UcaUfoCamera *uca_ufo_camera_new(GError **error) +G_MODULE_EXPORT UcaCamera * +uca_camera_impl_new (GError **error)  {      pcilib_model_t model = PCILIB_MODEL_DETECT;      pcilib_model_description_t *model_description; @@ -223,7 +225,7 @@ UcaUfoCamera *uca_ufo_camera_new(GError **error)      priv->handle = handle; -    return camera; +    return UCA_CAMERA (camera);  }  static void uca_ufo_camera_start_recording(UcaCamera *camera, GError **error) diff --git a/src/cameras/uca-ufo-camera.h b/src/cameras/uca-ufo-camera.h index 0b52ffb..7030389 100644 --- a/src/cameras/uca-ufo-camera.h +++ b/src/cameras/uca-ufo-camera.h @@ -69,8 +69,6 @@ struct _UcaUfoCameraClass {      UcaCameraClass parent;  }; -UcaUfoCamera *uca_ufo_camera_new(GError **error); -  GType uca_ufo_camera_get_type(void);  G_END_DECLS diff --git a/src/uca-camera.c b/src/uca-camera.c index 78adae3..e34bf62 100644 --- a/src/uca-camera.c +++ b/src/uca-camera.c @@ -20,26 +20,6 @@  #include "uca-camera.h"  #include "uca-enums.h" -#ifdef HAVE_PCO_CL -#include "cameras/uca-pco-camera.h" -#endif - -#ifdef HAVE_PYLON_CAMERA -#include "cameras/uca-pylon-camera.h" -#endif - -#ifdef HAVE_MOCK_CAMERA -#include "cameras/uca-mock-camera.h" -#endif - -#ifdef HAVE_UFO_CAMERA -#include "cameras/uca-ufo-camera.h" -#endif - -#ifdef HAVE_PHOTON_FOCUS -#include "cameras/uca-pf-camera.h" -#endif -  #define UCA_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_CAMERA, UcaCameraPrivate))  G_DEFINE_TYPE(UcaCamera, uca_camera, G_TYPE_OBJECT) @@ -65,25 +45,6 @@ GQuark uca_camera_error_quark()      return g_quark_from_static_string("uca-camera-error-quark");  } -static gchar *uca_camera_types[] = { -#ifdef HAVE_PCO_CL -        "pco", -#endif -#ifdef HAVE_PYLON_CAMERA -        "pylon", -#endif -#ifdef HAVE_MOCK_CAMERA -        "mock", -#endif -#ifdef HAVE_UFO_CAMERA -        "ufo", -#endif -#ifdef HAVE_PHOTON_FOCUS -        "pf", -#endif -        NULL -}; -  enum {      LAST_SIGNAL  }; @@ -126,7 +87,8 @@ struct _UcaCameraPrivate {      gboolean transfer_async;  }; -static void uca_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +static void +uca_camera_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)  {      UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE(object); @@ -145,7 +107,8 @@ static void uca_camera_set_property(GObject *object, guint property_id, const GV      }  } -static void uca_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +static void +uca_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)  {      UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE(object); @@ -167,7 +130,8 @@ static void uca_camera_get_property(GObject *object, guint property_id, GValue *      }  } -static void uca_camera_class_init(UcaCameraClass *klass) +static void +uca_camera_class_init(UcaCameraClass *klass)  {      GObjectClass *gobject_class = G_OBJECT_CLASS(klass);      gobject_class->set_property = uca_camera_set_property; @@ -370,80 +334,6 @@ static void uca_camera_init(UcaCamera *camera)       */  } -static UcaCamera *uca_camera_new_from_type(const gchar *type, GError **error) -{ -#ifdef HAVE_MOCK_CAMERA -    if (!g_strcmp0(type, "mock")) -        return UCA_CAMERA(uca_mock_camera_new(error)); -#endif - -#ifdef HAVE_PCO_CL -    if (!g_strcmp0(type, "pco")) -        return UCA_CAMERA(uca_pco_camera_new(error)); -#endif - -#ifdef HAVE_PYLON_CAMERA -    if (!g_strcmp0(type, "pylon")) -        return UCA_CAMERA(uca_pylon_camera_new(error)); -#endif - -#ifdef HAVE_UFO_CAMERA -    if (!g_strcmp0(type, "ufo")) -        return UCA_CAMERA(uca_ufo_camera_new(error)); -#endif - -#ifdef HAVE_PHOTON_FOCUS -    if (!g_strcmp0(type, "pf")) -        return UCA_CAMERA(uca_pf_camera_new(error)); -#endif - -    return NULL; -} - -/** - * uca_camera_get_types: - * - * Enumerate all camera types that can be instantiated with uca_camera_new(). - * - * Returns: An array of strings with camera types. The list should be freed with - * g_strfreev(). - */ -gchar **uca_camera_get_types() -{ -    return g_strdupv(uca_camera_types); -} - -/** - * uca_camera_new: - * @type: Type name of the camera - * @error: Location to store an error or %NULL - * - * Factory method for instantiating cameras by names listed in - * uca_camera_get_types(). - * - * Returns: A new #UcaCamera of the correct type or %NULL if type was not found - */ -UcaCamera *uca_camera_new(const gchar *type, GError **error) -{ -    UcaCamera *camera = NULL; -    GError *tmp_error = NULL; - -    camera = uca_camera_new_from_type(type, &tmp_error); - -    if (tmp_error != NULL) { -        g_propagate_error(error, tmp_error); -        return NULL; -    } - -    if ((tmp_error == NULL) && (camera == NULL)) { -        g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_FOUND, -                "Camera type %s not found", type); -        return NULL; -    } - -    return camera; -} -  /**   * uca_camera_start_recording:   * @camera: A #UcaCamera object diff --git a/src/uca-plugin-manager.c b/src/uca-plugin-manager.c new file mode 100644 index 0000000..5678e83 --- /dev/null +++ b/src/uca-plugin-manager.c @@ -0,0 +1,327 @@ +/** + * SECTION:uca-plugin-manager + * @Short_description: Load an #UcaFilter from a shared object + * @Title: UcaPluginManager + * + * The plugin manager opens shared object modules searched for in locations + * specified with uca_plugin_manager_add_path(). A #UcaCamera can be + * instantiated with uca_plugin_manager_new_camera() with a one-to-one mapping + * between filter name xyz and module name libucaxyz.so. Any errors are reported + * as one of #UcaPluginManagerError codes. To get a list of available camera + * names call uca_plugin_manager_get_available_cameras(). + * + * By default, any path listed in the %UCA_CAMERA_PATH environment variable is + * added to the search path. + * + * @Since: 1.1 + */ +#include <gmodule.h> +#include "uca-plugin-manager.h" + +G_DEFINE_TYPE (UcaPluginManager, uca_plugin_manager, G_TYPE_OBJECT) + +#define UCA_PLUGIN_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManagerPrivate)) + +struct _UcaPluginManagerPrivate { +    GList *search_paths; +}; + +static const gchar *MODULE_PATTERN = "libuca([A-Za-z]+)"; + +typedef UcaCamera * (*GetCameraFunc) (GError **error); + +/** + * UcaPluginManagerError: + * @UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND: The module could not be found + * @UCA_PLUGIN_MANAGER_ERROR_MODULE_OPEN: Module could not be opened + * @UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND: Necessary entry symbol was not + *      found + * + * Possible errors that uca_plugin_manager_get_filter() can return. + */ +GQuark +uca_plugin_manager_error_quark (void) +{ +    return g_quark_from_static_string ("uca-plugin-manager-error-quark"); +} + +/** + * uca_plugin_manager_new: + * @config: (allow-none): A #UcaConfiguration object or %NULL. + * + * Create a plugin manager object to instantiate filter objects. When a config + * object is passed to the constructor, its search-path property is added to the + * internal search paths. + * + * Return value: A new plugin manager object. + */ +UcaPluginManager * +uca_plugin_manager_new () +{ +    return UCA_PLUGIN_MANAGER (g_object_new (UCA_TYPE_PLUGIN_MANAGER, NULL)); +} + +/** + * uca_plugin_manager_add_path: + * @manager: A #UcaPluginManager + * @path: Path to look for camera modules + * + * Add a search path to the plugin manager. + */ +void +uca_plugin_manager_add_path (UcaPluginManager   *manager, +                             const gchar        *path) +{ +    g_return_if_fail (UCA_IS_PLUGIN_MANAGER (manager)); + +    if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { +        UcaPluginManagerPrivate *priv; + +        priv = manager->priv; +        priv->search_paths = g_list_append (priv->search_paths, +                                            g_strdup (path)); +    } +} + +static GList * +get_camera_module_paths (const gchar *path) +{ +    GRegex *pattern; +    GDir *dir; +    GList *result = NULL; + +    pattern = g_regex_new (MODULE_PATTERN, 0, 0, NULL); +    dir = g_dir_open (path, 0, NULL); + +    if (dir != NULL) { +        GMatchInfo *match_info = NULL; +        const gchar *name = g_dir_read_name (dir); + +        while (name != NULL) { +            if (g_regex_match (pattern, name, 0, &match_info)) +                result = g_list_append (result, g_build_filename (path, name, NULL)); + +            g_match_info_free (match_info); +            name = g_dir_read_name (dir); +        } +    } + +    return result; +} + +static GList * +scan_search_paths (GList *search_paths) +{ +    GList *camera_paths = NULL; + +    for (GList *it = g_list_first (search_paths); it != NULL; it = g_list_next (it)) { +        camera_paths = g_list_concat (camera_paths, +                                      get_camera_module_paths ((const gchar*) it->data)); +    } + +    return camera_paths; +} + +static void +transform_camera_module_path_to_name (gchar *path, GList **result) +{ +    GRegex *pattern; +    GMatchInfo *match_info; + +    pattern = g_regex_new (MODULE_PATTERN, 0, 0, NULL); +    g_regex_match (pattern, path, 0, &match_info); + +    *result = g_list_append (*result, g_match_info_fetch (match_info, 1)); +    g_match_info_free (match_info); +} + +static void +list_free_full (GList *list) +{ +    g_list_foreach (list, (GFunc) g_free, NULL); +    g_list_free (list); +} + +/** + * uca_plugin_manager_get_available_cameras: + * + * @manager: A #UcaPluginManager + * + * Return: A list with strings of available camera names. You have to free the + * individual strings with g_list_foreach(list, (GFunc) g_free, NULL) and the + * list itself with g_list_free. + */ +GList * +uca_plugin_manager_get_available_cameras (UcaPluginManager *manager) +{ +    UcaPluginManagerPrivate *priv; +    GList *camera_paths; +    GList *camera_names = NULL; + +    g_return_val_if_fail (UCA_IS_PLUGIN_MANAGER (manager), NULL); + +    priv = manager->priv; +    camera_paths = scan_search_paths (priv->search_paths); + +    g_list_foreach (camera_paths, (GFunc) transform_camera_module_path_to_name, &camera_names); +    list_free_full (camera_paths); + +    return camera_names; +} + +static gchar * +find_camera_module_path (GList *search_paths, const gchar *name) +{ +    gchar *result = NULL; +    GList *paths; + +    paths = scan_search_paths (search_paths); + +    for (GList *it = g_list_first (paths); it != NULL; it = g_list_next (it)) { +        gchar *path = (gchar *) it->data; +        gchar *basename = g_path_get_basename ((gchar *) path); + +        if (g_strrstr (basename, name)) { +            result = g_strdup (path); +            g_free (basename); +            break; +        } + +        g_free (basename); +    } + +    list_free_full (paths); +    return result; +} + +/** + * uca_plugin_manager_new_camera: + * @manager: A #UcaPluginManager + * @name: Name of the camera module, that maps to libuca<name>.so + * @error: Location for a #GError + */ +UcaCamera * +uca_plugin_manager_new_camera (UcaPluginManager   *manager, +                               const gchar        *name, +                               GError            **error) +{ +    UcaPluginManagerPrivate *priv; +    UcaCamera *camera; +    GModule *module; +    GetCameraFunc *func; +    gchar *module_path; +    GError *tmp_error = NULL; + +    const gchar *symbol_name = "uca_camera_impl_new"; + +    g_return_val_if_fail (UCA_IS_PLUGIN_MANAGER (manager) && (name != NULL), NULL); + +    priv = manager->priv; +    module_path = find_camera_module_path (priv->search_paths, name); + +    if (module_path == NULL) { +        g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND, +                "Camera module `%s' not found", name); +        return NULL; +    } + +    module = g_module_open (module_path, G_MODULE_BIND_LAZY); +    g_free (module_path); + +    if (!module) { +        g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_OPEN, +                     "Camera module `%s' could not be opened: %s", name, g_module_error ()); +        return NULL; +    } + +    func = g_malloc0 (sizeof (GetCameraFunc)); + +    if (!g_module_symbol (module, symbol_name, (gpointer *) func)) { +        g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND, +                     "%s", g_module_error ()); +        g_free (func); + +        if (!g_module_close (module)) +            g_warning ("%s", g_module_error ()); + +        return NULL; +    } + +    camera = (*func) (&tmp_error); + +    if (tmp_error != NULL) { +        g_propagate_error (error, tmp_error); +        return NULL; +    } + +    return camera; +} + +static void +uca_plugin_manager_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ +    switch (property_id) { +        default: +            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +            break; +    } +} + +static void +uca_plugin_manager_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ +    switch (property_id) { +        default: +            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +            break; +    } +} + +static void +uca_plugin_manager_dispose (GObject *object) +{ +    G_OBJECT_CLASS (uca_plugin_manager_parent_class)->dispose (object); +} + +static void +uca_plugin_manager_finalize (GObject *object) +{ +    UcaPluginManagerPrivate *priv = UCA_PLUGIN_MANAGER_GET_PRIVATE (object); + +    g_list_foreach (priv->search_paths, (GFunc) g_free, NULL); +    g_list_free (priv->search_paths); + +    G_OBJECT_CLASS (uca_plugin_manager_parent_class)->finalize (object); +} + +static void +uca_plugin_manager_class_init (UcaPluginManagerClass *klass) +{ +    GObjectClass *gobject_class = G_OBJECT_CLASS (klass); +    gobject_class->get_property = uca_plugin_manager_get_property; +    gobject_class->set_property = uca_plugin_manager_set_property; +    gobject_class->dispose      = uca_plugin_manager_dispose; +    gobject_class->finalize     = uca_plugin_manager_finalize; + +    g_type_class_add_private (klass, sizeof (UcaPluginManagerPrivate)); +} + +static void +uca_plugin_manager_init (UcaPluginManager *manager) +{ +    UcaPluginManagerPrivate *priv; +    const gchar *uca_camera_path; + +    manager->priv = priv = UCA_PLUGIN_MANAGER_GET_PRIVATE (manager); +    priv->search_paths = NULL; + +    uca_camera_path = g_getenv ("UCA_CAMERA_PATH"); + +    if (uca_camera_path != NULL) +        uca_plugin_manager_add_path (manager, uca_camera_path); + +    uca_plugin_manager_add_path (manager, "/usr/lib/uca"); +    uca_plugin_manager_add_path (manager, "/usr/lib64/uca"); +    uca_plugin_manager_add_path (manager, "/usr/local/lib/uca"); +    uca_plugin_manager_add_path (manager, "/usr/local/lib64/uca"); +} diff --git a/src/uca-plugin-manager.h b/src/uca-plugin-manager.h new file mode 100644 index 0000000..9291857 --- /dev/null +++ b/src/uca-plugin-manager.h @@ -0,0 +1,65 @@ +#ifndef __UCA_PLUGIN_MANAGER_H +#define __UCA_PLUGIN_MANAGER_H + +#include <glib-object.h> +#include "uca-camera.h" + +G_BEGIN_DECLS + +#define UCA_TYPE_PLUGIN_MANAGER             (uca_plugin_manager_get_type()) +#define UCA_PLUGIN_MANAGER(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManager)) +#define UCA_IS_PLUGIN_MANAGER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_PLUGIN_MANAGER)) +#define UCA_PLUGIN_MANAGER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManagerClass)) +#define UCA_IS_PLUGIN_MANAGER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PLUGIN_MANAGER)) +#define UCA_PLUGIN_MANAGER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManagerClass)) + +#define UCA_PLUGIN_MANAGER_ERROR uca_plugin_manager_error_quark() +GQuark uca_plugin_manager_error_quark(void); + +typedef enum { +    UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND, +    UCA_PLUGIN_MANAGER_ERROR_MODULE_OPEN, +    UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND +} UcaPluginManagerError; + +typedef struct _UcaPluginManager           UcaPluginManager; +typedef struct _UcaPluginManagerClass      UcaPluginManagerClass; +typedef struct _UcaPluginManagerPrivate    UcaPluginManagerPrivate; + +/** + * UcaPluginManager: + * + * Creates #UcaFilter instances by loading corresponding shared objects. The + * contents of the #UcaPluginManager structure are private and should only be + * accessed via the provided API. + */ +struct _UcaPluginManager { +    /*< private >*/ +    GObject parent_instance; + +    UcaPluginManagerPrivate *priv; +}; + +/** + * UcaPluginManagerClass: + * + * #UcaPluginManager class + */ +struct _UcaPluginManagerClass { +    /*< private >*/ +    GObjectClass parent_class; +}; + +UcaPluginManager    *uca_plugin_manager_new         (void); +void                 uca_plugin_manager_add_path    (UcaPluginManager   *manager, +                                                     const gchar        *path); +GList               *uca_plugin_manager_get_available_cameras +                                                    (UcaPluginManager   *manager); +UcaCamera           *uca_plugin_manager_new_camera  (UcaPluginManager   *manager, +                                                     const gchar        *name, +                                                     GError            **error); +GType                uca_plugin_manager_get_type    (void); + +G_END_DECLS + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ce45d71..e4e60dc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -10,10 +10,7 @@ pkg_check_modules(GTHREAD2 gthread-2.0)  pkg_check_modules(GLIB2 glib-2.0>=2.24 REQUIRED)  pkg_check_modules(GOBJECT2 gobject-2.0>=2.24 REQUIRED) -#include_directories(${CMAKE_SOURCE_DIR}/src) -  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/control.glade ${CMAKE_CURRENT_BINARY_DIR}) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run.py ${CMAKE_CURRENT_BINARY_DIR})  # --- Build targets -----------------------------------------------------------  include_directories( @@ -44,14 +41,7 @@ target_link_libraries(benchmark uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES})  target_link_libraries(grab uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES})  target_link_libraries(grab-async uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) -add_executable(grab_pylon grab_pylon.c) -target_link_libraries(grab_pylon uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) - -if (NOT DEFINED WITH_CONTROL_GUI) -    set(WITH_CONTROL_GUI TRUE) -endif() - -if (GTK2_FOUND AND WITH_CONTROL_GUI) +if (GTK2_FOUND)      include_directories(${GTK2_INCLUDE_DIRS})      add_executable(control  @@ -81,6 +71,6 @@ if (HAVE_MOCK_CAMERA)          ${CMAKE_CURRENT_BINARY_DIR}/gtester.xsl)  endif() -add_executable(test-all test-all.c) -target_link_libraries(test-all uca -    ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) +#add_executable(test-all test-all.c) +#target_link_libraries(test-all uca +#    ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) diff --git a/test/benchmark.c b/test/benchmark.c index 0b4f6f8..ef99fd1 100644 --- a/test/benchmark.c +++ b/test/benchmark.c @@ -20,6 +20,7 @@  #include <string.h>  #include <stdlib.h>  #include "uca-camera.h" +#include "uca-plugin-manager.h"  typedef void (*GrabFrameFunc) (UcaCamera *camera, gpointer buffer, guint n_frames); @@ -37,20 +38,25 @@ sigint_handler(int signal)  static void  print_usage (void)  { -    gchar **types; +    GList *types; +    UcaPluginManager *manager; -    g_print ("Usage: benchmark ("); -    types = uca_camera_get_types (); +    manager = uca_plugin_manager_new (); +    g_print ("Usage: benchmark [ "); +    types = uca_plugin_manager_get_available_cameras (manager); -    for (guint i = 0; types[i] != NULL; i++) { -        if (types[i+1] == NULL) -            g_print ("%s)", types[i]); -        else -            g_print ("%s | ", types[i]); +    if (types == NULL) { +        g_print ("] -- no camera plugin found\n"); +        return;      } -    g_print ("\n"); -    g_strfreev (types); +    for (GList *it = g_list_first (types); it != NULL; it = g_list_next (it)) { +        gchar *name = (gchar *) it->data; +        if (g_list_next (it) == NULL) +            g_print ("%s ]\n", name); +        else +            g_print ("%s, ", name); +    }  }  static void @@ -227,10 +233,12 @@ benchmark (UcaCamera *camera)  int  main (int argc, char *argv[])  { +    UcaPluginManager *manager;      GIOChannel  *log_channel;      GError      *error = NULL;      (void) signal (SIGINT, sigint_handler); +    g_type_init();      if (argc < 2) {          print_usage(); @@ -241,8 +249,8 @@ main (int argc, char *argv[])      g_assert_no_error (error);      g_log_set_handler (NULL, G_LOG_LEVEL_MASK, log_handler, log_channel); -    g_type_init(); -    camera = uca_camera_new(argv[1], &error); +    manager = uca_plugin_manager_new (); +    camera = uca_plugin_manager_new_camera (manager, argv[1], &error);      if (camera == NULL) {          g_error ("Initialization: %s", error->message); diff --git a/test/control.c b/test/control.c index eaa88e3..5a7b702 100644 --- a/test/control.c +++ b/test/control.c @@ -26,6 +26,7 @@  #include "config.h"  #include "uca-camera.h" +#include "uca-plugin-manager.h"  #include "egg-property-tree-view.h" @@ -48,20 +49,17 @@ typedef struct {      int pixel_size;  } ThreadData; -typedef struct { -    ThreadData *thread_data; -    GtkTreeStore *tree_store; -} ValueCellData; -  enum {      COLUMN_NAME = 0,      COLUMN_VALUE,      COLUMN_EDITABLE,      NUM_COLUMNS  }; +     +static UcaPluginManager *plugin_manager; - -static void convert_8bit_to_rgb(guchar *output, guchar *input, int width, int height) +static void +convert_8bit_to_rgb (guchar *output, guchar *input, int width, int height)  {      for (int i = 0, j = 0; i < width*height; i++) {          output[j++] = input[i]; @@ -70,7 +68,8 @@ static void convert_8bit_to_rgb(guchar *output, guchar *input, int width, int he      }  } -static void convert_16bit_to_rgb(guchar *output, guchar *input, int width, int height) +static void +convert_16bit_to_rgb (guchar *output, guchar *input, int width, int height)  {      guint16 *in = (guint16 *) input;      guint16 min = G_MAXUINT16, max = 0; @@ -96,54 +95,58 @@ static void convert_16bit_to_rgb(guchar *output, guchar *input, int width, int h      }  } -static void *grab_thread(void *args) +static void * +grab_thread (void *args)  {      ThreadData *data = (ThreadData *) args;      gchar filename[FILENAME_MAX] = {0,};      gint counter = 0;      while (data->running) { -        uca_camera_grab(data->camera, (gpointer) &data->buffer, NULL); +        uca_camera_grab (data->camera, (gpointer) &data->buffer, NULL);          if (data->store) { -            snprintf(filename, FILENAME_MAX, "frame-%i-%08i.raw", data->timestamp, counter++); -            FILE *fp = fopen(filename, "wb"); -            fwrite(data->buffer, data->width*data->height, data->pixel_size, fp); -            fclose(fp); +            snprintf (filename, FILENAME_MAX, "frame-%i-%08i.raw", data->timestamp, counter++); +            FILE *fp = fopen (filename, "wb"); +            fwrite (data->buffer, data->width*data->height, data->pixel_size, fp); +            fclose (fp);          }          /* FIXME: We should actually check if this is really a new frame and           * just do nothing if it is an already displayed one. */          if (data->pixel_size == 1) -            convert_8bit_to_rgb(data->pixels, data->buffer, data->width, data->height); +            convert_8bit_to_rgb (data->pixels, data->buffer, data->width, data->height);          else if (data->pixel_size == 2) { -            convert_16bit_to_rgb(data->pixels, data->buffer, data->width, data->height); +            convert_16bit_to_rgb (data->pixels, data->buffer, data->width, data->height);          } -        gdk_threads_enter(); -        gdk_flush(); -        gtk_image_clear(GTK_IMAGE(data->image)); -        gtk_image_set_from_pixbuf(GTK_IMAGE(data->image), data->pixbuf); -        gtk_widget_queue_draw_area(data->image, 0, 0, data->width, data->height); -        gdk_threads_leave(); +        gdk_threads_enter (); +        gdk_flush (); +        gtk_image_clear (GTK_IMAGE (data->image)); +        gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf); +        gtk_widget_queue_draw_area (data->image, 0, 0, data->width, data->height); +        gdk_threads_leave ();      }      return NULL;  } -gboolean on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) +gboolean +on_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)  {      return FALSE;  } -void on_destroy(GtkWidget *widget, gpointer data) +void +on_destroy (GtkWidget *widget, gpointer data)  {      ThreadData *td = (ThreadData *) data;      td->running = FALSE; -    g_object_unref(td->camera); -    gtk_main_quit(); +    g_object_unref (td->camera); +    gtk_main_quit ();  } -static void on_toolbutton_run_clicked(GtkWidget *widget, gpointer args) +static void +on_toolbutton_run_clicked (GtkWidget *widget, gpointer args)  {      ThreadData *data = (ThreadData *) args; @@ -153,184 +156,195 @@ static void on_toolbutton_run_clicked(GtkWidget *widget, gpointer args)      GError *error = NULL;      data->running = TRUE; -    uca_camera_start_recording(data->camera, &error); +    uca_camera_start_recording (data->camera, &error);      if (error != NULL) { -        g_printerr("Failed to start recording: %s\n", error->message); +        g_printerr ("Failed to start recording: %s\n", error->message);          return;      } -    if (!g_thread_create(grab_thread, data, FALSE, &error)) { -        g_printerr("Failed to create thread: %s\n", error->message); +    if (!g_thread_create (grab_thread, data, FALSE, &error)) { +        g_printerr ("Failed to create thread: %s\n", error->message);          return;      }  } -static void on_toolbutton_stop_clicked(GtkWidget *widget, gpointer args) +static void +on_toolbutton_stop_clicked (GtkWidget *widget, gpointer args)  {      ThreadData *data = (ThreadData *) args;      data->running = FALSE;      data->store = FALSE;      GError *error = NULL; -    uca_camera_stop_recording(data->camera, &error); +    uca_camera_stop_recording (data->camera, &error);      if (error != NULL) -        g_printerr("Failed to stop: %s\n", error->message); +        g_printerr ("Failed to stop: %s\n", error->message);  } -static void on_toolbutton_record_clicked(GtkWidget *widget, gpointer args) +static void +on_toolbutton_record_clicked (GtkWidget *widget, gpointer args)  {      ThreadData *data = (ThreadData *) args; -    data->timestamp = (int) time(0); +    data->timestamp = (int) time (0);      data->store = TRUE;      GError *error = NULL; -    gtk_statusbar_push(data->statusbar, data->statusbar_context_id, "Recording..."); +    gtk_statusbar_push (data->statusbar, data->statusbar_context_id, "Recording...");      if (data->running != TRUE) {          data->running = TRUE; -        uca_camera_start_recording(data->camera, &error); +        uca_camera_start_recording (data->camera, &error); -        if (!g_thread_create(grab_thread, data, FALSE, &error)) -            g_printerr("Failed to create thread: %s\n", error->message); +        if (!g_thread_create (grab_thread, data, FALSE, &error)) +            g_printerr ("Failed to create thread: %s\n", error->message);      }  } -static void create_main_window(GtkBuilder *builder, const gchar* camera_name) +static void +create_main_window (GtkBuilder *builder, const gchar* camera_name)  {      static ThreadData td;      GError *error = NULL; -    UcaCamera *camera = uca_camera_new(camera_name, &error); +    UcaCamera *camera = uca_plugin_manager_new_camera (plugin_manager, camera_name, &error);      if ((camera == NULL) || (error != NULL)) { -        g_error("%s\n", error->message); -        gtk_main_quit(); +        g_error ("%s\n", error->message); +        gtk_main_quit ();      }      guint bits_per_sample; -    g_object_get(camera, +    g_object_get (camera,              "roi-width", &td.width,              "roi-height", &td.height,              "sensor-bitdepth", &bits_per_sample,              NULL); -    GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window")); -    GtkWidget *image = GTK_WIDGET(gtk_builder_get_object(builder, "image")); +    GtkWidget *window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); +    GtkWidget *image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));      GtkWidget *property_tree_view = egg_property_tree_view_new (G_OBJECT (camera));      GtkContainer *scrolled_property_window = GTK_CONTAINER (gtk_builder_get_object (builder, "scrolledwindow2"));      gtk_container_add (scrolled_property_window, property_tree_view);      gtk_widget_show_all (GTK_WIDGET (scrolled_property_window)); -    GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, td.width, td.height); -    gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); +    GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, td.width, td.height); +    gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);      td.pixel_size = bits_per_sample > 8 ? 2 : 1;      td.image  = image;      td.pixbuf = pixbuf; -    td.buffer = (guchar *) g_malloc(td.pixel_size * td.width * td.height); -    td.pixels = gdk_pixbuf_get_pixels(pixbuf); +    td.buffer = (guchar *) g_malloc (td.pixel_size * td.width * td.height); +    td.pixels = gdk_pixbuf_get_pixels (pixbuf);      td.running = FALSE; -    td.statusbar = GTK_STATUSBAR(gtk_builder_get_object(builder, "statusbar")); -    td.statusbar_context_id = gtk_statusbar_get_context_id(td.statusbar, "Recording Information"); +    td.statusbar = GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); +    td.statusbar_context_id = gtk_statusbar_get_context_id (td.statusbar, "Recording Information");      td.store = FALSE;      td.camera = camera; -    td.property_model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "camera-properties")); - -    g_signal_connect(window, "destroy", G_CALLBACK(on_destroy), &td); -    g_signal_connect(gtk_builder_get_object(builder, "toolbutton_run"), -            "clicked", G_CALLBACK(on_toolbutton_run_clicked), &td); -    g_signal_connect(gtk_builder_get_object(builder, "toolbutton_stop"), -            "clicked", G_CALLBACK(on_toolbutton_stop_clicked), &td); -    g_signal_connect(gtk_builder_get_object(builder, "toolbutton_record"), -            "clicked", G_CALLBACK(on_toolbutton_record_clicked), &td); - -    gtk_widget_show(image); -    gtk_widget_show(window); +    td.property_model = GTK_TREE_MODEL (gtk_builder_get_object (builder, "camera-properties")); + +    g_signal_connect (window, "destroy", G_CALLBACK (on_destroy), &td); +    g_signal_connect (gtk_builder_get_object (builder, "toolbutton_run"), +            "clicked", G_CALLBACK (on_toolbutton_run_clicked), &td); +    g_signal_connect (gtk_builder_get_object (builder, "toolbutton_stop"), +            "clicked", G_CALLBACK (on_toolbutton_stop_clicked), &td); +    g_signal_connect (gtk_builder_get_object (builder, "toolbutton_record"), +            "clicked", G_CALLBACK (on_toolbutton_record_clicked), &td); + +    gtk_widget_show (image); +    gtk_widget_show (window);  } -static void on_button_proceed_clicked(GtkWidget *widget, gpointer data) +static void +on_button_proceed_clicked (GtkWidget *widget, gpointer data)  { -    GtkBuilder *builder = GTK_BUILDER(data); -    GtkWidget *choice_window = GTK_WIDGET(gtk_builder_get_object(builder, "choice-window")); -    GtkTreeView *treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview-cameras")); -    GtkListStore *list_store = GTK_LIST_STORE(gtk_builder_get_object(builder, "camera-types")); +    GtkBuilder *builder = GTK_BUILDER (data); +    GtkWidget *choice_window = GTK_WIDGET (gtk_builder_get_object (builder, "choice-window")); +    GtkTreeView *treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview-cameras")); +    GtkListStore *list_store = GTK_LIST_STORE (gtk_builder_get_object (builder, "camera-types")); -    GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview); -    GList *selected_rows = gtk_tree_selection_get_selected_rows(selection, NULL); +    GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview); +    GList *selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);      GtkTreeIter iter; -    gtk_widget_destroy(choice_window); -    gboolean valid = gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, selected_rows->data); +    gtk_widget_destroy (choice_window); +    gboolean valid = gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store), &iter, selected_rows->data);      if (valid) {          gchar *data; -        gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, 0, &data, -1); -        create_main_window(builder, data); -        g_free(data); +        gtk_tree_model_get (GTK_TREE_MODEL (list_store), &iter, 0, &data, -1); +        create_main_window (builder, data); +        g_free (data);      } -    g_list_foreach(selected_rows, (GFunc) gtk_tree_path_free, NULL); -    g_list_free(selected_rows); +    g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL); +    g_list_free (selected_rows);  } -static void on_treeview_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data) +static void +on_treeview_keypress (GtkWidget *widget, GdkEventKey *event, gpointer data)  {      if (event->keyval == GDK_KEY_Return) -        gtk_widget_grab_focus(GTK_WIDGET(data)); +        gtk_widget_grab_focus (GTK_WIDGET (data));  } -static void create_choice_window(GtkBuilder *builder) +static void +create_choice_window (GtkBuilder *builder)  { -    gchar **camera_types = uca_camera_get_types(); +    GList *camera_types = uca_plugin_manager_get_available_cameras (plugin_manager); -    GtkWidget *choice_window = GTK_WIDGET(gtk_builder_get_object(builder, "choice-window")); -    GtkTreeView *treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview-cameras")); -    GtkListStore *list_store = GTK_LIST_STORE(gtk_builder_get_object(builder, "camera-types")); -    GtkButton *proceed_button = GTK_BUTTON(gtk_builder_get_object(builder, "button-proceed")); +    GtkWidget *choice_window = GTK_WIDGET (gtk_builder_get_object (builder, "choice-window")); +    GtkTreeView *treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview-cameras")); +    GtkListStore *list_store = GTK_LIST_STORE (gtk_builder_get_object (builder, "camera-types")); +    GtkButton *proceed_button = GTK_BUTTON (gtk_builder_get_object (builder, "button-proceed"));      GtkTreeIter iter; -    for (guint i = 0; camera_types[i] != NULL; i++) { -        gtk_list_store_append(list_store, &iter); -        gtk_list_store_set(list_store, &iter, 0, camera_types[i], -1); +    for (GList *it = g_list_first (camera_types); it != NULL; it = g_list_next (it)) { +        gtk_list_store_append (list_store, &iter); +        gtk_list_store_set (list_store, &iter, 0, g_strdup ((gchar *) it->data), -1);      } -    gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list_store), &iter); +    gboolean valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter);      if (valid) { -        GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview); -        gtk_tree_selection_unselect_all(selection); -        gtk_tree_selection_select_path(selection, gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter)); +        GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview); +        gtk_tree_selection_unselect_all (selection); +        gtk_tree_selection_select_path (selection, gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), &iter));      } -    g_strfreev(camera_types); -    g_signal_connect(proceed_button, "clicked", G_CALLBACK(on_button_proceed_clicked), builder); -    g_signal_connect(treeview, "key-press-event", G_CALLBACK(on_treeview_keypress), proceed_button); -    gtk_widget_show_all(GTK_WIDGET(choice_window)); +    g_signal_connect (proceed_button, "clicked", G_CALLBACK (on_button_proceed_clicked), builder); +    g_signal_connect (treeview, "key-press-event", G_CALLBACK (on_treeview_keypress), proceed_button); +    gtk_widget_show_all (GTK_WIDGET (choice_window)); + +    g_list_foreach (camera_types, (GFunc) g_free, NULL); +    g_list_free (camera_types);  } -int main(int argc, char *argv[]) +int +main (int argc, char *argv[])  {      GError *error = NULL; -    g_thread_init(NULL); -    gdk_threads_init(); -    gtk_init(&argc, &argv); +    g_thread_init (NULL); +    gdk_threads_init (); +    gtk_init (&argc, &argv); -    GtkBuilder *builder = gtk_builder_new(); +    GtkBuilder *builder = gtk_builder_new (); -    if (!gtk_builder_add_from_file(builder, CONTROL_GLADE_PATH, &error)) { -        g_print("Error: %s\n", error->message); +    if (!gtk_builder_add_from_file (builder, CONTROL_GLADE_PATH, &error)) { +        g_print ("Error: %s\n", error->message);          return 1;      } -    create_choice_window(builder); -    gtk_builder_connect_signals(builder, NULL); +    plugin_manager = uca_plugin_manager_new (); +    create_choice_window (builder); +    gtk_builder_connect_signals (builder, NULL); -    gdk_threads_enter(); -    gtk_main(); -    gdk_threads_leave(); +    gdk_threads_enter (); +    gtk_main (); +    gdk_threads_leave (); +    g_object_unref (plugin_manager);      return 0;  } diff --git a/test/enum.c b/test/enum.c deleted file mode 100644 index 75ca596..0000000 --- a/test/enum.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library is distributed in the hope that it will be useful, but WITHOUT -   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#include <stdio.h> -#include "uca.h" - -int count_dots(const char *s) -{ -    int res = 0; -    while (*(s++) != '\0') -        if (*s == '.') -            res++; -    return res; -} - -void print_level(int depth) -{ -    for (int i = 0; i < depth; i++) -        printf("|  "); -    printf("|-- "); -} - -int main(int argc, char *argv[]) -{ -    uca *u = uca_init(NULL); -    if (u == NULL) { -        printf("Couldn't find a camera\n"); -        return 1; -    } - -    /* take first camera */ -    uca_camera *cam = u->cameras; - -    const size_t num_bytes = 256; -    char string_value[num_bytes]; -    uint32_t uint32_value; -    uint8_t uint8_value; - -    while (cam != NULL) { -        for (int i = 0; i < UCA_PROP_LAST; i++) { -            uca_property *prop = uca_get_full_property(i); -            print_level(count_dots(prop->name)); -            printf("%s = ", prop->name); -            switch (prop->type) { -                case uca_string: -                    if (uca_cam_get_property(cam, i, string_value, num_bytes) == UCA_NO_ERROR) { -                        printf("%s ", string_value); -                    } -                    else -                        printf("n/a"); -                    break; -                case uca_uint32t: -                    if (uca_cam_get_property(cam, i, &uint32_value, 0) == UCA_NO_ERROR) { -                        printf("%u %s", uint32_value, uca_unit_map[prop->unit]); -                    } -                    else -                        printf("n/a"); -                    break; -                case uca_uint8t: -                    if (uca_cam_get_property(cam, i, &uint8_value, 0) == UCA_NO_ERROR) { -                        printf("%u %s", uint8_value, uca_unit_map[prop->unit]); -                    } -                    else -                        printf("n/a"); -                    break; -            } -            printf("\n"); -        } -        cam = cam->next; -    } -     -    uca_destroy(u); -    return 0; -} diff --git a/test/grab-async.c b/test/grab-async.c index e1ec114..6132829 100644 --- a/test/grab-async.c +++ b/test/grab-async.c @@ -19,6 +19,7 @@  #include <signal.h>  #include <stdio.h>  #include <stdlib.h> +#include "uca-plugin-manager.h"  #include "uca-camera.h"  static UcaCamera *camera = NULL; @@ -29,7 +30,8 @@ typedef struct {      guint counter;  } CallbackData; -static void sigint_handler(int signal) +static void +sigint_handler(int signal)  {      printf("Closing down libuca\n");      uca_camera_stop_recording(camera, NULL); @@ -37,7 +39,8 @@ static void sigint_handler(int signal)      exit(signal);  } -static void grab_callback(gpointer data, gpointer user_data) +static void +grab_callback(gpointer data, gpointer user_data)  {      CallbackData *cbd = (CallbackData *) user_data;      gchar *filename = g_strdup_printf("frame-%04i.raw", cbd->counter++); @@ -49,16 +52,49 @@ static void grab_callback(gpointer data, gpointer user_data)      g_free(filename);  } -int main(int argc, char *argv[]) +static void +print_usage (void) +{ +    GList *types; +    UcaPluginManager *manager; + +    manager = uca_plugin_manager_new (); +    g_print ("Usage: benchmark [ "); +    types = uca_plugin_manager_get_available_cameras (manager); + +    if (types == NULL) { +        g_print ("] -- no camera plugin found\n"); +        return; +    } + +    for (GList *it = g_list_first (types); it != NULL; it = g_list_next (it)) { +        gchar *name = (gchar *) it->data; +        if (g_list_next (it) == NULL) +            g_print ("%s ]\n", name); +        else +            g_print ("%s, ", name); +    } +} + +int +main(int argc, char *argv[])  {      CallbackData cbd;      guint sensor_width, sensor_height;      gchar *name; +    UcaPluginManager *manager;      GError *error = NULL;      (void) signal(SIGINT, sigint_handler);      g_type_init(); -    camera = uca_camera_new("pco", &error); + +    if (argc < 2) { +        print_usage(); +        return 1; +    } + +    manager = uca_plugin_manager_new (); +    camera = uca_plugin_manager_new_camera (manager, argv[1], &error);      if (camera == NULL) {          g_print("Error during initialization: %s\n", error->message); diff --git a/test/grab.c b/test/grab.c index 41e6d88..e507d69 100644 --- a/test/grab.c +++ b/test/grab.c @@ -19,6 +19,7 @@  #include <signal.h>  #include <stdio.h>  #include <stdlib.h> +#include "uca-plugin-manager.h"  #include "uca-camera.h"  static UcaCamera *camera = NULL; @@ -31,26 +32,33 @@ static void sigint_handler(int signal)      exit(signal);  } -static void print_usage(void) +static void +print_usage (void)  { -    gchar **types; -     -    g_print("Usage: grab ("); -    types = uca_camera_get_types(); - -    for (guint i = 0; types[i] != NULL; i++) { -        if (types[i+1] == NULL) -            g_print("%s)", types[i]); -        else -            g_print("%s | ", types[i]); +    GList *types; +    UcaPluginManager *manager; + +    manager = uca_plugin_manager_new (); +    g_print ("Usage: benchmark [ "); +    types = uca_plugin_manager_get_available_cameras (manager); + +    if (types == NULL) { +        g_print ("] -- no camera plugin found\n"); +        return;      } -    g_print("\n"); -    g_strfreev(types); +    for (GList *it = g_list_first (types); it != NULL; it = g_list_next (it)) { +        gchar *name = (gchar *) it->data; +        if (g_list_next (it) == NULL) +            g_print ("%s ]\n", name); +        else +            g_print ("%s, ", name); +    }  }  int main(int argc, char *argv[])  { +    UcaPluginManager *manager;      GError *error = NULL;      (void) signal(SIGINT, sigint_handler); @@ -59,13 +67,15 @@ int main(int argc, char *argv[])      guint bits;      gchar *name; +    g_type_init(); +      if (argc < 2) {          print_usage();          return 1;      } -    g_type_init(); -    camera = uca_camera_new(argv[1], &error); +    manager = uca_plugin_manager_new (); +    camera = uca_plugin_manager_new_camera (manager, argv[1], &error);      if (camera == NULL) {          g_print("Error during initialization: %s\n", error->message); diff --git a/test/grab_pylon.c b/test/grab_pylon.c deleted file mode 100644 index 2f9b5a0..0000000 --- a/test/grab_pylon.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> -   (Karlsruhe Institute of Technology) - -   This library is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as published by the -   Free Software Foundation; either version 2.1 of the License, or (at your -   option) any later version. - -   This library is distributed in the hope that it will be useful, but WITHOUT -   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -   details. - -   You should have received a copy of the GNU Lesser General Public License along -   with this library; if not, write to the Free Software Foundation, Inc., 51 -   Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#include <glib-object.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include "uca-camera.h" - -#define handle_error(errno) {if ((errno) != UCA_NO_ERROR) printf("error at <%s:%i>\n", \ -    __FILE__, __LINE__);} - -static UcaCamera *camera = NULL; - -void sigint_handler(int signal) -{ -    printf("Closing down libuca\n"); -    uca_camera_stop_recording(camera, NULL); -    g_object_unref(camera); -    exit(signal); -} - -int main(int argc, char *argv[]) -{ -    GError *error = NULL; -    (void) signal(SIGINT, sigint_handler); - -    g_type_init(); -    camera = uca_camera_new("pylon", &error); - -    if (camera == NULL) { -        g_print("Couldn't initialize camera\n"); -        return 1; -    } - -    guint width, height, bits; -    g_object_get(G_OBJECT(camera), -            "sensor-width", &width, -            "sensor-height", &height, -            "sensor-bitdepth", &bits, -            NULL); - -    const int pixel_size = bits == 8 ? 1 : 2; -    g_print("allocate buffer %u, %u, %d\n", width, height, pixel_size); -    gpointer buffer = g_malloc0(width * height * pixel_size); - -    gchar filename[FILENAME_MAX]; - -    for (int i = 0; i < 2; i++) { -        gint counter = 0; -        g_print("Start recording\n"); -        uca_camera_start_recording(camera, &error); -        g_assert_no_error(error); - -        while (counter < 10) { -            g_print(" grab frame ... "); -            uca_camera_grab(camera, &buffer, &error); -            if (error != NULL) { -                g_print("\nError: %s\n", error->message); -                goto cleanup; -            } -            g_print("done\n"); - -            snprintf(filename, FILENAME_MAX, "frame-%08i.raw", counter++); -            FILE *fp = fopen(filename, "wb"); -            fwrite(buffer, width*height, pixel_size, fp); -            fclose(fp); -            //g_usleep(2 * G_USEC_PER_SEC); -        } - -        g_print("Stop recording\n"); -        uca_camera_stop_recording(camera, &error); -        g_assert_no_error(error); -    } - -cleanup: -    uca_camera_stop_recording(camera, NULL); -    g_object_unref(camera); -    g_free(buffer); - -    return error != NULL ? 1 : 0; -} diff --git a/test/run.py b/test/run.py deleted file mode 100755 index 7982617..0000000 --- a/test/run.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python - -import Tkinter -import threading -import subprocess - -class App(object): -    def __init__(self, parent): -        self.parent = parent -        self.canvas = Tkinter.Canvas(root, width=300, height=300) -        self.canvas.pack() -        self.rect = self.canvas.create_rectangle(0, 0, 300, 300, fill='yellow') -        self.run_button = Tkinter.Button(parent, text='Start grabbing', command=self.run_click) -        self.run_button.pack() -         -    def run_grab(self): -        proc = subprocess.Popen(['./grab']) -        proc.wait() -        self.canvas.itemconfig(self.rect, fill='red') -        self.run_button.config(state=Tkinter.NORMAL, text='Close', command=self.parent.destroy) -         -    def run_click(self): -        self.canvas.itemconfig(self.rect, fill='green') -        self.run_button.config(state=Tkinter.DISABLED) -        thread = threading.Thread(None, self.run_grab) -        thread.start() - -if __name__ == '__main__': -    root = Tkinter.Tk() -    app = App(root) -    root.mainloop() diff --git a/test/test-mock.c b/test/test-mock.c index 7594a3a..ca16c59 100644 --- a/test/test-mock.c +++ b/test/test-mock.c @@ -1,176 +1,195 @@  #include <glib.h>  #include "uca-camera.h" -#include "cameras/uca-mock-camera.h" +#include "uca-plugin-manager.h"  typedef struct { -    UcaMockCamera *camera; +    UcaPluginManager *manager; +    UcaCamera *camera;  } Fixture; -static void fixture_setup(Fixture *fixture, gconstpointer data) +static void +fixture_setup (Fixture *fixture, gconstpointer data)  {      GError *error = NULL; -    fixture->camera = uca_mock_camera_new(&error); -    g_assert(error == NULL); -    g_assert(fixture->camera); + +    fixture->manager = uca_plugin_manager_new (); +    uca_plugin_manager_add_path (fixture->manager, "./src"); + +    fixture->camera = uca_plugin_manager_new_camera (fixture->manager, "mock", &error); +    g_assert (error == NULL); +    g_assert (fixture->camera);  } -static void fixture_teardown(Fixture *fixture, gconstpointer data) +static void +fixture_teardown (Fixture *fixture, gconstpointer data)  { -    g_object_unref(fixture->camera); +    g_object_unref (fixture->camera); +    g_object_unref (fixture->manager);  } -static void on_property_change(gpointer instance, GParamSpec *pspec, gpointer user_data) +static void +on_property_change (gpointer instance, GParamSpec *pspec, gpointer user_data)  {      gboolean *success = (gboolean *) user_data;      *success = TRUE;  } -static void test_factory() +static void +test_factory (Fixture *fixture, gconstpointer data)  {      GError *error = NULL; -    UcaCamera *camera = uca_camera_new("fox994m3a0yxmy", &error); -    g_assert_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_FOUND); -    g_assert(camera == NULL); +    UcaCamera *camera = uca_plugin_manager_new_camera (fixture->manager, "fox994m3a0yxmy", &error); +    g_assert_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND); +    g_assert (camera == NULL);  } -static void test_recording(Fixture *fixture, gconstpointer data) +static void +test_recording (Fixture *fixture, gconstpointer data)  {      GError *error = NULL; -    UcaCamera *camera = UCA_CAMERA(fixture->camera); +    UcaCamera *camera = UCA_CAMERA (fixture->camera); -    uca_camera_stop_recording(camera, &error); -    g_assert_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING); -    g_error_free(error); +    uca_camera_stop_recording (camera, &error); +    g_assert_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING); +    g_error_free (error);      error = NULL; -    uca_camera_start_recording(camera, &error); -    g_assert_no_error(error); -    uca_camera_stop_recording(camera, &error); -    g_assert_no_error(error); +    uca_camera_start_recording (camera, &error); +    g_assert_no_error (error); +    uca_camera_stop_recording (camera, &error); +    g_assert_no_error (error);  } -static void test_recording_signal(Fixture *fixture, gconstpointer data) +static void +test_recording_signal (Fixture *fixture, gconstpointer data)  { -    UcaCamera *camera = UCA_CAMERA(fixture->camera); +    UcaCamera *camera = UCA_CAMERA (fixture->camera);      gboolean success = FALSE; -    g_signal_connect(G_OBJECT(camera), "notify::is-recording",  +    g_signal_connect (G_OBJECT (camera), "notify::is-recording",              (GCallback) on_property_change, &success); -    uca_camera_start_recording(camera, NULL); -    g_assert(success == TRUE); +    uca_camera_start_recording (camera, NULL); +    g_assert (success == TRUE);      success = FALSE; -    uca_camera_stop_recording(camera, NULL); -    g_assert(success == TRUE); +    uca_camera_stop_recording (camera, NULL); +    g_assert (success == TRUE);  } -static void grab_func(gpointer data, gpointer user_data) +static void +grab_func (gpointer data, gpointer user_data)  {      guint *count = (guint *) user_data;      *count += 1;  } -static void test_recording_async(Fixture *fixture, gconstpointer data) +static void +test_recording_async (Fixture *fixture, gconstpointer data)  { -    UcaCamera *camera = UCA_CAMERA(fixture->camera); +    UcaCamera *camera = UCA_CAMERA (fixture->camera);      guint count = 0; -    uca_camera_set_grab_func(camera, grab_func, &count); +    uca_camera_set_grab_func (camera, grab_func, &count); -    g_object_set(G_OBJECT(camera), +    g_object_set (G_OBJECT (camera),              "frame-rate", 10.0,              "transfer-asynchronously", TRUE,              NULL);      GError *error = NULL; -    uca_camera_start_recording(camera, &error); -    g_assert_no_error(error); +    uca_camera_start_recording (camera, &error); +    g_assert_no_error (error);      /*       * We sleep for an 1/8 of a second at 10 frames per second, thus we should       * record 2 frames.       */ -    g_usleep(G_USEC_PER_SEC / 8); +    g_usleep (G_USEC_PER_SEC / 8); -    uca_camera_stop_recording(camera, &error); -    g_assert_no_error(error); -    g_assert_cmpint(count, ==, 2); +    uca_camera_stop_recording (camera, &error); +    g_assert_no_error (error); +    g_assert_cmpint (count, ==, 2);  } -static void test_recording_property(Fixture *fixture, gconstpointer data) +static void +test_recording_property (Fixture *fixture, gconstpointer data)  { -    UcaCamera *camera = UCA_CAMERA(fixture->camera); +    UcaCamera *camera = UCA_CAMERA (fixture->camera);      gboolean is_recording = FALSE; -    uca_camera_start_recording(camera, NULL); -    g_object_get(G_OBJECT(camera), +    uca_camera_start_recording (camera, NULL); +    g_object_get (G_OBJECT (camera),              "is-recording", &is_recording,              NULL); -    g_assert(is_recording == TRUE); +    g_assert (is_recording == TRUE); -    uca_camera_stop_recording(camera, NULL); -    g_object_get(G_OBJECT(camera), +    uca_camera_stop_recording (camera, NULL); +    g_object_get (G_OBJECT (camera),              "is-recording", &is_recording,              NULL); -    g_assert(is_recording == FALSE); +    g_assert (is_recording == FALSE);  } -static void test_base_properties(Fixture *fixture, gconstpointer data) +static void +test_base_properties (Fixture *fixture, gconstpointer data)  { -    UcaCamera *camera = UCA_CAMERA(fixture->camera); +    UcaCamera *camera = UCA_CAMERA (fixture->camera);      guint n_properties = 0; -    GParamSpec **properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(camera), &n_properties); +    GParamSpec **properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (camera), &n_properties);      GValue val = {0};      for (guint i = 0; i < n_properties; i++) { -        g_value_init(&val, properties[i]->value_type); -        g_object_get_property(G_OBJECT(camera), properties[i]->name, &val); -        g_value_unset(&val); +        g_value_init (&val, properties[i]->value_type); +        g_object_get_property (G_OBJECT (camera), properties[i]->name, &val); +        g_value_unset (&val);      } -    g_free(properties); +    g_free (properties);  } -static void test_binnings_properties(Fixture *fixture, gconstpointer data) +static void +test_binnings_properties (Fixture *fixture, gconstpointer data)  { -    UcaCamera *camera = UCA_CAMERA(fixture->camera); +    UcaCamera *camera = UCA_CAMERA (fixture->camera);      GValueArray *array = NULL; -    g_object_get(G_OBJECT(camera), +    g_object_get (G_OBJECT (camera),              "sensor-horizontal-binnings", &array,              NULL); -    GValue *value = g_value_array_get_nth(array, 0); -    g_assert(value != NULL); -    g_assert(g_value_get_uint(value) == 1); +    GValue *value = g_value_array_get_nth (array, 0); +    g_assert (value != NULL); +    g_assert (g_value_get_uint (value) == 1);  } -static void test_signal(Fixture *fixture, gconstpointer data) +static void +test_signal (Fixture *fixture, gconstpointer data)  { -    UcaCamera *camera = UCA_CAMERA(fixture->camera); +    UcaCamera *camera = UCA_CAMERA (fixture->camera);      gboolean success = FALSE; -    g_signal_connect(camera, "notify::frame-rate", (GCallback) on_property_change, &success); -    g_object_set(G_OBJECT(camera), +    g_signal_connect (camera, "notify::frame-rate", (GCallback) on_property_change, &success); +    g_object_set (G_OBJECT (camera),              "frame-rate", 30.0,              NULL); -    g_assert(success == TRUE); +    g_assert (success == TRUE);  } -int main(int argc, char *argv[]) +int main (int argc, char *argv[])  { -    g_type_init(); -    g_test_init(&argc, &argv, NULL); -    g_test_bug_base("http://ufo.kit.edu/ufo/ticket"); - -    g_test_add_func("/factory", test_factory); -    g_test_add("/recording", Fixture, NULL, fixture_setup, test_recording, fixture_teardown); -    g_test_add("/recording/signal", Fixture, NULL, fixture_setup, test_recording_signal, fixture_teardown); -    g_test_add("/recording/asynchronous", Fixture, NULL, fixture_setup, test_recording_async, fixture_teardown); -    g_test_add("/properties/base", Fixture, NULL, fixture_setup, test_base_properties, fixture_teardown); -    g_test_add("/properties/recording", Fixture, NULL, fixture_setup, test_recording_property, fixture_teardown); -    g_test_add("/properties/binnings", Fixture, NULL, fixture_setup, test_binnings_properties, fixture_teardown); -    g_test_add("/signal", Fixture, NULL, fixture_setup, test_signal, fixture_teardown); - -    return g_test_run(); +    g_type_init (); + +    g_test_init (&argc, &argv, NULL); +    g_test_bug_base ("http://ufo.kit.edu/ufo/ticket"); + +    g_test_add ("/factory", Fixture, NULL, fixture_setup, test_factory, fixture_teardown); +    g_test_add ("/recording", Fixture, NULL, fixture_setup, test_recording, fixture_teardown); +    g_test_add ("/recording/signal", Fixture, NULL, fixture_setup, test_recording_signal, fixture_teardown); +    g_test_add ("/recording/asynchronous", Fixture, NULL, fixture_setup, test_recording_async, fixture_teardown); +    g_test_add ("/properties/base", Fixture, NULL, fixture_setup, test_base_properties, fixture_teardown); +    g_test_add ("/properties/recording", Fixture, NULL, fixture_setup, test_recording_property, fixture_teardown); +    g_test_add ("/properties/binnings", Fixture, NULL, fixture_setup, test_binnings_properties, fixture_teardown); +    g_test_add ("/signal", Fixture, NULL, fixture_setup, test_signal, fixture_teardown); + +    return g_test_run ();  }  | 
