summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/grabbers/me4.c3
-rw-r--r--src/uca.c1
-rw-r--r--test/CMakeLists.txt16
-rw-r--r--test/control.c163
-rw-r--r--test/control.glade245
5 files changed, 427 insertions, 1 deletions
diff --git a/src/grabbers/me4.c b/src/grabbers/me4.c
index 4cdb14a..17b46e3 100644
--- a/src/grabbers/me4.c
+++ b/src/grabbers/me4.c
@@ -18,7 +18,8 @@ struct uca_me4_grabber_t {
uint32_t uca_me4_destroy(struct uca_grabber_t *grabber)
{
- Fg_FreeGrabber(GET_FG(grabber));
+ if (grabber != NULL)
+ Fg_FreeGrabber(GET_FG(grabber));
}
uint32_t uca_me4_set_property(struct uca_grabber_t *grabber, enum uca_property_ids property, void *data)
diff --git a/src/uca.c b/src/uca.c
index b70c25a..7cbe8b8 100644
--- a/src/uca.c
+++ b/src/uca.c
@@ -98,6 +98,7 @@ struct uca_t *uca_init(void)
free(uca);
return NULL;
}
+ uca->grabbers = grabber;
grabber->next = NULL;
/* Probe each camera that is configured */
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 3f1e2a5..d1f1d67 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -2,10 +2,26 @@ cmake_minimum_required(VERSION 2.8)
add_definitions("--std=c99 -Wall")
+# --- Find packages and libraries ---------------------------------------------
+find_package(PkgConfig)
+
+pkg_check_modules(GTK2 gtk+-2.0)
+
include_directories(${CMAKE_SOURCE_DIR}/src)
+# --- Build targets -----------------------------------------------------------
add_executable(enum enum.c)
add_executable(grab grab.c)
target_link_libraries(enum uca)
target_link_libraries(grab uca)
+
+if (GTK2_FOUND)
+ include_directories(${GTK2_INCLUDE_DIRS})
+ add_executable(control control.c)
+ target_link_libraries(control
+ uca
+ ${GTK2_LIBRARIES}
+ )
+endif()
+
diff --git a/test/control.c b/test/control.c
new file mode 100644
index 0000000..dd71f47
--- /dev/null
+++ b/test/control.c
@@ -0,0 +1,163 @@
+#include <glib/gprintf.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "uca.h"
+#include "uca-cam.h"
+
+struct ThreadData {
+ guchar *buffer, *pixels;
+ GtkWidget *image;
+ GdkPixbuf *pixbuf;
+ int width;
+ int height;
+
+ struct uca_camera_t *cam;
+};
+
+static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+ return FALSE;
+}
+
+/* Another callback */
+static void destroy(GtkWidget *widget, gpointer data)
+{
+ struct uca_t *uca = (struct uca_t *) data;
+ uca_destroy(uca);
+ gtk_main_quit ();
+}
+
+void grey_to_rgb(guchar *output, guchar *input, int width, int height)
+{
+ for (int x = 0; x < width; x++) {
+ for (int y = 0; y < height; y++) {
+ const int off = y*width + x;
+ output[off*3] = input[off];
+ output[off*3+1] = input[off];
+ output[off*3+2] = input[off];
+ }
+ }
+}
+
+void *grab_thread(void *args)
+{
+ struct ThreadData *data = (struct ThreadData *) args;
+ struct uca_camera_t *cam = data->cam;
+
+ while (TRUE) {
+ cam->grab(cam, (char *) data->buffer);
+ grey_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();
+ }
+}
+
+void fill_tree_store(GtkTreeStore *tree_store, struct uca_camera_t *cam)
+{
+ GtkTreeIter iter, child;
+ struct uca_property_t *property;
+ gchar *value_string = g_malloc(256);
+ guint8 value_8;
+ guint32 value_32;
+
+ gtk_tree_store_append(tree_store, &iter, NULL);
+ for (int prop_id = 0; prop_id < UCA_PROP_LAST; prop_id++) {
+ property = uca_get_full_property(prop_id);
+ switch (property->type) {
+ case uca_string:
+ cam->get_property(cam, prop_id, value_string);
+ break;
+
+ case uca_uint8t:
+ cam->get_property(cam, prop_id, &value_8);
+ g_sprintf(value_string, "%d", value_8);
+ break;
+
+ case uca_uint32t:
+ cam->get_property(cam, prop_id, &value_32);
+ g_sprintf(value_string, "%d", value_32);
+ break;
+ }
+ gtk_tree_store_set(tree_store, &iter,
+ 0, property->name,
+ 1, value_string,
+ -1);
+ gtk_tree_store_append(tree_store, &iter, NULL);
+ }
+
+ g_free(value_string);
+}
+
+int main(int argc, char *argv[])
+{
+ struct uca_t *uca = uca_init();
+ if (uca == NULL) {
+ g_print("Couldn't initialize frame grabber and/or cameras\n");
+ return 1;
+ }
+
+ int width, height, bits_per_sample;
+ struct uca_camera_t *cam = uca->cameras;
+ cam->get_property(cam, UCA_PROP_WIDTH, &width);
+ cam->get_property(cam, UCA_PROP_HEIGHT, &height);
+ cam->get_property(cam, UCA_PROP_BITDEPTH, &bits_per_sample);
+ bits_per_sample = 8;
+
+ g_thread_init(NULL);
+ gdk_threads_init();
+ gtk_init (&argc, &argv);
+
+ GtkBuilder *builder = gtk_builder_new();
+ GError *error = NULL;
+ if (!gtk_builder_add_from_file(builder, "control.glade", &error)) {
+ g_print("Couldn't load UI file!\n");
+ g_print("Message: %s\n", error->message);
+ g_free(error);
+ }
+
+ GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
+ GtkWidget *image = GTK_WIDGET(gtk_builder_get_object(builder, "image"));
+ GtkTreeStore *tree_store = GTK_TREE_STORE(gtk_builder_get_object(builder, "cameraproperties"));
+ fill_tree_store(tree_store, cam);
+
+ g_signal_connect (window, "delete-event",
+ G_CALLBACK (delete_event), NULL);
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (destroy), uca);
+
+ GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, bits_per_sample, width, height);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
+
+ gtk_widget_show(image);
+ gtk_widget_show(window);
+
+ /* start grabbing and thread */
+ struct ThreadData td;
+ uca_cam_alloc(cam, 20);
+ td.image = image;
+ td.pixbuf = pixbuf;
+ td.buffer = (guchar *) g_malloc(width * height);
+ td.pixels = gdk_pixbuf_get_pixels(pixbuf);
+ td.width = width;
+ td.height = height;
+ td.cam = cam;
+ cam->start_recording(cam);
+ if (!g_thread_create(grab_thread, &td, FALSE, &error)) {
+ g_printerr("Failed to create thread: %s\n", error->message);
+ uca_destroy(uca);
+ return 1;
+ }
+
+ gdk_threads_enter();
+ gtk_main ();
+ gdk_threads_leave();
+
+ return 0;
+}
diff --git a/test/control.glade b/test/control.glade
new file mode 100644
index 0000000..c56ddfe
--- /dev/null
+++ b/test/control.glade
@@ -0,0 +1,245 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.20"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkTreeStore" id="cameraproperties">
+ <columns>
+ <!-- column-name PropertyName -->
+ <column type="gchararray"/>
+ <!-- column-name PropertyValue -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkWindow" id="window">
+ <property name="title" translatable="yes">Camera Control</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="menu1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem1">
+ <property name="label">gtk-new</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem2">
+ <property name="label">gtk-open</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem3">
+ <property name="label">gtk-save</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem4">
+ <property name="label">gtk-save-as</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem5">
+ <property name="label">gtk-quit</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menuitem2">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">_Edit</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="menu2">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem6">
+ <property name="label">gtk-cut</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem7">
+ <property name="label">gtk-copy</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem8">
+ <property name="label">gtk-paste</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem9">
+ <property name="label">gtk-delete</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menuitem3">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">_View</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menuitem4">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="menu3">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImageMenuItem" id="imagemenuitem10">
+ <property name="label">gtk-about</property>
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolbar" id="toolbar">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHPaned" id="hpaned1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkImage" id="image">
+ <property name="visible">True</property>
+ <property name="stock">gtk-missing-image</property>
+ </object>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTreeView" id="treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">cameraproperties</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="namecolumn">
+ <property name="title" translatable="yes">Name</property>
+ <child>
+ <object class="GtkCellRendererText" id="namecell"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="valuecolumn">
+ <property name="title" translatable="yes">Value</property>
+ <child>
+ <object class="GtkCellRendererText" id="valuecell"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkStatusbar" id="statusbar1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>