diff options
-rw-r--r-- | src/grabbers/me4.c | 3 | ||||
-rw-r--r-- | src/uca.c | 1 | ||||
-rw-r--r-- | test/CMakeLists.txt | 16 | ||||
-rw-r--r-- | test/control.c | 163 | ||||
-rw-r--r-- | test/control.glade | 245 |
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) @@ -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> |