gtk: Implement ignore-alpha property and enable it by default
authorSebastian Dröge <sebastian@centricular.com>
Mon, 15 Jun 2015 18:35:38 +0000 (20:35 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 15 Jun 2015 18:35:38 +0000 (20:35 +0200)
ext/gtk/gstgtkglsink.c
ext/gtk/gstgtkglsink.h
ext/gtk/gstgtksink.c
ext/gtk/gstgtksink.h
ext/gtk/gtkgstglwidget.c
ext/gtk/gtkgstwidget.c

index 1f2a9e9..2a77aec 100644 (file)
@@ -35,6 +35,7 @@ GST_DEBUG_CATEGORY (gst_debug_gtk_gl_sink);
 #define DEFAULT_FORCE_ASPECT_RATIO  TRUE
 #define DEFAULT_PAR_N               0
 #define DEFAULT_PAR_D               1
+#define DEFAULT_IGNORE_ALPHA        TRUE
 
 static void gst_gtk_gl_sink_finalize (GObject * object);
 static void gst_gtk_gl_sink_set_property (GObject * object, guint prop_id,
@@ -70,6 +71,7 @@ enum
   PROP_WIDGET,
   PROP_FORCE_ASPECT_RATIO,
   PROP_PIXEL_ASPECT_RATIO,
+  PROP_IGNORE_ALPHA,
 };
 
 enum
@@ -120,6 +122,11 @@ gst_gtk_gl_sink_class_init (GstGtkGLSinkClass * klass)
           "The pixel aspect ratio of the device", DEFAULT_PAR_N, DEFAULT_PAR_D,
           G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_IGNORE_ALPHA,
+      g_param_spec_boolean ("ignore-alpha", "Ignore Alpha",
+          "When enabled, alpha will be ignored and converted to black",
+          DEFAULT_IGNORE_ALPHA, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&gst_gtk_gl_sink_template));
 
@@ -141,6 +148,7 @@ gst_gtk_gl_sink_init (GstGtkGLSink * gtk_sink)
   gtk_sink->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
   gtk_sink->par_n = DEFAULT_PAR_N;
   gtk_sink->par_d = DEFAULT_PAR_D;
+  gtk_sink->ignore_alpha = DEFAULT_IGNORE_ALPHA;
 }
 
 static void
