From 33a90d8dc20a513722f5fdf66a99cff91be422d5 Mon Sep 17 00:00:00 2001
From: Matthias Vogelgesang <matthias.vogelgesang@gmail.com>
Date: Mon, 15 Oct 2012 10:33:14 +0200
Subject: Fix replay feature

---
 tools/gui/control.c            | 54 ++++++++++++++++++++++++------------------
 tools/gui/egg-histogram-view.c | 29 ++++++++++++++++++++---
 tools/gui/egg-histogram-view.h |  3 +++
 tools/gui/ring-buffer.c        | 12 +++++-----
 tools/gui/ring-buffer.h        |  2 +-
 5 files changed, 67 insertions(+), 33 deletions(-)

(limited to 'tools')

diff --git a/tools/gui/control.c b/tools/gui/control.c
index e01bc7d..f26cafc 100644
--- a/tools/gui/control.c
+++ b/tools/gui/control.c
@@ -79,6 +79,9 @@ convert_grayscale_to_rgb (ThreadData *data, gpointer buffer)
             output[j++] = val;
             output[j++] = val;
             output[j++] = val;
+            /* if (i < 10) { */
+            /*     g_print ("%i->%i ", input[i], val); */
+            /* } */
         }
     }
     else if (data->pixel_size == 2) {
@@ -161,13 +164,11 @@ on_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
 }
 
 void
-on_destroy (GtkWidget *widget, gpointer data)
+on_destroy (GtkWidget *widget, ThreadData *data)
 {
-    ThreadData *td = (ThreadData *) data;
-
-    td->state = IDLE;
-    g_object_unref (td->camera);
-    ring_buffer_free (td->buffer);
+    data->state = IDLE;
+    g_object_unref (data->camera);
+    ring_buffer_free (data->buffer);
 
     gtk_main_quit ();
 }
@@ -184,25 +185,27 @@ set_tool_button_state (ThreadData *data)
 }
 
 static void
-on_frame_slider_changed (GtkAdjustment *adjustment, gpointer user_data)
+update_current_frame (ThreadData *data)
 {
-    ThreadData *data = (ThreadData *) user_data;
+    gpointer buffer;
+    gint index;
 
-    if (data->state == IDLE) {
-        gpointer buffer;
-        gint index;
+    index = (gint) gtk_adjustment_get_value (data->frame_slider);
+    buffer = ring_buffer_get_pointer (data->buffer, index);
+    convert_grayscale_to_rgb (data, buffer);
+    update_pixbuf (data);
+}
 
-        index = (gint) gtk_adjustment_get_value (adjustment);
-        buffer = ring_buffer_get_pointer (data->buffer, index);
-        convert_grayscale_to_rgb (data, buffer);
-        update_pixbuf (data);
-    }
+static void
+on_frame_slider_changed (GtkAdjustment *adjustment, ThreadData *data)
+{
+    if (data->state == IDLE)
+        update_current_frame (data);
 }
 
 static void
-on_start_button_clicked (GtkWidget *widget, gpointer args)
+on_start_button_clicked (GtkWidget *widget, ThreadData *data)
 {
-    ThreadData *data = (ThreadData *) args;
     GError *error = NULL;
 
     uca_camera_start_recording (data->camera, &error);
@@ -223,13 +226,11 @@ on_start_button_clicked (GtkWidget *widget, gpointer args)
 }
 
 static void
-on_stop_button_clicked (GtkWidget *widget, gpointer args)
+on_stop_button_clicked (GtkWidget *widget, ThreadData *data)
 {
-    ThreadData *data = (ThreadData *) args;
     GError *error = NULL;
 
     data->state = IDLE;
-
     set_tool_button_state (data);
     uca_camera_stop_recording (data->camera, &error);
 
@@ -238,9 +239,8 @@ on_stop_button_clicked (GtkWidget *widget, gpointer args)
 }
 
 static void
-on_record_button_clicked (GtkWidget *widget, gpointer args)
+on_record_button_clicked (GtkWidget *widget, ThreadData *data)
 {
-    ThreadData *data = (ThreadData *) args;
     GError *error = NULL;
 
     uca_camera_start_recording (data->camera, &error);
@@ -260,6 +260,13 @@ on_record_button_clicked (GtkWidget *widget, gpointer args)
     }
 }
 
+static void
+on_histogram_changed (EggHistogramView *view, ThreadData *data)
+{
+    if (data->state == IDLE)
+        update_current_frame (data);
+}
+
 static void
 create_main_window (GtkBuilder *builder, const gchar* camera_name)
 {
@@ -351,6 +358,7 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
     g_signal_connect (td.start_button, "clicked", G_CALLBACK (on_start_button_clicked), &td);
     g_signal_connect (td.stop_button, "clicked", G_CALLBACK (on_stop_button_clicked), &td);
     g_signal_connect (td.record_button, "clicked", G_CALLBACK (on_record_button_clicked), &td);
+    g_signal_connect (histogram_view, "changed", G_CALLBACK (on_histogram_changed), &td);
     g_signal_connect (window, "destroy", G_CALLBACK (on_destroy), &td);
 
     /* Layout */
diff --git a/tools/gui/egg-histogram-view.c b/tools/gui/egg-histogram-view.c
index 5041ba2..812af7a 100644
--- a/tools/gui/egg-histogram-view.c
+++ b/tools/gui/egg-histogram-view.c
@@ -55,8 +55,16 @@ enum
     N_PROPERTIES
 };
 
+enum
+{
+    CHANGED,
+    LAST_SIGNAL
+};
+
 static GParamSpec *egg_histogram_view_properties[N_PROPERTIES] = { NULL, };
 
+static guint egg_histogram_view_signals[LAST_SIGNAL] = { 0 };
+
 
 GtkWidget *
 egg_histogram_view_new (void)
