summaryrefslogtreecommitdiffstats
path: root/zbarcam/zbarcam-gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'zbarcam/zbarcam-gtk.c')
-rw-r--r--zbarcam/zbarcam-gtk.c231
1 files changed, 231 insertions, 0 deletions
diff --git a/zbarcam/zbarcam-gtk.c b/zbarcam/zbarcam-gtk.c
new file mode 100644
index 0000000..1c7930a
--- /dev/null
+++ b/zbarcam/zbarcam-gtk.c
@@ -0,0 +1,231 @@
+/*------------------------------------------------------------------------
+ * Copyright 2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ * This file is part of the ZBar Bar Code Reader.
+ *
+ * The ZBar Bar Code Reader is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The ZBar Bar Code Reader 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 Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser Public License
+ * along with the ZBar Bar Code Reader; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+
+#include <gtk/gtk.h>
+#include <zbar/zbargtk.h>
+
+static GtkWidget *window = NULL;
+static GtkWidget *status_image = NULL;
+static GtkTextView *results = NULL;
+static gchar *open_file = NULL;
+
+int scan_video(void *add_device, void *userdata, const char *default_device);
+
+/* decode signal callback
+ * puts the decoded result in the textbox
+ */
+static void decoded(GtkWidget *widget, zbar_symbol_type_t symbol,
+ const char *result, gpointer data)
+{
+ GtkTextBuffer *resultbuf = gtk_text_view_get_buffer(results);
+ GtkTextIter end;
+ gtk_text_buffer_get_end_iter(resultbuf, &end);
+ gtk_text_buffer_insert(resultbuf, &end, zbar_get_symbol_name(symbol), -1);
+ gtk_text_buffer_insert(resultbuf, &end, ":", -1);
+ gtk_text_buffer_insert(resultbuf, &end, result, -1);
+ gtk_text_buffer_insert(resultbuf, &end, "\n", -1);
+ gtk_text_view_scroll_to_iter(results, &end, 0, FALSE, 0, 0);
+}
+
+/* update button state when video state changes
+ */
+static void video_enabled(GObject *object, GParamSpec *param, gpointer data)
+{
+ ZBarGtk *zbar = ZBAR_GTK(object);
+ gboolean enabled = zbar_gtk_get_video_enabled(zbar);
+ gboolean opened = zbar_gtk_get_video_opened(zbar);
+
+ GtkToggleButton *button = GTK_TOGGLE_BUTTON(data);
+ gboolean active = gtk_toggle_button_get_active(button);
+ if (active != (opened && enabled))
+ gtk_toggle_button_set_active(button, enabled);
+}
+
+static void video_opened(GObject *object, GParamSpec *param, gpointer data)
+{
+ ZBarGtk *zbar = ZBAR_GTK(object);
+ gboolean opened = zbar_gtk_get_video_opened(zbar);
+ gboolean enabled = zbar_gtk_get_video_enabled(zbar);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data), opened && enabled);
+ gtk_widget_set_sensitive(GTK_WIDGET(data), opened);
+}
+
+/* (re)open the video when a new device is selected
+ */
+static void video_changed(GtkWidget *widget, gpointer data)
+{
+ const char *video_device =
+ gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(widget));
+ zbar_gtk_set_video_device(
+ ZBAR_GTK(data),
+ ((video_device && video_device[0] != '<') ? video_device : NULL));
+}
+
+static void status_button_toggled(GtkToggleButton *button, gpointer data)
+{
+ ZBarGtk *zbar = ZBAR_GTK(data);
+ gboolean opened = zbar_gtk_get_video_opened(zbar);
+ gboolean enabled = zbar_gtk_get_video_enabled(zbar);
+ gboolean active = gtk_toggle_button_get_active(button);
+ if (opened && (active != enabled))
+ zbar_gtk_set_video_enabled(ZBAR_GTK(data), active);
+ gtk_image_set_from_icon_name(GTK_IMAGE(status_image),
+ (opened && active) ? "gtk-yes" : "gtk-no",
+ GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_label(GTK_BUTTON(button), (!opened) ? "closed" :
+ (active) ? "enabled" :
+ "disabled");
+}
+
+static void open_button_clicked(GtkButton *button, gpointer data)
+{
+ GtkWidget *dialog =
+ gtk_file_chooser_dialog_new("Open Image File", GTK_WINDOW(window),
+ GTK_FILE_CHOOSER_ACTION_OPEN, "gtk-cancel",
+ GTK_RESPONSE_CANCEL, "gtk-open",
+ GTK_RESPONSE_ACCEPT, NULL);
+ GtkFileChooser *chooser = GTK_FILE_CHOOSER(dialog);
+ if (open_file)
+ gtk_file_chooser_set_filename(chooser, open_file);
+
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+ gchar *file = gtk_file_chooser_get_filename(chooser);
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(file, NULL);
+ if (pixbuf)
+ zbar_gtk_scan_image(ZBAR_GTK(data), pixbuf);
+ else
+ fprintf(stderr, "ERROR: unable to open image file: %s\n", file);
+
+ if (open_file && file)
+ g_free(open_file);
+ open_file = file;
+ }
+ gtk_widget_destroy(dialog);
+}
+
+/* build a simple gui w/:
+ * - a combo box to select the desired video device
+ * - the zbar widget to display video
+ * - a non-editable text box to display any results
+ */
+int main(int argc, char *argv[])
+{
+ const char *video_arg = NULL;
+
+ gdk_set_allowed_backends("x11,*");
+ gtk_init(&argc, &argv);
+
+ if (argc > 1)
+ video_arg = argv[1];
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ gtk_window_set_title(GTK_WINDOW(window), "test_gtk");
+ gtk_container_set_border_width(GTK_CONTAINER(window), 8);
+
+ g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit),
+ NULL);
+
+ GtkWidget *zbar = zbar_gtk_new();
+
+ g_signal_connect(G_OBJECT(zbar), "decoded", G_CALLBACK(decoded), NULL);
+
+ /* video device list combo box */
+ GtkWidget *video_list = gtk_combo_box_text_new();
+
+ g_signal_connect(G_OBJECT(video_list), "changed", G_CALLBACK(video_changed),
+ zbar);
+
+ /* enable/disable status button */
+ GtkWidget *status_button = gtk_toggle_button_new();
+ status_image = gtk_image_new_from_icon_name("gtk-no", GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image(GTK_BUTTON(status_button), status_image);
+ gtk_button_set_label(GTK_BUTTON(status_button), "closed");
+ gtk_widget_set_sensitive(status_button, FALSE);
+
+ /* bind status button state and video state */
+ g_signal_connect(G_OBJECT(status_button), "toggled",
+ G_CALLBACK(status_button_toggled), zbar);
+ g_signal_connect(G_OBJECT(zbar), "notify::video-enabled",
+ G_CALLBACK(video_enabled), status_button);
+ g_signal_connect(G_OBJECT(zbar), "notify::video-opened",
+ G_CALLBACK(video_opened), status_button);
+
+ /* open image file button */
+#if GTK_MAJOR_VERSION >= 3
+ GtkWidget *open_button =
+ gtk_button_new_from_icon_name("gtk-open", GTK_ICON_SIZE_BUTTON);
+#else
+ GtkWidget *open_button = gtk_button_new_from_stock(GTK_STOCK_OPEN);
+#endif
+
+ g_signal_connect(G_OBJECT(open_button), "clicked",
+ G_CALLBACK(open_button_clicked), zbar);
+
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(video_list), "<none>");
+ int active =
+ scan_video(gtk_combo_box_text_append_text, video_list, video_arg);
+ if (active >= 0)
+ gtk_combo_box_set_active(GTK_COMBO_BOX(video_list), active);
+
+ /* hbox for combo box and buttons */
+#if GTK_MAJOR_VERSION >= 3
+ GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
+#else
+ GtkWidget *hbox = gtk_hbox_new(FALSE, 8);
+#endif
+
+ gtk_box_pack_start(GTK_BOX(hbox), video_list, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), status_button, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), open_button, FALSE, FALSE, 0);
+
+ /* text box for holding results */
+ results = GTK_TEXT_VIEW(gtk_text_view_new());
+ gtk_widget_set_size_request(GTK_WIDGET(results), 320, 64);
+ gtk_text_view_set_editable(results, FALSE);
+ gtk_text_view_set_cursor_visible(results, FALSE);
+ gtk_text_view_set_left_margin(results, 4);
+
+ /* vbox for hbox, zbar test widget and result text box */
+#if GTK_MAJOR_VERSION >= 3
+ GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
+#else
+ GtkWidget *vbox = gtk_vbox_new(FALSE, 8);
+#endif
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), zbar, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(results), FALSE, FALSE, 0);
+
+ GdkGeometry hints;
+ hints.min_width = 320;
+ hints.min_height = 240;
+ gtk_window_set_geometry_hints(GTK_WINDOW(window), zbar, &hints,
+ GDK_HINT_MIN_SIZE);
+
+ gtk_widget_show_all(window);
+ gtk_main();
+ return (0);
+}