cheese r672 - in trunk: . data src
- From: dgsiegel svn gnome org
- To: svn-commits-list gnome org
- Subject: cheese r672 - in trunk: . data src
- Date: Mon, 21 Apr 2008 17:37:07 +0100 (BST)
Author: dgsiegel
Date: Mon Apr 21 16:37:06 2008
New Revision: 672
URL: http://svn.gnome.org/viewvc/cheese?rev=672&view=rev
Log:
add a preferences dialog with basic resolution changing, partially fixes #522200, courtesy of James Liggett
Added:
trunk/data/cheese-prefs.glade
trunk/data/cheese-prefs.ui
trunk/src/cheese-prefs-dialog-widgets.c
trunk/src/cheese-prefs-dialog-widgets.h
trunk/src/cheese-prefs-dialog.c
trunk/src/cheese-prefs-dialog.h
trunk/src/cheese-prefs-resolution-combo.c
trunk/src/cheese-prefs-resolution-combo.h
trunk/src/cheese-prefs-widget.c
trunk/src/cheese-prefs-widget.h
Modified:
trunk/AUTHORS
trunk/ChangeLog
trunk/data/Makefile.am
trunk/data/cheese-ui.xml
trunk/data/cheese.schemas.in
trunk/src/Makefile.am
trunk/src/cheese-gconf.c
trunk/src/cheese-gconf.h
trunk/src/cheese-webcam.c
trunk/src/cheese-webcam.h
trunk/src/cheese-window.c
Modified: trunk/AUTHORS
==============================================================================
--- trunk/AUTHORS (original)
+++ trunk/AUTHORS Mon Apr 21 16:37:06 2008
@@ -1,10 +1,11 @@
written by daniel g. siegel <dgsiegel gmail com> and Jaap Haitsma <jaap haitsma org>
the following people contributed to cheese:
- - Cosimo Cecchi <anarki lilik it>
- Baptiste Mille-Mathias <bmm80 free fr>
+ - Cosimo Cecchi <anarki lilik it>
- Diego Escalante Urrelo <dieguito gmail com>
- Gintautas Miliauskas <gintas akl lt>
+ - James Liggett <jrliggett cox net>
- Luca Ferretti <elle uca libero it>
- Mirco "MacSlow" MÃller <macslow bangang de>
- Patryk Zawadzki <patrys pld-linux org>
Modified: trunk/data/Makefile.am
==============================================================================
--- trunk/data/Makefile.am (original)
+++ trunk/data/Makefile.am Mon Apr 21 16:37:06 2008
@@ -13,7 +13,8 @@
pkgdata_DATA = \
cheese.ui \
- cheese-ui.xml
+ cheese-ui.xml \
+ cheese-prefs.ui
EXTRA_DIST = \
$(desktop_in_files) \
Added: trunk/data/cheese-prefs.glade
==============================================================================
--- (empty file)
+++ trunk/data/cheese-prefs.glade Mon Apr 21 16:37:06 2008
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.0 on Sat Apr 12 23:13:46 2008 -->
+<glade-interface>
+ <widget class="GtkDialog" id="cheese_prefs_dialog">
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Preferences</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <widget class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment6">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkComboBox" id="resolution_combo_box">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes"><b>Resolution</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="button1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
Added: trunk/data/cheese-prefs.ui
==============================================================================
--- (empty file)
+++ trunk/data/cheese-prefs.ui Mon Apr 21 16:37:06 2008
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<!--Generated with glade3 3.4.0 on Sat Apr 12 23:13:46 2008 -->
+<interface>
+ <object class="GtkDialog" id="cheese_prefs_dialog">
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Preferences</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <object class="GtkAlignment" id="alignment6">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkComboBox" id="resolution_combo_box">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes"><b>Resolution</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">gtk-close</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">button1</action-widget>
+ </action-widgets>
+ </object>
+</interface>
Modified: trunk/data/cheese-ui.xml
==============================================================================
--- trunk/data/cheese-ui.xml (original)
+++ trunk/data/cheese-ui.xml Mon Apr 21 16:37:06 2008
@@ -1,21 +1,23 @@
<ui>
- <menubar name="MainMenu">
- <menu action="Cheese">
+ <menubar name="MainMenu" name="MainMenu">
+ <menu action="Cheese" name="Cheese">
<menuitem name="CountdownToggle" action="Countdown" />
<separator />
<menuitem action="TakePhoto" />
<menuitem action="TakeVideo" />
<separator />
- <menuitem action="Photo" />
- <menuitem action="Video" />
+ <menuitem action="Photo" name="Photo" />
+ <menuitem action="Video" name="Video" />
<separator />
<menuitem action="Quit" />
</menu>
- <menu action="Edit">
+ <menu action="Edit" name="Edit">
<menuitem action="Effects" />
<separator />
<menuitem action="MoveToTrash" />
<menuitem action="RemoveAll" />
+ <separator />
+ <menuitem action="Preferences" />
</menu>
<menu action="Help">
<menuitem action="HelpContents" />
Modified: trunk/data/cheese.schemas.in
==============================================================================
--- trunk/data/cheese.schemas.in (original)
+++ trunk/data/cheese.schemas.in Mon Apr 21 16:37:06 2008
@@ -10,7 +10,7 @@
<short>Use a countdown</short>
<long>Whether a countdown should be used, when taking a photo</long>
</locale>
- </schema>
+ </schema>
<schema>
<key>/schemas/apps/cheese/webcam</key>
@@ -38,6 +38,30 @@
Shagadelic, Vertigo, Edge, Dice and Warp</long>
</locale>
</schema>
+
+ <schema>
+ <key>/schemas/apps/cheese/x_resolution</key>
+ <applyto>/apps/cheese/x_resolution</applyto>
+ <owner>cheese</owner>
+ <type>int</type>
+ <default>0</default>
+ <locale name="C">
+ <short>X resolution</short>
+ <long>The X resolution of the image captured from the camera</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/cheese/y_resolution</key>
+ <applyto>/apps/cheese/y_resolution</applyto>
+ <owner>cheese</owner>
+ <type>int</type>
+ <default>0</default>
+ <locale name="C">
+ <short>Y resolution</short>
+ <long>The Y resolution of the image captured from the camera</long>
+ </locale>
+ </schema>
</schemalist>
</gconfschemafile>
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Mon Apr 21 16:37:06 2008
@@ -36,7 +36,15 @@
gedit-message-area.c \
gedit-message-area.h \
cheese-no-camera.c \
- cheese-no-camera.h
+ cheese-no-camera.h \
+ cheese-prefs-widget.h \
+ cheese-prefs-widget.c \
+ cheese-prefs-dialog-widgets.h \
+ cheese-prefs-dialog-widgets.c \
+ cheese-prefs-resolution-combo.h \
+ cheese-prefs-resolution-combo.c \
+ cheese-prefs-dialog.c \
+ cheese-prefs-dialog.h
cheese_LDADD = \
$(CHEESE_LIBS)
Modified: trunk/src/cheese-gconf.c
==============================================================================
--- trunk/src/cheese-gconf.c (original)
+++ trunk/src/cheese-gconf.c Mon Apr 21 16:37:06 2008
@@ -86,6 +86,16 @@
g_slist_free (list);
g_slist_free (tmp);
break;
+ case GCONF_PROP_X_RESOLUTION:
+ g_value_set_int (value, gconf_client_get_int (priv->client,
+ CHEESE_GCONF_PREFIX "/x_resolution",
+ NULL));
+ break;
+ case GCONF_PROP_Y_RESOLUTION:
+ g_value_set_int (value, gconf_client_get_int (priv->client,
+ CHEESE_GCONF_PREFIX "/y_resolution",
+ NULL));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -139,6 +149,18 @@
g_slist_free (list);
g_strfreev (effects);
break;
+ case GCONF_PROP_X_RESOLUTION:
+ gconf_client_set_int (priv->client,
+ CHEESE_GCONF_PREFIX "/x_resolution",
+ g_value_get_int (value),
+ NULL);
+ break;
+ case GCONF_PROP_Y_RESOLUTION:
+ gconf_client_set_int (priv->client,
+ CHEESE_GCONF_PREFIX "/y_resolution",
+ g_value_get_int (value),
+ NULL);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -183,8 +205,26 @@
NULL,
NULL,
"",
- G_PARAM_READWRITE));
-
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, GCONF_PROP_X_RESOLUTION,
+ g_param_spec_int ("gconf_prop_x_resolution",
+ NULL,
+ NULL,
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, GCONF_PROP_Y_RESOLUTION,
+ g_param_spec_int ("gconf_prop_y_resolution",
+ NULL,
+ NULL,
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
g_type_class_add_private (klass, sizeof (CheeseGConfPrivate));
}
Modified: trunk/src/cheese-gconf.h
==============================================================================
--- trunk/src/cheese-gconf.h (original)
+++ trunk/src/cheese-gconf.h Mon Apr 21 16:37:06 2008
@@ -44,7 +44,9 @@
GCONF_PROP_0,
GCONF_PROP_COUNTDOWN,
GCONF_PROP_WEBCAM,
- GCONF_PROP_SELECTED_EFFECTS
+ GCONF_PROP_SELECTED_EFFECTS,
+ GCONF_PROP_X_RESOLUTION,
+ GCONF_PROP_Y_RESOLUTION
};
GType cheese_gconf_get_type(void);
Added: trunk/src/cheese-prefs-dialog-widgets.c
==============================================================================
--- (empty file)
+++ trunk/src/cheese-prefs-dialog-widgets.c Mon Apr 21 16:37:06 2008
@@ -0,0 +1,115 @@
+/* -*- Mode: C; indent-tabs-mode: s; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright (C) 2008 James Liggett <jrliggett cox 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-prefs-dialog-widgets.h"
+
+typedef struct
+{
+ GList *widgets;
+ CheeseGConf *gconf;
+} CheesePrefsDialogWidgetsPrivate;
+
+#define CHEESE_PREFS_DIALOG_WIDGETS_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHEESE_TYPE_PREFS_DIALOG_WIDGETS, \
+ CheesePrefsDialogWidgetsPrivate))
+
+G_DEFINE_TYPE (CheesePrefsDialogWidgets, cheese_prefs_dialog_widgets, G_TYPE_OBJECT);
+
+static void
+cheese_prefs_dialog_widgets_init (CheesePrefsDialogWidgets *self)
+{
+ CheesePrefsDialogWidgetsPrivate *priv = CHEESE_PREFS_DIALOG_WIDGETS_GET_PRIVATE (self);
+
+ priv->widgets = NULL;
+ priv->gconf = NULL;
+}
+
+static void
+cheese_prefs_dialog_widgets_finalize (GObject *object)
+{
+ CheesePrefsDialogWidgetsPrivate *priv = CHEESE_PREFS_DIALOG_WIDGETS_GET_PRIVATE (object);
+ GList *current_widget;
+
+ current_widget = priv->widgets;
+
+ while (current_widget)
+ {
+ g_object_unref (current_widget->data);
+ current_widget = g_list_next (current_widget);
+ }
+
+ g_list_free (priv->widgets);
+
+ G_OBJECT_CLASS (cheese_prefs_dialog_widgets_parent_class)->finalize (object);
+}
+
+static void
+cheese_prefs_dialog_widgets_class_init (CheesePrefsDialogWidgetsClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (CheesePrefsDialogWidgetsPrivate));
+
+ object_class->finalize = cheese_prefs_dialog_widgets_finalize;
+}
+
+
+CheesePrefsDialogWidgets *
+cheese_prefs_dialog_widgets_new (CheeseGConf *gconf)
+{
+ CheesePrefsDialogWidgets *self;
+ CheesePrefsDialogWidgetsPrivate *priv;
+
+ self = g_object_new (CHEESE_TYPE_PREFS_DIALOG_WIDGETS, NULL);
+
+ priv = CHEESE_PREFS_DIALOG_WIDGETS_GET_PRIVATE (self);
+ priv->gconf = gconf;
+
+ return self;
+}
+
+void
+cheese_prefs_dialog_widgets_add (CheesePrefsDialogWidgets *prefs_widgets,
+ CheesePrefsWidget *widget)
+{
+ CheesePrefsDialogWidgetsPrivate *priv = CHEESE_PREFS_DIALOG_WIDGETS_GET_PRIVATE (prefs_widgets);
+
+ if (!g_list_find (priv->widgets, widget))
+ {
+ priv->widgets = g_list_append (priv->widgets, widget);
+ widget->gconf = priv->gconf;
+ }
+}
+
+void
+cheese_prefs_dialog_widgets_synchronize (CheesePrefsDialogWidgets *prefs_widgets)
+{
+ CheesePrefsDialogWidgetsPrivate *priv = CHEESE_PREFS_DIALOG_WIDGETS_GET_PRIVATE (prefs_widgets);
+
+ GList *current_widget;
+
+ current_widget = priv->widgets;
+
+ while (current_widget)
+ {
+ cheese_prefs_widget_synchronize (CHEESE_PREFS_WIDGET (current_widget->data));
+ current_widget = g_list_next (current_widget);
+ }
+}
Added: trunk/src/cheese-prefs-dialog-widgets.h
==============================================================================
--- (empty file)
+++ trunk/src/cheese-prefs-dialog-widgets.h Mon Apr 21 16:37:06 2008
@@ -0,0 +1,57 @@
+/* -*- Mode: C; indent-tabs-mode: s; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright (C) 2008 James Liggett <jrliggett cox 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_PREFS_DIALOG_WIDGETS_H_
+#define _CHEESE_PREFS_DIALOG_WIDGETS_H_
+
+#include <glib-object.h>
+#include "cheese-prefs-widget.h"
+
+G_BEGIN_DECLS
+
+#define CHEESE_TYPE_PREFS_DIALOG_WIDGETS (cheese_prefs_dialog_widgets_get_type ())
+#define CHEESE_PREFS_DIALOG_WIDGETS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHEESE_TYPE_PREFS_DIALOG_WIDGETS, CheesePrefsDialogWidgets))
+#define CHEESE_PREFS_DIALOG_WIDGETS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CHEESE_TYPE_PREFS_DIALOG_WIDGETS, CheesePrefsDialogWidgetsClass))
+#define CHEESE_IS_PREFS_DIALOG_WIDGETS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHEESE_TYPE_PREFS_DIALOG_WIDGETS))
+#define CHEESE_IS_PREFS_DIALOG_WIDGETS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CHEESE_TYPE_PREFS_DIALOG_WIDGETS))
+#define CHEESE_PREFS_DIALOG_WIDGETS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CHEESE_TYPE_PREFS_DIALOG_WIDGETS, CheesePrefsDialogWidgetsClass))
+
+typedef struct _CheesePrefsDialogWidgetsClass CheesePrefsDialogWidgetsClass;
+typedef struct _CheesePrefsDialogWidgets CheesePrefsDialogWidgets;
+
+struct _CheesePrefsDialogWidgetsClass
+{
+ GObjectClass parent_class;
+};
+
+struct _CheesePrefsDialogWidgets
+{
+ GObject parent_instance;
+};
+
+GType cheese_prefs_dialog_widgets_get_type (void) G_GNUC_CONST;
+CheesePrefsDialogWidgets *cheese_prefs_dialog_widgets_new (CheeseGConf *gconf);
+void cheese_prefs_dialog_widgets_add (CheesePrefsDialogWidgets *prefs_widgets,
+ CheesePrefsWidget *widget);
+void cheese_prefs_dialog_widgets_synchronize (CheesePrefsDialogWidgets *prefs_widgets);
+
+G_END_DECLS
+
+#endif /* _CHEESE_PREFS_DIALOG_WIDGETS_H_ */
Added: trunk/src/cheese-prefs-dialog.c
==============================================================================
--- (empty file)
+++ trunk/src/cheese-prefs-dialog.c Mon Apr 21 16:37:06 2008
@@ -0,0 +1,122 @@
+/* -*- Mode: C; indent-tabs-mode: s; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright (C) 2008 James Liggett <jrliggett cox 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-prefs-dialog.h"
+
+typedef struct
+{
+ GtkWidget *cheese_prefs_dialog;
+ GtkWidget *resolution_combo_box;
+
+ GtkWidget *parent;
+ CheeseWebcam *webcam;
+
+ CheesePrefsDialogWidgets *widgets;
+} CheesePrefsDialog;
+
+static void
+cheese_prefs_dialog_create_dialog (CheesePrefsDialog *prefs_dialog)
+{
+ GtkBuilder *builder;
+ GError *error;
+
+ error = NULL;
+ builder = gtk_builder_new ();
+ gtk_builder_add_from_file (builder, PACKAGE_DATADIR"/cheese-prefs.ui", &error);
+
+ if (error)
+ {
+ g_error ("building ui from %s failed: %s", PACKAGE_DATADIR"/cheese-prefs.ui", error->message);
+ g_clear_error (&error);
+ }
+
+ prefs_dialog->cheese_prefs_dialog = GTK_WIDGET (gtk_builder_get_object (builder,
+ "cheese_prefs_dialog"));
+ prefs_dialog->resolution_combo_box = GTK_WIDGET (gtk_builder_get_object (builder,
+ "resolution_combo_box"));
+
+ gtk_window_set_transient_for (GTK_WINDOW (prefs_dialog->cheese_prefs_dialog),
+ GTK_WINDOW (prefs_dialog->parent));
+}
+
+static void
+on_resolution_changed (CheesePrefsWidget *widget, gpointer user_data)
+{
+ CheeseWebcam *webcam;
+ CheeseVideoFormat *current_format;
+ CheeseVideoFormat *new_format;
+
+ g_object_get (widget, "webcam", &webcam, NULL);
+
+ current_format = cheese_webcam_get_current_video_format (webcam);
+ new_format = cheese_prefs_resolution_combo_get_selected_format (CHEESE_PREFS_RESOLUTION_COMBO (widget));
+
+ if (new_format != current_format)
+ cheese_webcam_set_video_format (webcam, new_format);
+}
+
+static void
+cheese_prefs_dialog_setup_widgets (CheesePrefsDialog *prefs_dialog)
+{
+ CheesePrefsWidget *widget;
+
+ widget = CHEESE_PREFS_WIDGET (cheese_prefs_resolution_combo_new (prefs_dialog->resolution_combo_box,
+ prefs_dialog->webcam,
+ "gconf_prop_x_resolution",
+ "gconf_prop_y_resolution",
+ 0, 0));
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (on_resolution_changed),
+ NULL);
+
+ cheese_prefs_dialog_widgets_add (prefs_dialog->widgets, widget);
+
+ cheese_prefs_dialog_widgets_synchronize (prefs_dialog->widgets);
+}
+
+static void
+cheese_prefs_dialog_destroy_dialog (CheesePrefsDialog *prefs_dialog)
+{
+ gtk_widget_destroy (prefs_dialog->cheese_prefs_dialog);
+
+ g_object_unref (prefs_dialog->widgets);
+
+ g_free (prefs_dialog);
+}
+
+void
+cheese_prefs_dialog_run (GtkWidget *parent, CheeseGConf *gconf,
+ CheeseWebcam *webcam)
+{
+ CheesePrefsDialog *prefs_dialog;
+
+ prefs_dialog = g_new0 (CheesePrefsDialog, 1);
+
+ prefs_dialog->parent = parent;
+ prefs_dialog->webcam = webcam;
+ prefs_dialog->widgets = cheese_prefs_dialog_widgets_new (gconf);
+
+ cheese_prefs_dialog_create_dialog (prefs_dialog);
+ cheese_prefs_dialog_setup_widgets (prefs_dialog);
+
+ gtk_dialog_run (GTK_DIALOG (prefs_dialog->cheese_prefs_dialog));
+
+ cheese_prefs_dialog_destroy_dialog (prefs_dialog);
+}
Added: trunk/src/cheese-prefs-dialog.h
==============================================================================
--- (empty file)
+++ trunk/src/cheese-prefs-dialog.h Mon Apr 21 16:37:06 2008
@@ -0,0 +1,35 @@
+/* -*- Mode: C; indent-tabs-mode: s; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright (C) 2008 James Liggett <jrliggett cox 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_PREFS_DIALOG_H_
+#define _CHEESE_PREFS_DIALOG_H_
+
+#ifdef HAVE_CONFIG_H
+#include "cheese-config.h"
+#endif
+
+#include "cheese-webcam.h"
+#include "cheese-prefs-dialog-widgets.h"
+#include "cheese-prefs-resolution-combo.h"
+
+void cheese_prefs_dialog_run (GtkWidget *parent, CheeseGConf *gconf,
+ CheeseWebcam *webcam);
+
+#endif /* _CHEESE_PREFS_DIALOG_H_ */
Added: trunk/src/cheese-prefs-resolution-combo.c
==============================================================================
--- (empty file)
+++ trunk/src/cheese-prefs-resolution-combo.c Mon Apr 21 16:37:06 2008
@@ -0,0 +1,358 @@
+/* -*- Mode: C; indent-tabs-mode: s; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright (C) 2008 James Liggett <jrliggett cox 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-prefs-resolution-combo.h"
+
+typedef struct
+{
+ gchar *x_resolution_key;
+ gchar *y_resolution_key;
+ unsigned int max_x_resolution;
+ unsigned int max_y_resolution;
+ GtkListStore *list_store;
+ CheeseWebcam *webcam;
+ CheeseVideoFormat *selected_format;
+ gboolean has_been_synchronized; /* Make sure we don't synchronize if client
+ * sets webcam on construction. */
+} CheesePrefsResolutionComboPrivate;
+
+#define CHEESE_PREFS_RESOLUTION_COMBO_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHEESE_TYPE_PREFS_RESOLUTION_COMBO, \
+ CheesePrefsResolutionComboPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_X_RESOLUTION_KEY,
+ PROP_Y_RESOLUTION_KEY,
+ PROP_MAX_X_RESOLUTION,
+ PROP_MAX_Y_RESOLUTION,
+ PROP_WEBCAM
+};
+
+enum
+{
+ COL_NAME,
+ COL_FORMAT,
+ NUM_COLS
+};
+
+G_DEFINE_TYPE (CheesePrefsResolutionCombo, cheese_prefs_resolution_combo, CHEESE_TYPE_PREFS_WIDGET);
+
+static void
+cheese_prefs_resolution_combo_init (CheesePrefsResolutionCombo *self)
+{
+ CheesePrefsResolutionComboPrivate *priv = CHEESE_PREFS_RESOLUTION_COMBO_GET_PRIVATE (self);
+
+ priv->x_resolution_key = NULL;
+ priv->y_resolution_key = NULL;
+ priv->max_x_resolution = G_MAXUINT;
+ priv->max_y_resolution = G_MAXUINT;
+ priv->list_store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_POINTER);
+ priv->webcam = NULL;
+ priv->selected_format = NULL;
+ priv->has_been_synchronized = FALSE;
+}
+
+static void
+cheese_prefs_resolution_combo_finalize (GObject *object)
+{
+ CheesePrefsResolutionCombo *self = CHEESE_PREFS_RESOLUTION_COMBO (object);
+ CheesePrefsResolutionComboPrivate *priv = CHEESE_PREFS_RESOLUTION_COMBO_GET_PRIVATE (self);
+
+ g_free (priv->x_resolution_key);
+ g_free (priv->y_resolution_key);
+ g_object_unref (priv->list_store);
+
+ G_OBJECT_CLASS (cheese_prefs_resolution_combo_parent_class)->finalize (object);
+}
+
+static void
+combo_selection_changed (GtkComboBox *combo_box,
+ CheesePrefsResolutionCombo *self)
+{
+ CheesePrefsResolutionComboPrivate *priv = CHEESE_PREFS_RESOLUTION_COMBO_GET_PRIVATE (self);
+ GtkTreeIter iter;
+ CheeseVideoFormat *format;
+
+ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), &iter);
+ gtk_tree_model_get (GTK_TREE_MODEL (priv->list_store), &iter, COL_FORMAT,
+ &format, -1);
+
+ g_object_set (CHEESE_PREFS_WIDGET (self)->gconf, priv->x_resolution_key,
+ format->width, priv->y_resolution_key, format->height, NULL);
+
+ priv->selected_format = format;
+
+ cheese_prefs_widget_notify_changed (CHEESE_PREFS_WIDGET (self));
+}
+
+static void
+cheese_prefs_resolution_combo_synchronize (CheesePrefsWidget *prefs_widget)
+{
+ CheesePrefsResolutionCombo *self = CHEESE_PREFS_RESOLUTION_COMBO (prefs_widget);
+ CheesePrefsResolutionComboPrivate *priv = CHEESE_PREFS_RESOLUTION_COMBO_GET_PRIVATE (self);
+ GtkWidget *combo_box;
+ CheeseVideoFormat *current_format;
+ GArray *formats;
+ int i;
+ CheeseVideoFormat *format;
+ gchar *format_name;
+ GtkTreeIter iter;
+ GtkTreeIter active_iter;
+ gboolean found_resolution;
+
+ priv->has_been_synchronized = TRUE;
+ found_resolution = FALSE;
+
+ /* Don't generate spurious changed events when we set the active resolution */
+ g_object_get (prefs_widget, "widget", &combo_box, NULL);
+ g_signal_handlers_disconnect_by_func (combo_box, combo_selection_changed,
+ prefs_widget);
+
+ g_object_ref (priv->list_store);
+ gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), NULL);
+
+ gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), NULL);
+ current_format = cheese_webcam_get_current_video_format (priv->webcam);
+
+ gtk_list_store_clear (priv->list_store);
+ formats = cheese_webcam_get_video_formats (priv->webcam);
+
+ for (i = 0; i < formats->len; i++)
+ {
+ format = &g_array_index (formats, CheeseVideoFormat, i);
+ format_name = g_strdup_printf ("%i x %i", format->width, format->height);
+
+
+ if (format->width <= priv->max_x_resolution &&
+ format->height <= priv->max_y_resolution)
+ {
+ gtk_list_store_append (priv->list_store, &iter);
+ gtk_list_store_set (priv->list_store, &iter,
+ COL_NAME, format_name,
+ COL_FORMAT, format,
+ -1);
+
+ g_free (format_name);
+
+ if (format == current_format)
+ {
+ active_iter = iter;
+ found_resolution = TRUE;
+ }
+
+ }
+ }
+
+ gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box),
+ GTK_TREE_MODEL (priv->list_store));
+ g_object_unref (priv->list_store);
+
+ if (found_resolution)
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &active_iter);
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
+
+ g_signal_connect (G_OBJECT (combo_box), "changed",
+ G_CALLBACK (combo_selection_changed),
+ self);
+
+}
+
+static void
+cheese_prefs_resolution_combo_set_property (GObject *object, guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CheesePrefsResolutionComboPrivate *priv = CHEESE_PREFS_RESOLUTION_COMBO_GET_PRIVATE (object);
+
+ g_return_if_fail (CHEESE_IS_PREFS_RESOLUTION_COMBO (object));
+
+ switch (prop_id)
+ {
+ case PROP_X_RESOLUTION_KEY:
+ priv->x_resolution_key = g_value_dup_string (value);
+ break;
+ case PROP_Y_RESOLUTION_KEY:
+ priv->y_resolution_key = g_value_dup_string (value);
+ break;
+ case PROP_MAX_X_RESOLUTION:
+ priv->max_x_resolution = g_value_get_uint (value);
+ break;
+ case PROP_MAX_Y_RESOLUTION:
+ priv->max_y_resolution = g_value_get_uint (value);
+ break;
+ case PROP_WEBCAM:
+ priv->webcam = CHEESE_WEBCAM (g_value_get_object (value));
+
+ /* If the webcam changes the resolutions change too. But only change the
+ * data if we've been synchronized once already. If this property is set
+ * on construction, we would synchronize twice--once when the property is
+ * set, and again when the dialog syncs when it's created. */
+ if (priv->has_been_synchronized)
+ cheese_prefs_resolution_combo_synchronize (CHEESE_PREFS_WIDGET (object));
+
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+cheese_prefs_resolution_combo_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ CheesePrefsResolutionComboPrivate *priv = CHEESE_PREFS_RESOLUTION_COMBO_GET_PRIVATE (object);
+
+ g_return_if_fail (CHEESE_IS_PREFS_RESOLUTION_COMBO (object));
+
+ switch (prop_id)
+ {
+ case PROP_X_RESOLUTION_KEY:
+ g_value_set_string (value, priv->x_resolution_key);
+ break;
+ case PROP_Y_RESOLUTION_KEY:
+ g_value_set_string (value, priv->y_resolution_key);
+ break;
+ case PROP_MAX_X_RESOLUTION:
+ g_value_set_uint (value, priv->max_x_resolution);
+ break;
+ case PROP_MAX_Y_RESOLUTION:
+ g_value_set_uint (value, priv->max_y_resolution);
+ break;
+ case PROP_WEBCAM:
+ g_value_set_object (value, priv->webcam);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+cheese_prefs_resolution_combo_class_init (CheesePrefsResolutionComboClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+ CheesePrefsWidgetClass* parent_class = CHEESE_PREFS_WIDGET_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (CheesePrefsResolutionComboPrivate));
+
+ object_class->finalize = cheese_prefs_resolution_combo_finalize;
+ object_class->set_property = cheese_prefs_resolution_combo_set_property;
+ object_class->get_property = cheese_prefs_resolution_combo_get_property;
+ parent_class->synchronize = cheese_prefs_resolution_combo_synchronize;
+
+ g_object_class_install_property (object_class,
+ PROP_X_RESOLUTION_KEY,
+ g_param_spec_string ("x_resolution_key",
+ "",
+ "GConf key for X resolution",
+ "",
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
+ PROP_Y_RESOLUTION_KEY,
+ g_param_spec_string ("y_resolution_key",
+ "",
+ "GConf key for Y resolution",
+ "",
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
+ PROP_MAX_X_RESOLUTION,
+ g_param_spec_uint ("max_x_resolution",
+ "",
+ "Maximum supported X resolution",
+ 0,
+ G_MAXUINT,
+ G_MAXUINT,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_MAX_Y_RESOLUTION,
+ g_param_spec_uint ("max_y_resolution",
+ "",
+ "Maximum supported Y resolution",
+ 0,
+ G_MAXUINT,
+ G_MAXUINT,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_WEBCAM,
+ g_param_spec_object ("webcam",
+ "",
+ "Webcam object",
+ CHEESE_TYPE_WEBCAM,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+}
+
+CheesePrefsResolutionCombo *
+cheese_prefs_resolution_combo_new (GtkWidget *combo_box, CheeseWebcam *webcam,
+ const gchar *x_resolution_key,
+ const gchar *y_resolution_key,
+ unsigned int max_x_resolution,
+ unsigned int max_y_resolution)
+{
+ CheesePrefsResolutionCombo *self;
+ GtkCellRenderer *renderer;
+ CheesePrefsResolutionComboPrivate *priv;
+
+ self = g_object_new (CHEESE_TYPE_PREFS_RESOLUTION_COMBO,
+ "widget", combo_box,
+ "webcam", webcam,
+ "x_resolution_key", x_resolution_key,
+ "y_resolution_key", y_resolution_key,
+ NULL);
+
+ if (max_x_resolution > 0 &&
+ max_y_resolution > 0)
+ {
+ g_object_set (self,
+ "max_x_resolution", max_x_resolution,
+ "max_y_resolution", max_y_resolution,
+ NULL);
+ }
+
+ priv = CHEESE_PREFS_RESOLUTION_COMBO_GET_PRIVATE (self);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, FALSE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo_box), renderer, "text",
+ COL_NAME);
+ gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box),
+ GTK_TREE_MODEL (priv->list_store));
+
+ return self;
+
+}
+
+CheeseVideoFormat *
+cheese_prefs_resolution_combo_get_selected_format (CheesePrefsResolutionCombo *resolution_combo)
+{
+ CheesePrefsResolutionComboPrivate *priv = CHEESE_PREFS_RESOLUTION_COMBO_GET_PRIVATE (resolution_combo);
+
+ return priv->selected_format;
+}
+
+
Added: trunk/src/cheese-prefs-resolution-combo.h
==============================================================================
--- (empty file)
+++ trunk/src/cheese-prefs-resolution-combo.h Mon Apr 21 16:37:06 2008
@@ -0,0 +1,62 @@
+/* -*- Mode: C; indent-tabs-mode: s; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright (C) 2008 James Liggett <jrliggett cox 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_PREFS_RESOLUTION_COMBO_H_
+#define _CHEESE_PREFS_RESOLUTION_COMBO_H_
+
+#include <glib-object.h>
+#include "cheese-prefs-widget.h"
+#include "cheese-webcam.h"
+
+G_BEGIN_DECLS
+
+#define CHEESE_TYPE_PREFS_RESOLUTION_COMBO (cheese_prefs_resolution_combo_get_type ())
+#define CHEESE_PREFS_RESOLUTION_COMBO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHEESE_TYPE_PREFS_RESOLUTION_COMBO, CheesePrefsResolutionCombo))
+#define CHEESE_PREFS_RESOLUTION_COMBO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CHEESE_TYPE_PREFS_RESOLUTION_COMBO, CheesePrefsResolutionComboClass))
+#define CHEESE_IS_PREFS_RESOLUTION_COMBO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHEESE_TYPE_PREFS_RESOLUTION_COMBO))
+#define CHEESE_IS_PREFS_RESOLUTION_COMBO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CHEESE_TYPE_PREFS_RESOLUTION_COMBO))
+#define CHEESE_PREFS_RESOLUTION_COMBO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CHEESE_TYPE_PREFS_RESOLUTION_COMBO, CheesePrefsResolutionComboClass))
+
+typedef struct _CheesePrefsResolutionComboClass CheesePrefsResolutionComboClass;
+typedef struct _CheesePrefsResolutionCombo CheesePrefsResolutionCombo;
+
+struct _CheesePrefsResolutionComboClass
+{
+ CheesePrefsWidgetClass parent_class;
+};
+
+struct _CheesePrefsResolutionCombo
+{
+ CheesePrefsWidget parent_instance;
+};
+
+GType cheese_prefs_resolution_combo_get_type (void) G_GNUC_CONST;
+
+CheesePrefsResolutionCombo *cheese_prefs_resolution_combo_new (GtkWidget *combo_box,
+ CheeseWebcam *webcam,
+ const gchar *x_resolution_key,
+ const gchar *y_resolution_key,
+ unsigned int max_x_resolution,
+ unsigned int max_y_resolution);
+CheeseVideoFormat *cheese_prefs_resolution_combo_get_selected_format (CheesePrefsResolutionCombo *resolution_combo);
+
+G_END_DECLS
+
+#endif /* _CHEESE_PREFS_RESOLUTION_COMBO_H_ */
Added: trunk/src/cheese-prefs-widget.c
==============================================================================
--- (empty file)
+++ trunk/src/cheese-prefs-widget.c Mon Apr 21 16:37:06 2008
@@ -0,0 +1,153 @@
+/* -*- Mode: C; indent-tabs-mode: s; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright (C) 2008 James Liggett <jrliggett cox 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-prefs-widget.h"
+
+enum
+{
+ CHANGED,
+
+ LAST_SIGNAL
+};
+
+enum
+{
+ PROP_0,
+
+ PROP_WIDGET
+};
+
+
+static guint prefs_widget_signals[LAST_SIGNAL] = { 0 };
+
+typedef struct
+{
+ GtkWidget *widget;
+} CheesePrefsWidgetPrivate;
+
+#define CHEESE_PREFS_WIDGET_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHEESE_TYPE_PREFS_WIDGET, \
+ CheesePrefsWidgetPrivate))
+
+G_DEFINE_TYPE (CheesePrefsWidget, cheese_prefs_widget, G_TYPE_OBJECT);
+
+static void
+cheese_prefs_widget_init (CheesePrefsWidget *prefs_widget)
+{
+ CheesePrefsWidgetPrivate *priv = CHEESE_PREFS_WIDGET_GET_PRIVATE (prefs_widget);
+
+ prefs_widget->gconf = NULL;
+ priv->widget = NULL;
+}
+
+static void
+cheese_prefs_widget_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (cheese_prefs_widget_parent_class)->finalize (object);
+}
+
+static void
+cheese_prefs_widget_set_property (GObject *object, guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ CheesePrefsWidgetPrivate *priv = CHEESE_PREFS_WIDGET_GET_PRIVATE (object);
+
+ g_return_if_fail (CHEESE_IS_PREFS_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_prefs_widget_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ CheesePrefsWidgetPrivate *priv = CHEESE_PREFS_WIDGET_GET_PRIVATE (object);
+
+ g_return_if_fail (CHEESE_IS_PREFS_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;
+ }
+}
+
+static void
+cheese_prefs_widget_changed (CheesePrefsWidget *self)
+{
+
+}
+
+static void
+cheese_prefs_widget_class_init (CheesePrefsWidgetClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = cheese_prefs_widget_finalize;
+ object_class->set_property = cheese_prefs_widget_set_property;
+ object_class->get_property = cheese_prefs_widget_get_property;
+
+ klass->changed = cheese_prefs_widget_changed;
+ klass->synchronize = NULL;
+
+ g_type_class_add_private (klass, sizeof (CheesePrefsWidgetPrivate));
+
+ prefs_widget_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ 0,
+ G_STRUCT_OFFSET (CheesePrefsWidgetClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_object_class_install_property (object_class, PROP_WIDGET,
+ g_param_spec_object ("widget",
+ "",
+ "The widget that this object wraps",
+ GTK_TYPE_WIDGET,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+
+void
+cheese_prefs_widget_synchronize (CheesePrefsWidget *prefs_widget)
+{
+ CHEESE_PREFS_WIDGET_GET_CLASS (prefs_widget)->synchronize (prefs_widget);
+}
+
+void
+cheese_prefs_widget_notify_changed (CheesePrefsWidget *prefs_widget)
+{
+ g_signal_emit_by_name (prefs_widget, "changed");
+}
Added: trunk/src/cheese-prefs-widget.h
==============================================================================
--- (empty file)
+++ trunk/src/cheese-prefs-widget.h Mon Apr 21 16:37:06 2008
@@ -0,0 +1,64 @@
+/* -*- Mode: C; indent-tabs-mode: s; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * Copyright (C) 2008 James Liggett <jrliggett cox 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_PREFS_WIDGET_H_
+#define _CHEESE_PREFS_WIDGET_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "cheese-gconf.h"
+
+G_BEGIN_DECLS
+
+#define CHEESE_TYPE_PREFS_WIDGET (cheese_prefs_widget_get_type ())
+#define CHEESE_PREFS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHEESE_TYPE_PREFS_WIDGET, CheesePrefsWidget))
+#define CHEESE_PREFS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CHEESE_TYPE_PREFS_WIDGET, CheesePrefsWidgetClass))
+#define CHEESE_IS_PREFS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHEESE_TYPE_PREFS_WIDGET))
+#define CHEESE_IS_PREFS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CHEESE_TYPE_PREFS_WIDGET))
+#define CHEESE_PREFS_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CHEESE_TYPE_PREFS_WIDGET, CheesePrefsWidgetClass))
+
+typedef struct _CheesePrefsWidgetClass CheesePrefsWidgetClass;
+typedef struct _CheesePrefsWidget CheesePrefsWidget;
+
+struct _CheesePrefsWidgetClass
+{
+ GObjectClass parent_class;
+
+ /* Signals */
+ void (*changed) (CheesePrefsWidget *self);
+
+ /* Virtual methods */
+ void (*synchronize) (CheesePrefsWidget *self);
+};
+
+struct _CheesePrefsWidget
+{
+ GObject parent_instance;
+
+ CheeseGConf *gconf;
+};
+
+GType cheese_prefs_widget_get_type (void) G_GNUC_CONST;
+void cheese_prefs_widget_synchronize (CheesePrefsWidget *prefs_widget);
+void cheese_prefs_widget_notify_changed (CheesePrefsWidget *prefs_widget);
+
+G_END_DECLS
+
+#endif /* _CHEESE_PREFS_WIDGET_H_ */
Modified: trunk/src/cheese-webcam.c
==============================================================================
--- trunk/src/cheese-webcam.c (original)
+++ trunk/src/cheese-webcam.c Mon Apr 21 16:37:06 2008
@@ -39,21 +39,6 @@
#define CHEESE_WEBCAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHEESE_TYPE_WEBCAM, CheeseWebcamPrivate))
-typedef struct
-{
- int numerator;
- int denominator;
-} CheeseFramerate;
-
-typedef struct
-{
- char *mimetype;
- int width;
- int height;
- int num_framerates;
- CheeseFramerate *framerates;
-} CheeseVideoFormat;
-
typedef struct
{
char *video_device;
@@ -78,6 +63,7 @@
GstElement *video_save_bin;
GstElement *video_source;
+ GstElement *capsfilter;
GstElement *video_file_sink;
GstElement *photo_sink;
GstElement *audio_source;
@@ -98,13 +84,20 @@
int num_webcam_devices;
char *device_name;
CheeseWebcamDevice *webcam_devices;
+ int x_resolution;
+ int y_resolution;
+ int selected_device;
+ CheeseVideoFormat *current_format;
+ GHashTable *supported_resolutions;
} CheeseWebcamPrivate;
enum
{
PROP_0,
PROP_VIDEO_WINDOW,
- PROP_DEVICE_NAME
+ PROP_DEVICE_NAME,
+ PROP_X_RESOLUTION,
+ PROP_Y_RESOLUTION
};
enum
@@ -240,6 +233,10 @@
CheeseWebcamPrivate* priv = CHEESE_WEBCAM_GET_PRIVATE (webcam);
int i;
int num_udis;
+ int num_devices; /* Devices we actually create formats for; can either be the
+ * number of webcams detected, or 1 if none were. The one
+ * refers to a fake device so that resolution changing still
+ * works even if the computer doesn't have a webcam. */
char **udis;
DBusError error;
LibHalContext *hal_ctx;
@@ -283,9 +280,19 @@
}
/* Initialize webcam structures */
- priv->num_webcam_devices = num_udis;
- priv->webcam_devices = g_new0 (CheeseWebcamDevice, priv->num_webcam_devices);
- for (i = 0; i < priv->num_webcam_devices; i++)
+
+ if (num_udis > 0)
+ priv->num_webcam_devices = num_devices = num_udis;
+ else
+ {
+ num_devices = 1;
+ priv->num_webcam_devices = num_udis; /* We don't have any real cameras--
+ * this is important when we create
+ * the pipeline. */
+ }
+
+ priv->webcam_devices = g_new0 (CheeseWebcamDevice, num_devices);
+ for (i = 0; i < num_devices; i++)
{
priv->webcam_devices[i].num_video_formats = 0;
priv->webcam_devices[i].video_formats = g_array_new (FALSE, FALSE, sizeof (CheeseVideoFormat));
@@ -456,8 +463,10 @@
}
static void
-cheese_webcam_get_webcam_device_data (CheeseWebcamDevice *webcam_device)
+cheese_webcam_get_webcam_device_data (CheeseWebcam *webcam,
+ CheeseWebcamDevice *webcam_device)
{
+ CheeseWebcamPrivate* priv = CHEESE_WEBCAM_GET_PRIVATE (webcam);
char *pipeline_desc;
GstElement *pipeline;
GError *err;
@@ -532,6 +541,12 @@
CheeseVideoFormat video_format;
video_format = g_array_index (webcam_device->video_formats, CheeseVideoFormat, i);
+ g_hash_table_insert (priv->supported_resolutions,
+ g_strdup_printf ("%ix%i", video_format.width,
+ video_format.height),
+ &g_array_index (webcam_device->video_formats,
+ CheeseVideoFormat,
+ i));
g_print ("%s %d x %d num_framerates %d\n", video_format.mimetype, video_format.width,
video_format.height, video_format.num_framerates);
for (j = 0; j < video_format.num_framerates; j++)
@@ -544,6 +559,26 @@
}
static void
+cheese_webcam_create_fake_format (CheeseWebcam *webcam)
+{
+ CheeseWebcamPrivate *priv = CHEESE_WEBCAM_GET_PRIVATE (webcam);
+ CheeseVideoFormat format;
+
+ /* Right now just emulate one format: video/x-raw-yuv, 320x240 @ 30 Hz */
+
+ format.mimetype = g_strdup ("video/x-raw-yuv");
+ format.width = 320;
+ format.height = 240;
+ format.num_framerates = 1;
+ format.framerates = g_new0 (CheeseFramerate, 1);
+ format.framerates[0].numerator = 30;
+ format.framerates[0].denominator = 1;
+
+ g_array_append_val (priv->webcam_devices[0].video_formats, format);
+ priv->current_format = &format;
+}
+
+static void
cheese_webcam_detect_webcam_devices (CheeseWebcam *webcam)
{
CheeseWebcamPrivate* priv = CHEESE_WEBCAM_GET_PRIVATE (webcam);
@@ -552,8 +587,37 @@
cheese_webcam_get_video_devices_from_hal (webcam);
for (i = 0; i < priv->num_webcam_devices; i++)
{
- cheese_webcam_get_webcam_device_data (&(priv->webcam_devices[i]));
+ cheese_webcam_get_webcam_device_data (webcam, &(priv->webcam_devices[i]));
}
+
+ if (priv->num_webcam_devices == 0)
+ cheese_webcam_create_fake_format (webcam);
+}
+
+static void
+find_highest_framerate (CheeseVideoFormat *format, int *numerator,
+ int *denominator)
+{
+ int framerate_numerator;
+ int framerate_denominator;
+ int i;
+
+ /* Select the highest framerate up to 30 Hz*/
+ framerate_numerator = 1;
+ framerate_denominator = 1;
+ for (i = 0; i < format->num_framerates; i++)
+ {
+ float framerate = format->framerates[i].numerator / format->framerates[i].denominator;
+ if (framerate > ((float)framerate_numerator / framerate_denominator)
+ && framerate <= 30)
+ {
+ framerate_numerator = format->framerates[i].numerator;
+ framerate_denominator = format->framerates[i].denominator;
+ }
+ }
+
+ *numerator = framerate_numerator;
+ *denominator = framerate_denominator;
}
static gboolean
@@ -565,53 +629,60 @@
if (priv->num_webcam_devices == 0)
{
- goto fallback;
+ priv->webcam_source_bin = gst_parse_bin_from_description ("videotestsrc name=video_source ! capsfilter name=capsfilter ! identity",
+ TRUE, &err);
}
else
{
CheeseVideoFormat *format;
int i;
- int selected_device;
int framerate_numerator, framerate_denominator;
+ gchar *resolution;
/* If we have a matching video device use that one, otherwise use the first */
- selected_device = 0;
+ priv->selected_device = 0;
+ format = NULL;
for (i = 1; i < priv->num_webcam_devices ; i++)
{
if (g_strcmp0 (priv->webcam_devices[i].video_device, priv->device_name) == 0)
- selected_device = i;
+ priv->selected_device = i;
}
- CheeseWebcamDevice *selected_webcam = &(priv->webcam_devices[selected_device]);
+ CheeseWebcamDevice *selected_webcam = &(priv->webcam_devices[priv->selected_device]);
- /* Select the highest resolution */
- format = &(g_array_index (selected_webcam->video_formats, CheeseVideoFormat, 0));
- for (i = 1; i < selected_webcam->num_video_formats; i++)
- {
+ resolution = g_strdup_printf ("%ix%i", priv->x_resolution,
+ priv->y_resolution);
- if (g_array_index (selected_webcam->video_formats, CheeseVideoFormat, i).width > format->width)
+ /* Use the previously set resolution from gconf if it is set and the
+ * camera supports it. */
+ if (priv->x_resolution != 0 && priv->y_resolution != 0)
+ format = g_hash_table_lookup (priv->supported_resolutions, resolution);
+
+ if (!format)
+ {
+ /* Select the highest resolution */
+ format = &(g_array_index (selected_webcam->video_formats,
+ CheeseVideoFormat, 0));
+ for (i = 1; i < selected_webcam->num_video_formats; i++)
{
- format = &(g_array_index (selected_webcam->video_formats, CheeseVideoFormat, i));
+ if (g_array_index (selected_webcam->video_formats,
+ CheeseVideoFormat, i).width > format->width)
+ {
+ format = &(g_array_index (selected_webcam->video_formats,
+ CheeseVideoFormat, i));
+ }
}
}
-
+
+ priv->current_format = format;
+ g_free (resolution);
+
+ find_highest_framerate (format, &framerate_numerator,
+ &framerate_denominator);
+
if (format == NULL)
goto fallback;
- /* Select the highest framerate up to 30 Hz*/
- framerate_numerator = 1;
- framerate_denominator = 1;
- for (i = 0; i < format->num_framerates; i++)
- {
- float framerate = format->framerates[i].numerator / format->framerates[i].denominator;
- if (framerate > ((float)framerate_numerator / framerate_denominator)
- && framerate <= 30)
- {
- framerate_numerator = format->framerates[i].numerator;
- framerate_denominator = format->framerates[i].denominator;
- }
- }
-
- webcam_input = g_strdup_printf ("%s name=video_source device=%s ! %s,width=%d,height=%d,framerate=%d/%d ! identity",
+ webcam_input = g_strdup_printf ("%s name=video_source device=%s ! capsfilter name=capsfilter caps=%s,width=%d,height=%d,framerate=%d/%d ! identity",
selected_webcam->gstreamer_src,
selected_webcam->video_device,
format->mimetype,
@@ -625,11 +696,13 @@
TRUE, &err);
g_free (webcam_input);
- if ( priv->webcam_source_bin == NULL)
+ if (priv->webcam_source_bin == NULL)
goto fallback;
}
priv->video_source = gst_bin_get_by_name (GST_BIN (priv->webcam_source_bin), "video_source");
+ priv->capsfilter = gst_bin_get_by_name (GST_BIN (priv->webcam_source_bin),
+ "capsfilter");
return TRUE;
fallback:
@@ -647,6 +720,8 @@
g_error_free (err);
return FALSE;
}
+ priv->capsfilter = gst_bin_get_by_name (GST_BIN (priv->webcam_source_bin),
+ "capsfilter");
return TRUE;
}
@@ -749,7 +824,6 @@
GstElement *mux;
GstPad *pad;
gboolean ok;
- GstCaps *caps;
priv->video_save_bin = gst_bin_new ("video_save_bin");
@@ -781,15 +855,8 @@
ok = gst_element_link_many (priv->audio_source, audio_queue, audio_convert,
audio_enc, mux, priv->video_file_sink, NULL);
- /* Record videos always in 320x240 */
- ok &= gst_element_link (video_save_csp ,video_save_scale);
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "width", G_TYPE_INT, 320,
- "height", G_TYPE_INT, 240,
- NULL);
- ok &= gst_element_link_filtered (video_save_scale, video_enc, caps);
- gst_caps_unref (caps);
-
+ ok &= gst_element_link_many (video_save_csp, video_save_scale, video_enc,
+ NULL);
ok &= gst_element_link (video_enc, mux);
if (!ok)
@@ -1004,6 +1071,8 @@
g_array_free (priv->webcam_devices[i].video_formats, TRUE);
}
g_free (priv->webcam_devices);
+
+ g_hash_table_destroy (priv->supported_resolutions);
G_OBJECT_CLASS (cheese_webcam_parent_class)->finalize (object);
}
@@ -1024,6 +1093,12 @@
case PROP_DEVICE_NAME:
g_value_set_string (value, priv->device_name);
break;
+ case PROP_X_RESOLUTION:
+ g_value_set_int (value, priv->x_resolution);
+ break;
+ case PROP_Y_RESOLUTION:
+ g_value_set_int (value, priv->y_resolution);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1049,6 +1124,12 @@
g_free (priv->device_name);
priv->device_name = g_value_dup_string (value);
break;
+ case PROP_X_RESOLUTION:
+ priv->x_resolution = g_value_get_int (value);
+ break;
+ case PROP_Y_RESOLUTION:
+ priv->y_resolution = g_value_get_int (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1090,6 +1171,26 @@
NULL,
"",
G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_X_RESOLUTION,
+ g_param_spec_int ("x-resolution",
+ NULL,
+ NULL,
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class, PROP_Y_RESOLUTION,
+ g_param_spec_int ("y-resolution",
+ NULL,
+ NULL,
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
g_type_class_add_private (klass, sizeof (CheeseWebcamPrivate));
@@ -1105,6 +1206,33 @@
priv->photo_filename = NULL;
priv->webcam_devices = NULL;
priv->device_name = NULL;
+
+ priv->supported_resolutions = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free, NULL);
+}
+
+CheeseWebcam*
+cheese_webcam_new (GtkWidget* video_window, char *webcam_device_name,
+ int x_resolution, int y_resolution)
+{
+ CheeseWebcam *webcam;
+
+ if (webcam_device_name)
+ {
+ webcam = g_object_new (CHEESE_TYPE_WEBCAM, "video-window", video_window,
+ "device_name", webcam_device_name,
+ "x-resolution", x_resolution,
+ "y-resolution", y_resolution, NULL);
+ }
+ else
+ {
+ webcam = g_object_new (CHEESE_TYPE_WEBCAM, "video-window", video_window,
+ "x-resolution", x_resolution,
+ "y-resolution", y_resolution, NULL);
+ }
+
+ return webcam;
}
void
@@ -1139,20 +1267,46 @@
gdk_threads_leave();
}
+GArray *
+cheese_webcam_get_video_formats (CheeseWebcam *webcam)
+{
+ CheeseWebcamPrivate *priv = CHEESE_WEBCAM_GET_PRIVATE (webcam);
+
+ return priv->webcam_devices[priv->selected_device].video_formats;
+}
+
+void
+cheese_webcam_set_video_format (CheeseWebcam *webcam, CheeseVideoFormat *format)
+{
+ CheeseWebcamPrivate *priv = CHEESE_WEBCAM_GET_PRIVATE (webcam);
+ GstCaps *new_caps;
+ int framerate_numerator;
+ int framerate_denominator;
+
+ find_highest_framerate (format, &framerate_numerator, &framerate_denominator);
+
+ new_caps = gst_caps_new_simple (format->mimetype,
+ "width", G_TYPE_INT,
+ format->width,
+ "height", G_TYPE_INT,
+ format->height,
+ "framerate", GST_TYPE_FRACTION,
+ framerate_numerator,
+ framerate_denominator,
+ NULL);
+
+ priv->current_format = format;
+
+ cheese_webcam_stop (webcam);
+ g_object_set (priv->capsfilter, "caps", new_caps, NULL);
+ cheese_webcam_play (webcam);
+}
-CheeseWebcam*
-cheese_webcam_new (GtkWidget* video_window, char *webcam_device_name)
+CheeseVideoFormat *
+cheese_webcam_get_current_video_format (CheeseWebcam *webcam)
{
- CheeseWebcam *webcam;
- if (webcam_device_name)
- {
- webcam = g_object_new (CHEESE_TYPE_WEBCAM, "video-window", video_window,
- "device-name", webcam_device_name, NULL);
- }
- else
- {
- webcam = g_object_new (CHEESE_TYPE_WEBCAM, "video-window", video_window, NULL);
- }
- return webcam;
+ CheeseWebcamPrivate *priv = CHEESE_WEBCAM_GET_PRIVATE (webcam);
+
+ return priv->current_format;
}
Modified: trunk/src/cheese-webcam.h
==============================================================================
--- trunk/src/cheese-webcam.h (original)
+++ trunk/src/cheese-webcam.h Mon Apr 21 16:37:06 2008
@@ -35,6 +35,21 @@
#define CHEESE_IS_WEBCAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CHEESE_TYPE_WEBCAM))
#define CHEESE_WEBCAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CHEESE_TYPE_WEBCAM, CheeseWebcamClass))
+typedef struct
+{
+ int numerator;
+ int denominator;
+} CheeseFramerate;
+
+typedef struct
+{
+ char *mimetype;
+ int width;
+ int height;
+ int num_framerates;
+ CheeseFramerate *framerates;
+} CheeseVideoFormat;
+
typedef enum
{
CHEESE_WEBCAM_EFFECT_NO_EFFECT = (0),
@@ -66,7 +81,10 @@
GType cheese_webcam_get_type (void);
-CheeseWebcam *cheese_webcam_new (GtkWidget *video_window, char *webcam_device_name);
+CheeseWebcam *cheese_webcam_new (GtkWidget *video_window,
+ char *webcam_device_name,
+ int x_resolution,
+ int y_resolution);
void cheese_webcam_setup (CheeseWebcam *webcam);
void cheese_webcam_play (CheeseWebcam *webcam);
void cheese_webcam_stop (CheeseWebcam *webcam);
@@ -76,6 +94,10 @@
void cheese_webcam_take_photo (CheeseWebcam *webcam, char *filename);
gboolean cheese_webcam_has_webcam (CheeseWebcam *webcam);
int cheese_webcam_get_num_webcam_devices (CheeseWebcam *webcam);
+GArray *cheese_webcam_get_video_formats (CheeseWebcam *webcam);
+void cheese_webcam_set_video_format (CheeseWebcam *webcam,
+ CheeseVideoFormat *format);
+CheeseVideoFormat *cheese_webcam_get_current_video_format (CheeseWebcam *webcam);
G_END_DECLS
#endif /* __CHEESE_WEBCAM_H__ */
Modified: trunk/src/cheese-window.c
==============================================================================
--- trunk/src/cheese-window.c (original)
+++ trunk/src/cheese-window.c Mon Apr 21 16:37:06 2008
@@ -49,6 +49,7 @@
#include "gst-audio-play.h"
#include "gedit-message-area.h"
#include "cheese-no-camera.h"
+#include "cheese-prefs-dialog.h"
#define SHUTTER_SOUNDS 5
@@ -58,7 +59,6 @@
WEBCAM_MODE_VIDEO
} WebcamMode;
-
typedef struct
{
gboolean recording;
@@ -114,6 +114,7 @@
GtkActionGroup *actions_account_photo;
GtkActionGroup *actions_countdown;
GtkActionGroup *actions_effects;
+ GtkActionGroup *actions_preferences;
GtkActionGroup *actions_file;
GtkActionGroup *actions_flickr;
GtkActionGroup *actions_fspot;
@@ -234,6 +235,9 @@
g_object_unref (cheese_window->actions_mail);
g_object_unref (cheese_window->actions_photo);
g_object_unref (cheese_window->actions_toggle);
+ g_object_unref (cheese_window->actions_effects);
+ g_object_unref (cheese_window->actions_preferences);
+ g_object_unref (cheese_window->actions_file);
g_object_unref (cheese_window->actions_video);
g_object_unref (cheese_window->ui_manager);
g_object_unref (cheese_window->gconf);
@@ -941,6 +945,13 @@
}
}
+static void
+cheese_window_preferences_cb (GtkAction *action, CheeseWindow *cheese_window)
+{
+ cheese_prefs_dialog_run (cheese_window->window, cheese_window->gconf,
+ cheese_window->webcam);
+}
+
static const GtkActionEntry action_entries_main[] = {
{"Cheese", NULL, N_("_Cheese")},
@@ -963,6 +974,10 @@
{"Effects", NULL, N_("_Effects"), NULL, NULL, G_CALLBACK (cheese_window_effect_button_pressed_cb), FALSE},
};
+static const GtkActionEntry action_entries_preferences[] = {
+ {"Preferences", GTK_STOCK_PREFERENCES, N_("Preferences"), NULL, NULL, G_CALLBACK (cheese_window_preferences_cb)},
+};
+
static const GtkRadioActionEntry action_entries_toggle[] = {
{"Photo", NULL, N_("_Photo"), NULL, NULL, 0},
{"Video", NULL, N_("_Video"), NULL, NULL, 1},
@@ -1194,6 +1209,10 @@
"ActionsEffects",
action_entries_effects,
G_N_ELEMENTS (action_entries_effects));
+ cheese_window->actions_preferences = cheese_window_action_group_new (cheese_window,
+ "ActionsPreferences",
+ action_entries_preferences,
+ G_N_ELEMENTS (action_entries_preferences));
cheese_window->actions_file = cheese_window_action_group_new (cheese_window,
"ActionsFile",
action_entries_file,
@@ -1306,11 +1325,16 @@
setup_camera (CheeseWindow *cheese_window)
{
char *webcam_device = NULL;
+ int x_resolution;
+ int y_resolution;
GtkWidget *message_area;
+
+ g_object_get (cheese_window->gconf, "gconf_prop_x_resolution", &x_resolution,
+ "gconf_prop_y_resolution", &y_resolution, NULL);
- g_object_get (cheese_window->gconf, "gconf_prop_webcam", &webcam_device, NULL);
-
- cheese_window->webcam = cheese_webcam_new (cheese_window->screen, webcam_device);
+ cheese_window->webcam = cheese_webcam_new (cheese_window->screen,
+ webcam_device, x_resolution,
+ y_resolution);
g_free (webcam_device);
cheese_webcam_setup (cheese_window->webcam);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]