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 /src | |
parent | e6a6eb9aede59a1f7441b926b36afefd9c42b91d (diff) | |
parent | 9f262857d13a3e0d7ee214b33b90359c51227718 (diff) | |
download | uca-6eaadaa0e4ad8ce906aa8ccee63d91f0d9cb28ea.tar.gz uca-6eaadaa0e4ad8ce906aa8ccee63d91f0d9cb28ea.tar.bz2 uca-6eaadaa0e4ad8ce906aa8ccee63d91f0d9cb28ea.tar.xz uca-6eaadaa0e4ad8ce906aa8ccee63d91f0d9cb28ea.zip |
Merge branch 'plugins'
Diffstat (limited to 'src')
-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 |
12 files changed, 685 insertions, 392 deletions
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 |