示例#1
0
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_stock(GTK_IMAGE(status_image),
                             (opened && active) ? GTK_STOCK_YES : GTK_STOCK_NO,
                             GTK_ICON_SIZE_BUTTON);
    gtk_button_set_label(GTK_BUTTON(button),
                         (!opened) ? "closed" :
                         (active) ? "enabled" : "disabled");
}
示例#2
0
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_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                    GTK_STOCK_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);
}
示例#3
0
static void zbar_gtk_get_property (GObject *object,
                                   guint prop_id,
                                   GValue *value,
                                   GParamSpec *pspec)
{
    ZBarGtk *self = ZBAR_GTK(object);
    if(!self->_private)
        return;
    ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private);

    switch(prop_id) {
    case PROP_VIDEO_DEVICE:
        if(zbar->video_device)
            g_value_set_string(value, zbar->video_device);
        else
            g_value_set_static_string(value, "");
        break;
    case PROP_VIDEO_ENABLED:
        g_value_set_boolean(value, zbar->video_enabled);
        break;
    case PROP_VIDEO_OPENED:
        g_value_set_boolean(value, zbar->video_opened);
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    }
}
示例#4
0
static void zbar_gtk_unrealize (GtkWidget *widget)
{
    if(GTK_WIDGET_MAPPED(widget))
        gtk_widget_unmap(widget);

    ZBarGtk *self = ZBAR_GTK(widget);
    if(!self->_private)
        return;
    ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private);

    if(zbar->video_enabled) {
        zbar->video_enabled = FALSE;
        GValue *msg = zbar_gtk_new_value(G_TYPE_INT);
        g_value_set_int(msg, 0);
        g_async_queue_push(zbar->queue, msg);
    }

    zbar_window_attach(zbar->window, NULL, 0);

    GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);

    gdk_window_set_user_data(widget->window, NULL);
    gdk_window_destroy(widget->window);
    widget->window = NULL;
}
示例#5
0
static void zbar_gtk_realize (GtkWidget *widget)
{
    ZBarGtk *self = ZBAR_GTK(widget);
    if(!self->_private)
        return;
    ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private);

    GTK_WIDGET_UNSET_FLAGS(widget, GTK_DOUBLE_BUFFERED);
    GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);

    GdkWindowAttr attributes;
    attributes.x = widget->allocation.x;
    attributes.y = widget->allocation.y;
    attributes.width = widget->allocation.width;
    attributes.height = widget->allocation.height;
    attributes.wclass = GDK_INPUT_OUTPUT;
    attributes.window_type = GDK_WINDOW_CHILD;
    attributes.event_mask = (gtk_widget_get_events(widget) |
                             GDK_EXPOSURE_MASK);

    widget->window = gdk_window_new(gtk_widget_get_parent_window(widget),
                                    &attributes,
                                    GDK_WA_X | GDK_WA_Y);
    gdk_window_set_user_data(widget->window, widget);
    gdk_window_set_back_pixmap(widget->window, NULL, TRUE);

    /* attach zbar_window to underlying X window */
    if(zbar_window_attach(zbar->window,
                           gdk_x11_drawable_get_xdisplay(widget->window),
                           gdk_x11_drawable_get_xid(widget->window)))
        zbar_window_error_spew(zbar->window, 0);
}
示例#6
0
/* (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_get_active_text(GTK_COMBO_BOX(widget));
    zbar_gtk_set_video_device(ZBAR_GTK(data),
                               ((video_device && video_device[0] != '<')
                                ? video_device
                                : NULL));
}
示例#7
0
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);
}
示例#8
0
/* update botton 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);
}
示例#9
0
static gboolean zbar_gtk_expose (GtkWidget *widget,
                                 GdkEventExpose *event)
{
    ZBarGtk *self = ZBAR_GTK(widget);
    if(!self->_private)
        return(FALSE);
    ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private);

    if(GTK_WIDGET_VISIBLE(widget) &&
       GTK_WIDGET_MAPPED(widget) &&
       zbar_window_redraw(zbar->window))
        return(TRUE);
    return(FALSE);
}
示例#10
0
static void zbar_gtk_size_allocate (GtkWidget *widget,
                                    GtkAllocation *allocation)
{
    ZBarGtk *self = ZBAR_GTK(widget);
    if(!self->_private)
        return;
    ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private);

    (*GTK_WIDGET_CLASS(zbar_gtk_parent_class)->size_allocate)
        (widget, allocation);
    if(zbar->window)
        zbar_window_resize(zbar->window,
                            allocation->width, allocation->height);
}
示例#11
0
static void zbar_gtk_size_request (GtkWidget *widget,
                                   GtkRequisition *requisition)
{
    ZBarGtk *self = ZBAR_GTK(widget);
    if(!self->_private)
        return;
    ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private);

    /* use native video size (max) if available,
     * arbitrary defaults otherwise.
     * video attributes maintained under main gui thread lock
     */
    requisition->width = zbar->req_width;
    requisition->height = zbar->req_height;
}
示例#12
0
static void zbar_gtk_set_property (GObject *object,
                                   guint prop_id,
                                   const GValue *value,
                                   GParamSpec *pspec)
{
    ZBarGtk *self = ZBAR_GTK(object);
    switch(prop_id) {
    case PROP_VIDEO_DEVICE:
        zbar_gtk_set_video_device(self, g_value_get_string(value));
        break;
    case PROP_VIDEO_ENABLED:
        zbar_gtk_set_video_enabled(self, g_value_get_boolean(value));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
    }
}
示例#13
0
static void zbar_gtk_dispose (GObject *object)
{
    ZBarGtk *self = ZBAR_GTK(object);
    if(!self->_private)
        return;

    ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private);
    self->_private = NULL;

    g_free((void*)zbar->video_device);
    zbar->video_device = NULL;

    /* signal processor thread to exit */
    GValue *msg = zbar_gtk_new_value(G_TYPE_INT);
    g_value_set_int(msg, -1);
    g_async_queue_push(zbar->queue, msg);
    zbar->thread = NULL;

    /* there are no external references which might call other APIs */
    g_async_queue_unref(zbar->queue);

    g_object_unref(G_OBJECT(zbar));
}
示例#14
0
static void *zbar_gtk_processing_thread (void *arg)
{
    ZBarGtk *self = ZBAR_GTK(arg);
    if(!self->_private)
        return(NULL);
    ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private);
    g_object_ref(zbar);
    g_assert(zbar->queue);
    g_async_queue_ref(zbar->queue);

    zbar->scanner = zbar_image_scanner_create();
    g_assert(zbar->scanner);

    /* thread side enabled state */
    gboolean video_enabled = FALSE;
    GValue *msg = NULL;

    while(TRUE) {
        if(!msg)
            msg = g_async_queue_pop(zbar->queue);
        g_assert(G_IS_VALUE(msg));

        GType type = G_VALUE_TYPE(msg);
        if(type == G_TYPE_INT) {
            /* video state change */
            int state = g_value_get_int(msg);
            if(state < 0) {
                /* terminate processing thread */
                g_value_unset(msg);
                g_free(msg);
                msg = NULL;
                break;
            }
            g_assert(state >= 0 && state <= 1);
            video_enabled = (state != 0);
        }
        else if(type == G_TYPE_STRING) {
            /* open new video device */
            const char *video_device = g_value_get_string(msg);
            video_enabled = zbar_gtk_video_open(self, video_device);
        }
        else if(type == GDK_TYPE_PIXBUF) {
            /* scan provided image and broadcast results */
            zbar_image_t *image = zbar_image_create();
            GdkPixbuf *pixbuf = GDK_PIXBUF(g_value_dup_object(msg));
            if(zbar_gtk_image_from_pixbuf(image, pixbuf))
                zbar_gtk_process_image(self, image);
            else
                g_object_unref(pixbuf);
            zbar_image_destroy(image);
        }
        else {
            gchar *dbg = g_strdup_value_contents(msg);
            g_warning("unknown message type (%x) passed to thread: %s\n",
                      (unsigned)type, dbg);
            g_free(dbg);
        }
        g_value_unset(msg);
        g_free(msg);
        msg = NULL;

        if(video_enabled) {
            /* release reference to any previous pixbuf */
            zbar_window_draw(zbar->window, NULL);

            if(zbar_video_enable(zbar->video, 1)) {
                zbar_video_error_spew(zbar->video, 0);
                video_enabled = FALSE;
                continue;
            }
            zbar_image_scanner_enable_cache(zbar->scanner, 1);

            while(video_enabled &&
                  !(msg = g_async_queue_try_pop(zbar->queue))) {
                zbar_image_t *image = zbar_video_next_image(zbar->video);
                if(zbar_gtk_process_image(self, image) < 0)
                    video_enabled = FALSE;
                if(image)
                    zbar_image_destroy(image);
            }

            zbar_image_scanner_enable_cache(zbar->scanner, 0);
            if(zbar_video_enable(zbar->video, 0)) {
                zbar_video_error_spew(zbar->video, 0);
                video_enabled = FALSE;
            }
            /* release video image and revert to logo */
            if(zbar->window) {
                zbar_window_draw(zbar->window, NULL);
                gtk_widget_queue_draw(GTK_WIDGET(self));
            }

            if(!video_enabled)
                /* must have been an error while streaming */
                zbar_gtk_video_open(self, NULL);
        }
    }
    if(zbar->window)
        zbar_window_draw(zbar->window, NULL);
    g_object_unref(zbar);
    return(NULL);
}