@@ -173,6 +181,9 @@ gst_gtk_gl_sink_get_widget (GstGtkGLSink * gtk_sink)
   gtk_sink->bind_pixel_aspect_ratio =
       g_object_bind_property (gtk_sink, "pixel-aspect-ratio", gtk_sink->widget,
       "pixel-aspect-ratio", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+  gtk_sink->bind_ignore_alpha =
+      g_object_bind_property (gtk_sink, "ignore-alpha", gtk_sink->widget,
+      "ignore-alpha", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
 
   /* Take the floating ref, otherwise the destruction of the container will
    * make this widget disapear possibly before we are done. */
@@ -199,6 +210,9 @@ gst_gtk_gl_sink_get_property (GObject * object, guint prop_id,
     case PROP_PIXEL_ASPECT_RATIO:
       gst_value_set_fraction (value, gtk_sink->par_n, gtk_sink->par_d);
       break;
+    case PROP_IGNORE_ALPHA:
+      g_value_set_boolean (value, gtk_sink->ignore_alpha);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -219,6 +233,9 @@ gst_gtk_gl_sink_set_property (GObject * object, guint prop_id,
       gtk_sink->par_n = gst_value_get_fraction_numerator (value);
       gtk_sink->par_d = gst_value_get_fraction_denominator (value);
       break;
+    case PROP_IGNORE_ALPHA:
+      gtk_sink->ignore_alpha = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index eaf2f0c..844b28b 100644 (file)
@@ -73,6 +73,9 @@ struct _GstGtkGLSink
   gint                  par_d;
   GBinding             *bind_pixel_aspect_ratio;
 
+  gboolean              ignore_alpha;
+  GBinding             *bind_ignore_alpha;
+
   GstGtkGLSinkPrivate  *priv;
 };
 
index 09487b7..be5bf15 100644 (file)
@@ -61,6 +61,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
 #define DEFAULT_FORCE_ASPECT_RATIO  TRUE
 #define DEFAULT_PAR_N               0
 #define DEFAULT_PAR_D               1
+#define DEFAULT_IGNORE_ALPHA        TRUE
 
 enum
 {
@@ -68,6 +69,7 @@ enum
   PROP_WIDGET,
   PROP_FORCE_ASPECT_RATIO,
   PROP_PIXEL_ASPECT_RATIO,
+  PROP_IGNORE_ALPHA,
 };
 
 enum
@@ -118,6 +120,11 @@ gst_gtk_sink_class_init (GstGtkSinkClass * klass)
           "The pixel aspect ratio of the device", DEFAULT_PAR_N, DEFAULT_PAR_D,
           G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_IGNORE_ALPHA,
+      g_param_spec_boolean ("ignore-alpha", "Ignore Alpha",
+          "When enabled, alpha will be ignored and converted to black",
+          DEFAULT_IGNORE_ALPHA, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&gst_gtk_sink_template));
 
@@ -138,6 +145,7 @@ gst_gtk_sink_init (GstGtkSink * gtk_sink)
   gtk_sink->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
   gtk_sink->par_n = DEFAULT_PAR_N;
   gtk_sink->par_d = DEFAULT_PAR_D;
+  gtk_sink->ignore_alpha = DEFAULT_IGNORE_ALPHA;
 }
 
 static void
@@ -170,6 +178,9 @@ gst_gtk_sink_get_widget (GstGtkSink * gtk_sink)
   gtk_sink->bind_pixel_aspect_ratio =
       g_object_bind_property (gtk_sink, "pixel-aspect-ratio", gtk_sink->widget,
       "pixel-aspect-ratio", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+  gtk_sink->bind_ignore_alpha =
+      g_object_bind_property (gtk_sink, "ignore-alpha", gtk_sink->widget,
+      "ignore-alpha", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
 
   /* Take the floating ref, other wise the destruction of the container will
    * make this widget disapear possibly before we are done. */
@@ -194,6 +205,9 @@ gst_gtk_sink_get_property (GObject * object, guint prop_id,
     case PROP_PIXEL_ASPECT_RATIO:
       gst_value_set_fraction (value, gtk_sink->par_n, gtk_sink->par_d);
       break;
+    case PROP_IGNORE_ALPHA:
+      g_value_set_boolean (value, gtk_sink->ignore_alpha);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -214,6 +228,9 @@ gst_gtk_sink_set_property (GObject * object, guint prop_id,
       gtk_sink->par_n = gst_value_get_fraction_numerator (value);
       gtk_sink->par_d = gst_value_get_fraction_denominator (value);
       break;
+    case PROP_IGNORE_ALPHA:
+      gtk_sink->ignore_alpha = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index d3e0b7b..ded85d7 100644 (file)
@@ -64,6 +64,9 @@ struct _GstGtkSink
   gint                  par_d;
   GBinding             *bind_pixel_aspect_ratio;
 
+  gboolean              ignore_alpha;
+  GBinding             *bind_ignore_alpha;
+
   GstGtkSinkPrivate   *priv;
 };
 
index 26fa0dc..adca9cd 100644 (file)
@@ -59,12 +59,14 @@ G_DEFINE_TYPE_WITH_CODE (GtkGstGLWidget, gtk_gst_gl_widget, GTK_TYPE_GL_AREA,
 #define DEFAULT_FORCE_ASPECT_RATIO  TRUE
 #define DEFAULT_PAR_N               0
 #define DEFAULT_PAR_D               1
+#define DEFAULT_IGNORE_ALPHA        TRUE
 
 enum
 {
   PROP_0,
   PROP_FORCE_ASPECT_RATIO,
   PROP_PIXEL_ASPECT_RATIO,
+  PROP_IGNORE_ALPHA,
 };
 
 struct _GtkGstGLWidgetPrivate
@@ -74,6 +76,7 @@ struct _GtkGstGLWidgetPrivate
   /* properties */
   gboolean force_aspect_ratio;
   gint par_n, par_d;
+  gboolean ignore_alpha;
 
   gint display_width;
   gint display_height;
@@ -452,6 +455,11 @@ gtk_gst_gl_widget_set_property (GObject * object, guint prop_id,
       gtk_widget->priv->par_n = gst_value_get_fraction_numerator (value);
       gtk_widget->priv->par_d = gst_value_get_fraction_denominator (value);
       break;
+    case PROP_IGNORE_ALPHA:
+      gtk_widget->priv->ignore_alpha = g_value_get_boolean (value);
+      gtk_gl_area_set_has_alpha ((GtkGLArea *) gtk_widget,
+          !gtk_widget->priv->ignore_alpha);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -472,6 +480,9 @@ gtk_gst_gl_widget_get_property (GObject * object, guint prop_id, GValue * value,
       gst_value_set_fraction (value, gtk_widget->priv->par_n,
           gtk_widget->priv->par_d);
       break;
+    case PROP_IGNORE_ALPHA:
+      g_value_set_boolean (value, gtk_widget->priv->ignore_alpha);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -503,6 +514,11 @@ gtk_gst_gl_widget_class_init (GtkGstGLWidgetClass * klass)
           "The pixel aspect ratio of the device", DEFAULT_PAR_N, DEFAULT_PAR_D,
           G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_klass, PROP_IGNORE_ALPHA,
+      g_param_spec_boolean ("ignore-alpha", "Ignore Alpha",
+          "When enabled, alpha will be ignored and converted to black",
+          DEFAULT_IGNORE_ALPHA, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gl_widget_klass->render = gtk_gst_gl_widget_render;
 
   widget_klass->get_preferred_width = gtk_gst_gl_widget_get_preferred_width;
@@ -519,6 +535,7 @@ gtk_gst_gl_widget_init (GtkGstGLWidget * widget)
   widget->priv->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
   widget->priv->par_n = DEFAULT_PAR_N;
   widget->priv->par_d = DEFAULT_PAR_D;
+  widget->priv->ignore_alpha = DEFAULT_IGNORE_ALPHA;
 
   g_mutex_init (&widget->priv->lock);
 
@@ -544,7 +561,7 @@ gtk_gst_gl_widget_init (GtkGstGLWidget * widget)
   if (!widget->priv->display)
     widget->priv->display = gst_gl_display_new ();
 
-  gtk_gl_area_set_has_alpha ((GtkGLArea *) widget, FALSE);
+  gtk_gl_area_set_has_alpha ((GtkGLArea *) widget, !widget->priv->ignore_alpha);
 }
 
 GtkWidget *
index 7607bd5..ac3e5a9 100644 (file)
@@ -43,12 +43,14 @@ G_DEFINE_TYPE (GtkGstWidget, gtk_gst_widget, GTK_TYPE_DRAWING_AREA);
 #define DEFAULT_FORCE_ASPECT_RATIO  TRUE
 #define DEFAULT_PAR_N               0
 #define DEFAULT_PAR_D               1
+#define DEFAULT_IGNORE_ALPHA        TRUE
 
 enum
 {
   PROP_0,
   PROP_FORCE_ASPECT_RATIO,
   PROP_PIXEL_ASPECT_RATIO,
+  PROP_IGNORE_ALPHA,
 };
 
 struct _GtkGstWidgetPrivate
@@ -58,6 +60,7 @@ struct _GtkGstWidgetPrivate
   /* properties */
   gboolean force_aspect_ratio;
   gint par_n, par_d;
+  gboolean ignore_alpha;
 
   gint display_width;
   gint display_height;
@@ -151,6 +154,30 @@ gtk_gst_widget_draw (GtkWidget * widget, cairo_t * cr)
       result.h = widget_height;
     }
 
+    if (gst_widget->priv->ignore_alpha) {
+      GdkRGBA color = { 0.0, 0.0, 0.0, 1.0 };
+
+      gdk_cairo_set_source_rgba (cr, &color);
+      if (result.x > 0) {
+        cairo_rectangle (cr, 0, 0, result.x, widget_height);
+        cairo_fill (cr);
+      }
+      if (result.y > 0) {
+        cairo_rectangle (cr, 0, 0, widget_width, result.y);
+        cairo_fill (cr);
+      }
+      if (result.w < widget_width) {
+        cairo_rectangle (cr, result.x + result.w, 0, widget_width - result.w,
+            widget_height);
+        cairo_fill (cr);
+      }
+      if (result.h < widget_height) {
+        cairo_rectangle (cr, 0, result.y + result.h, widget_width,
+            widget_height - result.h);
+        cairo_fill (cr);
+      }
+    }
+
     scale_x *=
         (gdouble) gst_widget->priv->display_width / (gdouble) frame.info.width;
     scale_y *=
@@ -169,8 +196,13 @@ gtk_gst_widget_draw (GtkWidget * widget, cairo_t * cr)
   } else {
     GdkRGBA color;
 
-    gtk_style_context_get_color (gtk_widget_get_style_context (widget), 0,
-        &color);
+    if (gst_widget->priv->ignore_alpha) {
+      color.red = color.blue = color.green = 0.0;
+      color.alpha = 1.0;
+    } else {
+      gtk_style_context_get_color (gtk_widget_get_style_context (widget),
+          GTK_STATE_FLAG_NORMAL, &color);
+    }
     gdk_cairo_set_source_rgba (cr, &color);
     cairo_rectangle (cr, 0, 0, widget_width, widget_height);
     cairo_fill (cr);
@@ -205,6 +237,9 @@ gtk_gst_widget_set_property (GObject * object, guint prop_id,
       gtk_widget->priv->par_n = gst_value_get_fraction_numerator (value);
       gtk_widget->priv->par_d = gst_value_get_fraction_denominator (value);
       break;
+    case PROP_IGNORE_ALPHA:
+      gtk_widget->priv->ignore_alpha = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -224,6 +259,8 @@ gtk_gst_widget_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_PIXEL_ASPECT_RATIO:
       gst_value_set_fraction (value, gtk_widget->priv->par_n,
           gtk_widget->priv->par_d);
+    case PROP_IGNORE_ALPHA:
+      g_value_set_boolean (value, gtk_widget->priv->ignore_alpha);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -255,6 +292,11 @@ gtk_gst_widget_class_init (GtkGstWidgetClass * klass)
           "The pixel aspect ratio of the device", DEFAULT_PAR_N, DEFAULT_PAR_D,
           G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_klass, PROP_IGNORE_ALPHA,
+      g_param_spec_boolean ("ignore-alpha", "Ignore Alpha",
+          "When enabled, alpha will be ignored and converted to black",
+          DEFAULT_IGNORE_ALPHA, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   widget_klass->draw = gtk_gst_widget_draw;
   widget_klass->get_preferred_width = gtk_gst_widget_get_preferred_width;
   widget_klass->get_preferred_height = gtk_gst_widget_get_preferred_height;
@@ -268,6 +310,7 @@ gtk_gst_widget_init (GtkGstWidget * widget)
   widget->priv->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
   widget->priv->par_n = DEFAULT_PAR_N;
   widget->priv->par_d = DEFAULT_PAR_D;
+  widget->priv->ignore_alpha = DEFAULT_IGNORE_ALPHA;
 
   g_mutex_init (&widget->priv->lock);
 }