@@ -253,7 +261,7 @@ egg_histogram_view_expose (GtkWidget *widget,
     cairo_rectangle (cr, BORDER, BORDER, priv->min_border + 0.5, height - 1);
     cairo_fill (cr);
 
-    cairo_rectangle (cr, priv->max_border + 0.5, BORDER, width - priv->min_border - 0.5, height - 1);
+    cairo_rectangle (cr, priv->max_border + 0.5, BORDER, width - priv->max_border + 0.5, height - 1);
     cairo_fill (cr);
 
     /* Draw spikes */
@@ -393,9 +401,14 @@ egg_histogram_view_motion_notify (GtkWidget *widget,
     priv = view->priv;
 
     if (priv->grabbing) {
-        *priv->grabbed = event->x;
+        GtkAllocation allocation;
+
+        gtk_widget_get_allocation (widget, &allocation);
 
-        gtk_widget_queue_draw (widget);
+        if ((event->x + BORDER > 0) && (event->x + BORDER < allocation.width)) {
+            *priv->grabbed = event->x;
+            gtk_widget_queue_draw (widget);
+        }
     }
     else {
         if (is_on_border (priv, event->x))
@@ -416,6 +429,7 @@ egg_histogram_view_button_release (GtkWidget *widget,
     view = EGG_HISTOGRAM_VIEW (widget);
     set_cursor_type (view, GDK_ARROW);
     view->priv->grabbing = FALSE;
+    g_signal_emit (widget, egg_histogram_view_signals[CHANGED], 0);
 
     return TRUE;
 }
@@ -473,6 +487,15 @@ egg_histogram_view_class_init (EggHistogramViewClass *klass)
     g_object_class_install_property (object_class, PROP_MINIMUM_BIN_VALUE, egg_histogram_view_properties[PROP_MINIMUM_BIN_VALUE]);
     g_object_class_install_property (object_class, PROP_MAXIMUM_BIN_VALUE, egg_histogram_view_properties[PROP_MAXIMUM_BIN_VALUE]);
 
+    egg_histogram_view_signals[CHANGED] =
+        g_signal_new ("changed",
+                      G_OBJECT_CLASS_TYPE (klass),
+                      G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
+                      G_STRUCT_OFFSET (EggHistogramViewClass, changed),
+                      NULL, NULL,
+                      g_cclosure_marshal_VOID__VOID,
+                      G_TYPE_NONE, 0);
+
     g_type_class_add_private (klass, sizeof (EggHistogramViewPrivate));
 }
 
diff --git a/tools/gui/egg-histogram-view.h b/tools/gui/egg-histogram-view.h
index 61a1c8c..7a62fca 100644
--- a/tools/gui/egg-histogram-view.h
+++ b/tools/gui/egg-histogram-view.h
@@ -44,6 +44,9 @@ struct _EggHistogramView
 struct _EggHistogramViewClass
 {
     GtkDrawingAreaClass      parent_class;
+
+    /* signals */
+    void (* changed) (EggHistogramView *view);
 };
 
 GType         egg_histogram_view_get_type (void);
diff --git a/tools/gui/ring-buffer.c b/tools/gui/ring-buffer.c
index 5915d2a..ec2638c 100644
--- a/tools/gui/ring-buffer.c
+++ b/tools/gui/ring-buffer.c
@@ -12,7 +12,7 @@ ring_buffer_new (gsize block_size,
     buffer->block_size = block_size;
     buffer->n_blocks_total = n_blocks;
     buffer->n_blocks_used = 0;
-    buffer->start_index = 0;
+    buffer->current_index = 0;
     buffer->data = g_malloc0_n (n_blocks, block_size);
 
     return buffer;
@@ -29,13 +29,13 @@ void
 ring_buffer_reset (RingBuffer *buffer)
 {
     buffer->n_blocks_used = 0;
-    buffer->start_index = 0;
+    buffer->current_index = 0;
 }
 
 gpointer
 ring_buffer_get_current_pointer (RingBuffer *buffer)
 {
-    return ring_buffer_get_pointer (buffer, 0);
+    return buffer->data + (buffer->current_index % buffer->n_blocks_total) * buffer->block_size;
 }
 
 gpointer
@@ -43,7 +43,7 @@ ring_buffer_get_pointer (RingBuffer *buffer,
                          guint       index)
 {
     g_assert (index < buffer->n_blocks_total);
-    return buffer->data + ((buffer->start_index + index) % buffer->n_blocks_total) * buffer->block_size;
+    return buffer->data + ((buffer->current_index - buffer->n_blocks_used + index) % buffer->n_blocks_total) * buffer->block_size;
 }
 
 guint
@@ -55,10 +55,10 @@ ring_buffer_get_num_blocks (RingBuffer *buffer)
 void
 ring_buffer_proceed (RingBuffer *buffer)
 {
-    buffer->start_index++;
+    buffer->current_index++;
 
     if (buffer->n_blocks_used < buffer->n_blocks_total)
         buffer->n_blocks_used++;
     else
-        buffer->start_index = buffer->start_index % buffer->n_blocks_total;
+        buffer->current_index = buffer->current_index % buffer->n_blocks_total;
 }
diff --git a/tools/gui/ring-buffer.h b/tools/gui/ring-buffer.h
index 22cbde7..9966eb7 100644
--- a/tools/gui/ring-buffer.h
+++ b/tools/gui/ring-buffer.h
@@ -10,7 +10,7 @@ typedef struct {
     gsize    block_size;
     guint    n_blocks_total;
     guint    n_blocks_used;
-    guint    start_index;
+    guint    current_index;
 } RingBuffer;
 
 RingBuffer * ring_buffer_new                  (gsize       block_size,
-- 
cgit v1.2.3