[cheese] First pass at webcam widget for use in other applications



commit c032a30cb1bb8d66b13b938cc9d729af8cdeeeb1
Author: Bastien Nocera <hadess hadess net>
Date:   Tue Dec 1 16:00:44 2009 +0000

    First pass at webcam widget for use in other applications
    
    https://bugzilla.gnome.org/show_bug.cgi?id=522199

 .gitignore                           |    1 +
 libcheese/Makefile.am                |   25 +++-
 {src => libcheese}/cheese-fileutil.c |    0
 {src => libcheese}/cheese-fileutil.h |    0
 {src => libcheese}/cheese-flash.c    |    0
 {src => libcheese}/cheese-flash.h    |    0
 {src => libcheese}/cheese-gconf.c    |    0
 {src => libcheese}/cheese-gconf.h    |    0
 libcheese/cheese-test-widget.c       |   48 ++++++
 libcheese/cheese-widget.c            |  280 ++++++++++++++++++++++++++++++++++
 libcheese/cheese-widget.h            |   57 +++++++
 src/Makefile.am                      |    8 +-
 12 files changed, 409 insertions(+), 10 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index acdf6da..e7f74ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,4 @@ help/*/cheese.xml
 .waf-*
 _build_
 *.swp
+libcheese/cheese-test-widget
diff --git a/libcheese/Makefile.am b/libcheese/Makefile.am
index f906ef6..cc4cbc3 100644
--- a/libcheese/Makefile.am
+++ b/libcheese/Makefile.am
@@ -1,4 +1,4 @@
-libcheese_la_CFLAGS = \
+INCLUDES = \
 	-DDATADIR=\"$(datadir)\" \
 	-DPREFIX=\""$(prefix)"\" \
 	-DSYSCONFDIR=\""$(sysconfdir)"\" \
@@ -10,14 +10,33 @@ libcheese_la_CFLAGS = \
 	$(CHEESE_CFLAGS)
 
 lib_LTLIBRARIES = libcheese.la
+noinst_LTLIBRARIES = libcheesecommon.la
 
 libcheese_la_CFLAGS = $(CHEESE_CFLAGS)
 
-libcheese_la_SOURCES = \
+libcheesecommon_la_SOURCES = \
+	cheese-gconf.c \
+	cheese-gconf.h \
+	cheese-fileutil.c \
+	cheese-fileutil.h \
 	cheese-camera.c \
+	cheese-camera.h \
+	cheese-flash.h \
+	cheese-flash.c
+
+libcheese_la_SOURCES = \
+	cheese-widget.c \
+	cheese-widget.h \
 	$(NULL)
 
-include_HEADERS = cheese-camera.h
+# FIXME when we have a .pc file, and sonames
+# include_HEADERS = cheese-widget.h
 
 libcheese_la_LIBADD = \
+	libcheesecommon.la \
 	$(CHEESE_LIBS)
+
+noinst_PROGRAMS = cheese-test-widget
+cheese_test_widget_SOURCES = cheese-test-widget.c
+cheese_test_widget_LDADD = $(CHEESE_LIBS) libcheese.la libcheesecommon.la
+
diff --git a/src/cheese-fileutil.c b/libcheese/cheese-fileutil.c
similarity index 100%
rename from src/cheese-fileutil.c
rename to libcheese/cheese-fileutil.c
diff --git a/src/cheese-fileutil.h b/libcheese/cheese-fileutil.h
similarity index 100%
rename from src/cheese-fileutil.h
rename to libcheese/cheese-fileutil.h
diff --git a/src/cheese-flash.c b/libcheese/cheese-flash.c
similarity index 100%
rename from src/cheese-flash.c
rename to libcheese/cheese-flash.c
diff --git a/src/cheese-flash.h b/libcheese/cheese-flash.h
similarity index 100%
rename from src/cheese-flash.h
rename to libcheese/cheese-flash.h
diff --git a/src/cheese-gconf.c b/libcheese/cheese-gconf.c
similarity index 100%
rename from src/cheese-gconf.c
rename to libcheese/cheese-gconf.c
diff --git a/src/cheese-gconf.h b/libcheese/cheese-gconf.h
similarity index 100%
rename from src/cheese-gconf.h
rename to libcheese/cheese-gconf.h
diff --git a/libcheese/cheese-test-widget.c b/libcheese/cheese-test-widget.c
new file mode 100644
index 0000000..69bf468
--- /dev/null
+++ b/libcheese/cheese-test-widget.c
@@ -0,0 +1,48 @@
+
+#include "cheese-config.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gst/gst.h>
+#include "cheese-widget.h"
+
+static gboolean
+delete_callback (GtkWidget *window,
+		 GdkEvent *event,
+		 gpointer data)
+{
+	gtk_widget_destroy (window);
+	gtk_main_quit ();
+	return FALSE;
+}
+
+int main (int argc, char **argv)
+{
+	GtkWidget *window;
+	GtkWidget *camera;
+
+	g_thread_init (NULL);
+	gdk_threads_init ();
+	gst_init (&argc, &argv);
+
+	bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	gtk_init (&argc, &argv);
+
+	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+	gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
+	g_signal_connect (G_OBJECT (window), "delete-event",
+			 G_CALLBACK (delete_callback), NULL);
+
+
+	camera = cheese_widget_new ();
+	gtk_container_add (GTK_CONTAINER (window), camera);
+
+	gtk_widget_show_all (window);
+
+	gtk_main ();
+
+	return 0;
+}
diff --git a/libcheese/cheese-widget.c b/libcheese/cheese-widget.c
new file mode 100644
index 0000000..d6ac015
--- /dev/null
+++ b/libcheese/cheese-widget.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright © 2009 Bastien Nocera <hadess hadess net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cheese-config.h"
+
+#include "cheese-widget.h"
+#include "cheese-gconf.h"
+#include "cheese-camera.h"
+
+enum
+{
+  CHANGED,
+  LAST_SIGNAL
+};
+
+enum
+{
+  PROP_0,
+  PROP_WIDGET
+};
+
+enum {
+	SPINNER_PAGE = 0,
+	WEBCAM_PAGE  = 1,
+	NO_WEBCAM_PAGE = 2,
+	BUG_PAGE = 3
+};
+
+static guint widget_signals[LAST_SIGNAL] = {0};
+
+typedef struct
+{
+  GtkWidget *spinner;
+  GtkWidget *screen;
+  CheeseGConf *gconf;
+  CheeseCamera *webcam;
+} CheeseWidgetPrivate;
+
+#define CHEESE_WIDGET_GET_PRIVATE(o)                     \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHEESE_TYPE_WIDGET, \
+                                CheeseWidgetPrivate))
+
+G_DEFINE_TYPE (CheeseWidget, cheese_widget, GTK_TYPE_NOTEBOOK);
+
+static void
+cheese_widget_init (CheeseWidget *widget)
+{
+  CheeseWidgetPrivate *priv = CHEESE_WIDGET_GET_PRIVATE (widget);
+
+  priv->spinner = gtk_spinner_new ();
+
+  /* XXX
+   * remove this line if you want to debug */
+  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+
+  gtk_notebook_append_page (GTK_NOTEBOOK (widget),
+  			    priv->spinner, gtk_label_new ("spinner"));
+
+  priv->screen = gtk_drawing_area_new ();
+  gtk_notebook_append_page (GTK_NOTEBOOK (widget),
+  			    priv->screen, gtk_label_new ("webcam"));
+
+  gtk_notebook_append_page (GTK_NOTEBOOK (widget),
+			    gtk_label_new ("no webcam"),
+			    gtk_label_new ("no webcam"));
+
+  gtk_notebook_append_page (GTK_NOTEBOOK (widget),
+			    gtk_label_new ("bug!"),
+			    gtk_label_new ("bug!"));
+
+  priv->gconf = cheese_gconf_new ();
+}
+
+static void
+cheese_widget_finalize (GObject *object)
+{
+  CheeseWidgetPrivate *priv = CHEESE_WIDGET_GET_PRIVATE (object);
+
+  if (priv->gconf) {
+  	  g_object_unref (priv->gconf);
+  	  priv->gconf = NULL;
+  }
+  if (priv->webcam) {
+  	  g_object_unref (priv->webcam);
+  	  priv->webcam = NULL;
+  }
+
+  G_OBJECT_CLASS (cheese_widget_parent_class)->finalize (object);
+}
+
+#if 0
+static void
+cheese_widget_set_property (GObject *object, guint prop_id,
+                                  const GValue *value,
+                                  GParamSpec *pspec)
+{
+  CheeseWidgetPrivate *priv = CHEESE_WIDGET_GET_PRIVATE (object);
+
+  g_return_if_fail (CHEESE_IS_WIDGET (object));
+
+  switch (prop_id)
+  {
+    case PROP_WIDGET:
+      priv->widget = GTK_WIDGET (g_value_get_object (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+cheese_widget_get_property (GObject *object, guint prop_id,
+                                  GValue *value, GParamSpec *pspec)
+{
+  CheeseWidgetPrivate *priv = CHEESE_WIDGET_GET_PRIVATE (object);
+
+  g_return_if_fail (CHEESE_IS_WIDGET (object));
+
+  switch (prop_id)
+  {
+    case PROP_WIDGET:
+      g_value_set_object (value, priv->widget);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+#endif
+#if 0
+static void
+cheese_widget_changed (CheeseWidget *self)
+{
+}
+#endif
+
+void
+setup_camera (CheeseWidget *widget)
+{
+  CheeseWidgetPrivate *priv = CHEESE_WIDGET_GET_PRIVATE (widget);
+  char      *webcam_device = NULL;
+  int        x_resolution;
+  int        y_resolution;
+  gdouble    brightness;
+  gdouble    contrast;
+  gdouble    saturation;
+  gdouble    hue;
+  GError    *error = NULL;
+
+  g_object_get (priv->gconf,
+                "gconf_prop_x_resolution", &x_resolution,
+                "gconf_prop_y_resolution", &y_resolution,
+                "gconf_prop_webcam", &webcam_device,
+                "gconf_prop_brightness", &brightness,
+                "gconf_prop_contrast", &contrast,
+                "gconf_prop_saturation", &saturation,
+                "gconf_prop_hue", &hue,
+                NULL);
+
+  gdk_threads_enter ();
+  priv->webcam = cheese_camera_new (priv->screen,
+                                             webcam_device, x_resolution,
+                                             y_resolution);
+  gdk_threads_leave ();
+
+  g_free (webcam_device);
+
+  cheese_camera_setup (priv->webcam, NULL, &error);
+  if (error != NULL)
+  {
+    g_warning ("Error setting up webcam %s", error->message);
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), NO_WEBCAM_PAGE);
+    return;
+  }
+
+  cheese_camera_play (priv->webcam);
+  gdk_threads_enter ();
+  gtk_spinner_stop (GTK_SPINNER (priv->spinner));
+
+  if (cheese_camera_get_num_camera_devices (priv->webcam) == 0)
+	  gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), NO_WEBCAM_PAGE);
+  else
+	  gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), WEBCAM_PAGE);
+
+  gdk_threads_leave ();
+}
+
+static void
+cheese_widget_realize (GtkWidget *widget)
+{
+  GdkWindow *window;
+  CheeseWidgetPrivate *priv = CHEESE_WIDGET_GET_PRIVATE (widget);
+  GError *error = NULL;
+
+  GTK_WIDGET_CLASS (cheese_widget_parent_class)->realize (widget);
+
+  gtk_spinner_start (GTK_SPINNER (priv->spinner));
+
+  gtk_widget_realize (priv->screen);
+  window = gtk_widget_get_window (priv->screen);
+  if (!gdk_window_ensure_native (window))
+  {
+    /* abort: no native window, no xoverlay, no cheese. */
+    g_warning ("Could not create a native X11 window for the drawing area");
+    goto error;
+  }
+
+  gdk_window_set_back_pixmap (gtk_widget_get_window (priv->screen), NULL, FALSE);
+  gtk_widget_set_app_paintable (priv->screen, TRUE);
+  gtk_widget_set_double_buffered (priv->screen, FALSE);
+
+  if (!g_thread_create ((GThreadFunc) setup_camera, widget, FALSE, &error))
+  {
+    g_warning ("Failed to create setup thread: %s\n", error->message);
+    g_error_free (error);
+    goto error;
+  }
+  return;
+
+error:
+  gtk_spinner_stop (GTK_SPINNER (priv->spinner));
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), BUG_PAGE);
+}
+
+static void
+cheese_widget_class_init (CheeseWidgetClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize     = cheese_widget_finalize;
+//  object_class->set_property = cheese_widget_set_property;
+//  object_class->get_property = cheese_widget_get_property;
+
+//  klass->changed     = cheese_widget_changed;
+//  klass->synchronize = NULL;
+
+  widget_class->realize      = cheese_widget_realize;
+
+  g_type_class_add_private (klass, sizeof (CheeseWidgetPrivate));
+}
+
+#if 0
+void
+cheese_widget_synchronize (CheeseWidget *widget)
+{
+  CHEESE_WIDGET_GET_CLASS (widget)->synchronize (widget);
+}
+#endif
+#if 0
+void
+cheese_widget_notify_changed (CheeseWidget *widget)
+{
+  g_signal_emit_by_name (widget, "changed");
+}
+#endif
+
+GtkWidget *
+cheese_widget_new (void)
+{
+	return g_object_new (CHEESE_TYPE_WIDGET, NULL);
+}
+
diff --git a/libcheese/cheese-widget.h b/libcheese/cheese-widget.h
new file mode 100644
index 0000000..0689b7c
--- /dev/null
+++ b/libcheese/cheese-widget.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2009 Bastien Nocera <hadess hadess net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CHEESE_WIDGET_H_
+#define _CHEESE_WIDGET_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define CHEESE_TYPE_WIDGET (cheese_widget_get_type ())
+#define CHEESE_WIDGET(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHEESE_TYPE_WIDGET, \
+                                                                         CheeseWidget))
+#define CHEESE_WIDGET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CHEESE_TYPE_WIDGET, \
+                                                                      CheeseWidgetClass))
+#define CHEESE_IS_WIDGET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHEESE_TYPE_WIDGET))
+#define CHEESE_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CHEESE_TYPE_WIDGET))
+#define CHEESE_WIDGET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), CHEESE_TYPE_WIDGET, \
+                                                                        CheeseWidgetClass))
+
+typedef struct _CheeseWidgetClass CheeseWidgetClass;
+typedef struct _CheeseWidget CheeseWidget;
+
+struct _CheeseWidgetClass
+{
+  GtkNotebookClass parent_class;
+};
+
+struct _CheeseWidget
+{
+  GtkNotebook parent_instance;
+};
+
+GType cheese_widget_get_type (void) G_GNUC_CONST;
+
+GtkWidget *cheese_widget_new (void);
+
+G_END_DECLS
+
+#endif /* _CHEESE_WIDGET_H_ */
diff --git a/src/Makefile.am b/src/Makefile.am
index 23324f1..3c5b2df 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,10 +22,6 @@ cheese_SOURCES = \
 	cheese-dbus.h \
 	cheese-effect-chooser.c \
 	cheese-effect-chooser.h \
-	cheese-fileutil.c \
-	cheese-fileutil.h \
-	cheese-gconf.c \
-	cheese-gconf.h \
 	cheese-thumb-view.c \
 	cheese-thumb-view.h \
 	cheese-window.c \
@@ -46,15 +42,13 @@ cheese_SOURCES = \
 	cheese-prefs-balance-scale.h \
 	cheese-prefs-dialog.c \
 	cheese-prefs-dialog.h \
-	cheese-flash.h \
-	cheese-flash.c \
 	cheese-prefs-camera-combo.c \
 	cheese-prefs-camera-combo.h \
 	cheese-prefs-burst-spinbox.h \
 	cheese-prefs-burst-spinbox.c
 
 cheese_LDADD = \
-	$(top_builddir)/libcheese/libcheese.la \
+	$(top_builddir)/libcheese/libcheesecommon.la \
 	$(CHEESE_LIBS)
 
 #dbus



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]