[cheese/f19] Add a number of bug-fixes to deal better with high res cams (#873434)

Hans de Goede jwrdegoede at fedoraproject.org
Mon Jun 17 12:25:11 UTC 2013


commit 65a88490987032a8f26eb1d79b8f4b0d46d4f5c2
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon Jun 17 14:24:49 2013 +0200

    Add a number of bug-fixes to deal better with high res cams (#873434)
    
    - Fix cheese-introduction.png being in both cheese and cheese-libs (#893756)
    - Put the COPYING file in the docs for cheese-libs (#893800)
    - Fix the flash when taking a photo being dark grey instead of white (#965813)
    - Fix needing to press the effects button twice to select effects after
      selecting an effect for the first time
    - Various other bug-fixes

 ...ra-Add-a-capsfilter-to-our-video-source-b.patch |   49 ++++
 ...b-view-Don-t-set-columns-to-5000-in-horiz.patch |  126 ---------
 ...ra-remove-extranous-csp_post_balance-vide.patch |   65 +++++
 ...camera_device_update_format_table-going-i.patch |   45 ---
 ...e-camera-Set-image-and-video-capture-caps.patch |   30 ++
 ...h-is-a-multiple-of-8-and-height-a-multipl.patch |   73 -----
 ...ra-Fix-the-no-video-after-switching-resol.patch |   57 ++++
 ...se-camera-2-minor-error-handling-cleanups.patch |   43 +++
 ...ra-Fix-video-source-memleak-when-switchin.patch |   28 ++
 0007-cheese-camera-Remove-unused-enum.patch        |   36 +++
 ...cheese-camera-device-Fix-compiler-warning.patch |   26 ++
 ...era-device-Fix-memleak-in-get_best_format.patch |   54 ++++
 ...ra-device-Keep-track-of-highest-available.patch |  281 ++++++++++++++++++++
 ...ra-device-Add-cheese_camera_device_find_f.patch |   74 +++++
 ...ra-device-limit-caps-to-the-maximum-frame.patch |   94 +++++++
 ...ra-device-get_caps_for_format-simplify-th.patch |   29 ++
 ...amera-device-Make-get_best_format-smarter.patch |   67 +++++
 ...eese-camera-device-Plug-some-memory-leaks.patch |   47 ++++
 0016-cheese-camera-Drop-unused-preview_caps.patch  |   26 ++
 ...ra-Do-not-add-videoconvert-elements-aroun.patch |   52 ++++
 ...ra-Check-for-the-current-effect-being-the.patch |   81 ++++++
 ...ra-Don-t-block-the-main-valve-while-recor.patch |   30 ++
 ...ra-Downscale-image-for-effects-preview-pi.patch |  119 +++++++++
 ...indow-Fix-de-activation-of-effects-button.patch |   51 ++++
 ...ow-Make-mode-toggle-and-effects-button-in.patch |   98 +++++++
 ...dd-_init_with_args-init-function-variants.patch |  213 +++++++++++++++
 0024-cheese-Use-cheese_gtk_init_with_args.patch    |  196 ++++++++++++++
 ...Remove-last-remnants-of-the-old-menu-code.patch |  206 ++++++++++++++
 ...ect-set_wide_mode-set_fullscreen-against-.patch |   52 ++++
 ...-rid-of-special-set_startup_foo-functions.patch |   94 +++++++
 ...the-need-to-press-F11-twice-after-startin.patch |   32 +++
 ...e-widemode-controllable-from-the-app-menu.patch |   68 +++++
 ...-reading-of-widemode-setting-to-cheese-ma.patch |   54 ++++
 ...reading-of-fullscreen-setting-from-config.patch |   34 +++
 ...t-show-thumbnails-when-toggling-widemode-.patch |   53 ++++
 ...updating-of-device-selection-combo-sensit.patch |   54 ++++
 ...e-Fix-assert-failures-when-taking-a-photo.patch |   38 +++
 ...flash-Fix-the-flash-no-longer-being-white.patch |   65 +++++
 cheese.spec                                        |  124 +++++++--
 39 files changed, 2700 insertions(+), 264 deletions(-)
---
diff --git a/0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch b/0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch
new file mode 100644
index 0000000..a4569a7
--- /dev/null
+++ b/0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch
@@ -0,0 +1,49 @@
+From a602ffdd541b828ab9b8aac9b20db31ce427ba8b Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 19:48:47 +0200
+Subject: [PATCH 01/35] cheese-camera: Add a capsfilter to our video-source bin
+
+This serves 2 purposes:
+1) It forces gstreamer to actually run the video source at the configured
+   resolution, rather then say run it at 1600x1200 @ 5 fps and downscale
+   that to 800x600 (still at 5 fps), as gstreamer opts to do with my
+   Logitech Webcam Pro 9000, when left to its own auto negotiate code.
+2) By greatly reducing the amount of advertised caps (this cam supports lots
+   of different resolutions at many different framerates per resolution), it
+   avoids a caps intersect "explosion", reducing the pipeline caps negotiation
+   on my core i5 @ 3.1Ghz from aprox 1.1 sec to aprox 350 ms (*).
+
+*) When combined with later patches in this patchset which also limit the
+framerates in the filtered caps.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index a78affd..c42d896 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -417,7 +417,7 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+   }
+ 
+   camera_input = g_strdup_printf (
+-    "%s name=video_source device=%s",
++    "%s name=video_source device=%s ! capsfilter name=video_source_filter",
+     cheese_camera_device_get_src (selected_camera),
+     cheese_camera_device_get_device_node (selected_camera));
+ 
+@@ -762,7 +762,8 @@ cheese_camera_set_new_caps (CheeseCamera *camera)
+ 
+   if (!gst_caps_is_empty (caps))
+   {
+-    GST_INFO_OBJECT (camera, "SETTING caps%" GST_PTR_FORMAT, caps);
++    GST_INFO_OBJECT (camera, "SETTING caps %" GST_PTR_FORMAT, caps);
++    g_object_set (gst_bin_get_by_name (GST_BIN (priv->video_source), "video_source_filter"), "caps", caps, NULL);
+     g_object_set (priv->camerabin, "viewfinder-caps", caps, NULL);
+   }
+   gst_caps_unref (caps);
+-- 
+1.8.2.1
+
diff --git a/0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch b/0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch
new file mode 100644
index 0000000..091ac69
--- /dev/null
+++ b/0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch
@@ -0,0 +1,65 @@
+From 4740659c6092018a35bb820dfefac545b23c5dc2 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Sun, 9 Jun 2013 17:14:00 +0200
+Subject: [PATCH 02/35] cheese-camera: remove extranous csp_post_balance
+ videoconvert element
+
+camerabin2 already has a videoconvert element both before and after its
+video-source-filter element, so ending our own video-source-filter bin with
+a videoconvert element puts 2 videoconvert elements behind each other, which
+is not really useful.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index c42d896..7737209 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -89,7 +89,7 @@ struct _CheeseCameraPrivate
+   ClutterTexture *video_texture;
+ 
+   GstElement *effect_filter;
+-  GstElement *video_balance, *csp_post_balance;
++  GstElement *video_balance;
+   GstElement *camera_tee, *effects_tee;
+   GstElement *main_valve, *effects_valve;
+ 
+@@ -608,29 +608,22 @@ cheese_camera_create_video_filter_bin (CheeseCamera *camera, GError **error)
+     cheese_camera_set_error_element_not_found (error, "videobalance");
+     return FALSE;
+   }
+-  if ((priv->csp_post_balance = gst_element_factory_make ("videoconvert", "csp_post_balance")) == NULL)
+-  {
+-    cheese_camera_set_error_element_not_found (error, "videoconvert");
+-    return FALSE;
+-  }
+ 
+   if (error != NULL && *error != NULL)
+     return FALSE;
+ 
+   gst_bin_add_many (GST_BIN (priv->video_filter_bin), priv->camera_tee,
+                     priv->main_valve, priv->effect_filter,
+-                    priv->video_balance, priv->csp_post_balance,
+-                    priv->effects_preview_bin, NULL);
++                    priv->video_balance, priv->effects_preview_bin, NULL);
+ 
+   ok &= gst_element_link_many (priv->camera_tee, priv->main_valve,
+-                               priv->effect_filter, priv->video_balance,
+-                               priv->csp_post_balance, NULL);
++                               priv->effect_filter, priv->video_balance, NULL);
+   gst_pad_link (gst_element_get_request_pad (priv->camera_tee, "src_%u"),
+                 gst_element_get_static_pad (priv->effects_preview_bin, "sink"));
+ 
+   /* add ghostpads */
+ 
+-  pad = gst_element_get_static_pad (priv->csp_post_balance, "src");
++  pad = gst_element_get_static_pad (priv->video_balance, "src");
+   gst_element_add_pad (priv->video_filter_bin, gst_ghost_pad_new ("src", pad));
+   gst_object_unref (GST_OBJECT (pad));
+ 
+-- 
+1.8.2.1
+
diff --git a/0003-cheese-camera-Set-image-and-video-capture-caps.patch b/0003-cheese-camera-Set-image-and-video-capture-caps.patch
new file mode 100644
index 0000000..203bf5b
--- /dev/null
+++ b/0003-cheese-camera-Set-image-and-video-capture-caps.patch
@@ -0,0 +1,30 @@
+From aedbd71c2c57b6555744a8ecf35f50816a809d97 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:12:41 +0200
+Subject: [PATCH 03/35] cheese-camera: Set image- and video-capture-caps
+
+Force the image / video capture to be in our desired resolution, rather then
+relying on constraints elsewhere in the pipeline resulting in us getting
+the desired resolution.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 7737209..9eeb245 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -758,6 +758,8 @@ cheese_camera_set_new_caps (CheeseCamera *camera)
+     GST_INFO_OBJECT (camera, "SETTING caps %" GST_PTR_FORMAT, caps);
+     g_object_set (gst_bin_get_by_name (GST_BIN (priv->video_source), "video_source_filter"), "caps", caps, NULL);
+     g_object_set (priv->camerabin, "viewfinder-caps", caps, NULL);
++    g_object_set (priv->camerabin, "image-capture-caps", caps, NULL);
++    g_object_set (priv->camerabin, "video-capture-caps", caps, NULL);
+   }
+   gst_caps_unref (caps);
+ }
+-- 
+1.8.2.1
+
diff --git a/0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch b/0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch
new file mode 100644
index 0000000..c7936d1
--- /dev/null
+++ b/0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch
@@ -0,0 +1,57 @@
+From 62d880a4f15b2a4ccf84c7078b9c7232b27cd228 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:26:39 +0200
+Subject: [PATCH 04/35] cheese-camera: Fix the no video after switching
+ resolution problem
+
+There is a bug in wrappercamerabinsrc which causes it to loose its video-source
+setting after the pipeline has started, so on a stop / re-start, as we
+do when changing resolution, its video-source has become NULL, and we no
+longer have video.
+
+This patch works around this by moving the setting of the video-source
+property to cheese_camera_play(), so that it gets (re)set each time before
+we start the pipeline.
+
+I've also written a patch fixing the underlying cause, but since the workaround
+is simple, and has no adverse effects when the underlying issue is fixed,
+it seems a good idea to have this workaround in cheese, see here for the
+gst-plugins-bad fix: https://bugzilla.gnome.org/show_bug.cgi?id=701915
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 9eeb245..b353152 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -424,7 +424,7 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+   priv->video_source = gst_parse_bin_from_description (camera_input, TRUE, &err);
+   g_free (camera_input);
+ 
+-  if (priv->video_source == NULL || priv->camera_source == NULL)
++  if (priv->video_source == NULL)
+   {
+     if (err != NULL)
+     {
+@@ -433,7 +433,6 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+     }
+     return FALSE;
+   }
+-  g_object_set (priv->camera_source, "video-source", priv->video_source, NULL);
+ 
+   return TRUE;
+ }
+@@ -769,6 +768,7 @@ cheese_camera_play (CheeseCamera *camera)
+ {
+   CheeseCameraPrivate *priv   = CHEESE_CAMERA_GET_PRIVATE (camera);
+   cheese_camera_set_new_caps (camera);
++  g_object_set (priv->camera_source, "video-source", priv->video_source, NULL);
+   gst_element_set_state (priv->camerabin, GST_STATE_PLAYING);
+   priv->pipeline_is_playing = TRUE;
+ }
+-- 
+1.8.2.1
+
diff --git a/0005-cheese-camera-2-minor-error-handling-cleanups.patch b/0005-cheese-camera-2-minor-error-handling-cleanups.patch
new file mode 100644
index 0000000..b80f076
--- /dev/null
+++ b/0005-cheese-camera-2-minor-error-handling-cleanups.patch
@@ -0,0 +1,43 @@
+From b770f7675a42a0ff0bc0845aff1af1a739525e3c Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:39:16 +0200
+Subject: [PATCH 05/35] cheese-camera: 2 minor error handling cleanups
+
+1) Simplify error cleanup in cheese_camera_set_camera_source()
+2) Don't call g_error_free on a possible NULL error in
+   cheese_camera_element_from_effect()
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index b353152..b55dc82 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -426,11 +426,7 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+ 
+   if (priv->video_source == NULL)
+   {
+-    if (err != NULL)
+-    {
+-      g_error_free (err);
+-      err = NULL;
+-    }
++    g_clear_error(&err);
+     return FALSE;
+   }
+ 
+@@ -867,7 +863,7 @@ cheese_camera_element_from_effect (CheeseCamera *camera, CheeseEffect *effect)
+   g_free (effects_pipeline_desc);
+   if (!effect_filter || (err != NULL))
+   {
+-    g_error_free (err);
++    g_clear_error (&err);
+     g_warning ("Error with effect filter %s. Ignored", name);
+     g_free (name);
+     return NULL;
+-- 
+1.8.2.1
+
diff --git a/0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch b/0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch
new file mode 100644
index 0000000..c1391dd
--- /dev/null
+++ b/0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch
@@ -0,0 +1,28 @@
+From 6d3749f799b1217363ac40eb7e618a37301b008b Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:46:10 +0200
+Subject: [PATCH 06/35] cheese-camera: Fix video-source memleak when switching
+ between cameras
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index b55dc82..c6cb4eb 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -400,6 +400,9 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+   guint               i;
+   CheeseCameraDevice *selected_camera;
+ 
++  if (priv->video_source)
++    gst_object_unref (priv->video_source);
++
+   /* If we have a matching video device use that one, otherwise use the first */
+   priv->selected_device = 0;
+   selected_camera       = g_ptr_array_index (priv->camera_devices, 0);
+-- 
+1.8.2.1
+
diff --git a/0007-cheese-camera-Remove-unused-enum.patch b/0007-cheese-camera-Remove-unused-enum.patch
new file mode 100644
index 0000000..31010b6
--- /dev/null
+++ b/0007-cheese-camera-Remove-unused-enum.patch
@@ -0,0 +1,36 @@
+From b0478b500889ccc7b17c1a3ba8e5aac87e12fdd0 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:46:43 +0200
+Subject: [PATCH 07/35] cheese-camera: Remove unused enum
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index c6cb4eb..fd5d2bf 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -59,18 +59,6 @@ G_DEFINE_TYPE (CheeseCamera, cheese_camera, G_TYPE_OBJECT)
+ 
+ #define CHEESE_CAMERA_ERROR cheese_camera_error_quark ()
+ 
+-typedef enum {
+-  GST_CAMERABIN_FLAG_SOURCE_RESIZE               = (1 << 0),
+-  GST_CAMERABIN_FLAG_SOURCE_COLOR_CONVERSION     = (1 << 1),
+-  GST_CAMERABIN_FLAG_VIEWFINDER_COLOR_CONVERSION = (1 << 2),
+-  GST_CAMERABIN_FLAG_VIEWFINDER_SCALE            = (1 << 3),
+-  GST_CAMERABIN_FLAG_AUDIO_CONVERSION            = (1 << 4),
+-  GST_CAMERABIN_FLAG_DISABLE_AUDIO               = (1 << 5),
+-  GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION      = (1 << 6),
+-  GST_CAMERABIN_FLAG_VIDEO_COLOR_CONVERSION      = (1 << 7)
+-} GstCameraBinFlags;
+-
+-
+ struct _CheeseCameraPrivate
+ {
+   GstBus *bus;
+-- 
+1.8.2.1
+
diff --git a/0008-cheese-camera-device-Fix-compiler-warning.patch b/0008-cheese-camera-device-Fix-compiler-warning.patch
new file mode 100644
index 0000000..bf87947
--- /dev/null
+++ b/0008-cheese-camera-device-Fix-compiler-warning.patch
@@ -0,0 +1,26 @@
+From 5df60ca7f29d6008f894e8b702b288dad55851f9 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:56:25 +0200
+Subject: [PATCH 08/35] cheese-camera-device: Fix compiler warning
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index 92d03a3..c7b7a07 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -165,7 +165,7 @@ compare_formats (gconstpointer a, gconstpointer b)
+  * Returns: the filtered #GstCaps
+  */
+ static GstCaps *
+-cheese_camera_device_filter_caps (CheeseCameraDevice *device, const GstCaps *caps, GStrv formats)
++cheese_camera_device_filter_caps (CheeseCameraDevice *device, GstCaps *caps, GStrv formats)
+ {
+   GstCaps *filter;
+   GstCaps *allowed;
+-- 
+1.8.2.1
+
diff --git a/0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch b/0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch
new file mode 100644
index 0000000..e74eefd
--- /dev/null
+++ b/0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch
@@ -0,0 +1,54 @@
+From d5e114ae636089ff6c1554c1d98b1ea8d8ad3ff3 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 13:44:47 +0200
+Subject: [PATCH 09/35] cheese-camera-device: Fix memleak in get_best_format
+
+cheese_camera_device_get_best_format() calls
+cheese_camera_device_get_format_list(), which returns a sorted copy of the
+format lists, then takes the first element of that list, and returns a
+copy of that element. While never freeing the list copy.
+
+This patch fixes this leak by simply making the priv->formats list sorted
+so that cheese_camera_device_get_best_format can use it directly without
+the need to make (and then later free) a copy.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index c7b7a07..e5ec5fa 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -219,7 +219,7 @@ cheese_camera_device_add_format (CheeseCameraDevice *device, CheeseVideoFormat *
+ 
+   GST_INFO ("%dx%d", format->width, format->height);
+ 
+-  priv->formats = g_list_append (priv->formats, format);
++  priv->formats = g_list_insert_sorted (priv->formats, format, compare_formats);
+ }
+ 
+ /*
+@@ -700,7 +700,7 @@ cheese_camera_device_get_format_list (CheeseCameraDevice *device)
+ {
+   g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
+ 
+-  return g_list_sort (g_list_copy (device->priv->formats), compare_formats);
++  return g_list_copy (device->priv->formats);
+ }
+ 
+ /**
+@@ -788,8 +788,7 @@ cheese_camera_device_get_best_format (CheeseCameraDevice *device)
+ 
+   g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
+ 
+-  format = g_boxed_copy (CHEESE_TYPE_VIDEO_FORMAT,
+-                         cheese_camera_device_get_format_list (device)->data);
++  format = g_boxed_copy (CHEESE_TYPE_VIDEO_FORMAT, device->priv->formats->data);
+ 
+   GST_INFO ("%dx%d", format->width, format->height);
+   return format;
+-- 
+1.8.2.1
+
diff --git a/0010-cheese-camera-device-Keep-track-of-highest-available.patch b/0010-cheese-camera-device-Keep-track-of-highest-available.patch
new file mode 100644
index 0000000..4311329
--- /dev/null
+++ b/0010-cheese-camera-device-Keep-track-of-highest-available.patch
@@ -0,0 +1,281 @@
+From 8b76b4ebc3f38e742f39ccded070be5e5290d41d Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 14:15:58 +0200
+Subject: [PATCH 10/35] cheese-camera-device: Keep track of highest available
+ framerate per format
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 167 ++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 149 insertions(+), 18 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index e5ec5fa..c684367 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -109,11 +109,29 @@ struct _CheeseCameraDevicePrivate
+   gchar *name;
+   guint  v4lapi_version;
+   GstCaps *caps;
+-  GList   *formats;
++  GList   *formats; /* list members are CheeseVideoFormatFull structs */
+ 
+   GError *construct_error;
+ };
+ 
++typedef struct _CheeseVideoFormatFull CheeseVideoFormatFull;
++
++/*
++ * This is our private version of CheeseVideoFormat, with extra fields added
++ * at the end. IMPORTANT the first fields *must* be kept in sync with the
++ * public CheeseVideoFormat, since in various places we cast pointers to
++ * CheeseVideoFormatFull to CheeseVideoFormat.
++ */
++struct _CheeseVideoFormatFull
++{
++  /* CheeseVideoFormat members keep synced with cheese-camera-device.h! */
++  gint width;
++  gint height;
++  /* libcheese private members */
++  gint fr_numerator;
++  gint fr_denominator;
++};
++
+ GQuark cheese_camera_device_error_quark (void);
+ 
+ GQuark
+@@ -145,8 +163,8 @@ G_DEFINE_BOXED_TYPE (CheeseVideoFormat, cheese_video_format,
+ static gint
+ compare_formats (gconstpointer a, gconstpointer b)
+ {
+-  const CheeseVideoFormat *c = a;
+-  const CheeseVideoFormat *d = b;
++  const CheeseVideoFormatFull *c = a;
++  const CheeseVideoFormatFull *d = b;
+ 
+   /* descending sort for rectangle area */
+   return (d->width * d->height - c->width * c->height);
+@@ -197,42 +215,154 @@ cheese_camera_device_filter_caps (CheeseCameraDevice *device, GstCaps *caps, GSt
+ }
+ 
+ /*
++ * cheese_camera_device_get_highest_framerate:
++ * @framerate: a #GValue holding a framerate cap
++ * @numerator: destination to store the numerator of the highest rate
++ * @denominator: destination to store the denominator of the highest rate
++ *
++ * Get the numerator and denominator for the highest framerate stored in
++ * a framerate cap.
++ *
++ * Note this function does not handle framerate ranges, if @framerate
++ * contains a range it will return 0/0 as framerate
++ */
++static void
++cheese_camera_device_get_highest_framerate(const GValue *framerate,
++  gint *numerator, gint *denominator)
++{
++  *numerator = 0;
++  *denominator = 0;
++
++  if (GST_VALUE_HOLDS_FRACTION (framerate))
++  {
++    *numerator = gst_value_get_fraction_numerator (framerate);
++    *denominator = gst_value_get_fraction_denominator (framerate);
++  }
++  else if (GST_VALUE_HOLDS_ARRAY (framerate))
++  {
++    float curr, highest = 0;
++    guint i, size = gst_value_array_get_size (framerate);
++
++    for (i = 0; i < size; i++)
++    {
++      const GValue *val = gst_value_array_get_value(framerate, i);
++
++      if (!GST_VALUE_HOLDS_FRACTION (val) ||
++          gst_value_get_fraction_denominator(val) == 0) {
++        continue;
++      }
++
++      curr = (float)gst_value_get_fraction_numerator(val) /
++             (float)gst_value_get_fraction_denominator(val);
++      if (curr > highest && curr <= CHEESE_MAXIMUM_RATE)
++      {
++        highest = curr;
++        *numerator = gst_value_get_fraction_numerator (val);
++        *denominator = gst_value_get_fraction_denominator (val);
++      }
++    }
++  }
++  else if (GST_VALUE_HOLDS_LIST (framerate))
++  {
++    float curr, highest = 0;
++    guint i, size = gst_value_list_get_size (framerate);
++
++    for (i = 0; i < size; i++)
++    {
++      const GValue *val = gst_value_list_get_value(framerate, i);
++
++      if (!GST_VALUE_HOLDS_FRACTION (val) ||
++          gst_value_get_fraction_denominator(val) == 0) {
++        continue;
++      }
++
++      curr = (float)gst_value_get_fraction_numerator(val) /
++             (float)gst_value_get_fraction_denominator(val);
++      if (curr > highest && curr <= CHEESE_MAXIMUM_RATE)
++      {
++        highest = curr;
++        *numerator = gst_value_get_fraction_numerator (val);
++        *denominator = gst_value_get_fraction_denominator (val);
++      }
++    }
++  }
++}
++
++/*
++ * cheese_camera_device_format_update_framerate:
++ * @format: the #CheeseVideoFormatFull to update the framerate of
++ * @framerate: a #GValue holding a framerate cap
++ *
++ * This function updates the framerate in @format with the highest framerate
++ * from @framerate, if @framerate contains a framerate higher then the
++ * framerate currently stored in @format.
++ */
++static void
++cheese_camera_device_format_update_framerate(CheeseVideoFormatFull *format,
++  const GValue *framerate)
++{
++  float high, curr = (float)format->fr_numerator / format->fr_denominator;
++  gint high_numerator, high_denominator;
++
++  cheese_camera_device_get_highest_framerate (framerate, &high_numerator,
++                                                         &high_denominator);
++  if (high_denominator == 0)
++    return;
++
++  high = (float)high_numerator / (float)high_denominator;
++  if (high > curr) {
++    format->fr_numerator = high_numerator;
++    format->fr_denominator = high_denominator;
++    GST_INFO ("%dx%d new framerate %d/%d", format->width, format->height,
++              format->fr_numerator, format->fr_denominator);
++  }
++}
++
++/*
+  * cheese_camera_device_add_format:
+  * @device: a #CheeseCameraDevice
+- * @format: the #CheeseVideoFormat to add
++ * @format: the #CheeseVideoFormatFull to add
+  *
+  * Add the supplied @format to the list of formats supported by the @device.
+  */
+ static void
+-cheese_camera_device_add_format (CheeseCameraDevice *device, CheeseVideoFormat *format)
++cheese_camera_device_add_format (CheeseCameraDevice *device,
++  CheeseVideoFormatFull *format, const GValue *framerate)
+ {
+   CheeseCameraDevicePrivate *priv =  device->priv;
+   GList *l;
+ 
+   for (l = priv->formats; l != NULL; l = l->next)
+   {
+-    CheeseVideoFormat *item = l->data;
++    CheeseVideoFormatFull *item = l->data;
+     if ((item != NULL) &&
+         (item->width == format->width) &&
+-        (item->height == format->height)) return;
++        (item->height == format->height))
++    {
++      cheese_camera_device_format_update_framerate (item, framerate);
++      return;
++    }
+   }
+ 
+-  GST_INFO ("%dx%d", format->width, format->height);
++  cheese_camera_device_get_highest_framerate (framerate,
++            &format->fr_numerator, &format->fr_denominator);
++  GST_INFO ("%dx%d framerate %d/%d", format->width, format->height,
++            format->fr_numerator, format->fr_denominator);
+ 
+   priv->formats = g_list_insert_sorted (priv->formats, format, compare_formats);
+ }
+ 
+ /*
+  * free_format_list_foreach:
+- * @data: the #CheeseVideoFormat to free
++ * @data: the #CheeseVideoFormatFull to free
+  * @user_data: unused
+  *
+- * Free the individual #CheeseVideoFormat.
++ * Free the individual #CheeseVideoFormatFull.
+  */
+ static void
+ free_format_list_foreach (gpointer data, G_GNUC_UNUSED gpointer user_data)
+ {
+-  g_slice_free (CheeseVideoFormat, data);
++  g_slice_free (CheeseVideoFormatFull, data);
+ }
+ 
+ /*
+@@ -271,19 +401,20 @@ cheese_camera_device_update_format_table (CheeseCameraDevice *device)
+   for (i = 0; i < num_structures; i++)
+   {
+     GstStructure *structure;
+-    const GValue *width, *height;
++    const GValue *width, *height, *framerate;
+     structure = gst_caps_get_structure (priv->caps, i);
+ 
+     width  = gst_structure_get_value (structure, "width");
+     height = gst_structure_get_value (structure, "height");
++    framerate = gst_structure_get_value (structure, "framerate");
+ 
+     if (G_VALUE_HOLDS_INT (width))
+     {
+-      CheeseVideoFormat *format = g_slice_new0 (CheeseVideoFormat);
++      CheeseVideoFormatFull *format = g_slice_new0 (CheeseVideoFormatFull);
+ 
+       gst_structure_get_int (structure, "width", &(format->width));
+       gst_structure_get_int (structure, "height", &(format->height));
+-      cheese_camera_device_add_format (device, format);
++      cheese_camera_device_add_format (device, format, framerate);
+     }
+     else if (GST_VALUE_HOLDS_INT_RANGE (width))
+     {
+@@ -310,14 +441,14 @@ cheese_camera_device_update_format_table (CheeseCameraDevice *device)
+        * we use <= here (and not below) to make this work */
+       while (cur_width <= max_width && cur_height <= max_height)
+       {
+-        CheeseVideoFormat *format = g_slice_new0 (CheeseVideoFormat);
++        CheeseVideoFormatFull *format = g_slice_new0 (CheeseVideoFormatFull);
+ 
+         /* Gstreamer wants resolutions for YUV formats where the width is
+          * a multiple of 8, and the height is a multiple of 2 */
+         format->width  = cur_width & ~7;
+         format->height = cur_height & ~1;
+ 
+-        cheese_camera_device_add_format (device, format);
++        cheese_camera_device_add_format (device, format, framerate);
+ 
+         cur_width  *= 2;
+         cur_height *= 2;
+@@ -327,14 +458,14 @@ cheese_camera_device_update_format_table (CheeseCameraDevice *device)
+       cur_height = max_height;
+       while (cur_width > min_width && cur_height > min_height)
+       {
+-        CheeseVideoFormat *format = g_slice_new0 (CheeseVideoFormat);
++        CheeseVideoFormatFull *format = g_slice_new0 (CheeseVideoFormatFull);
+ 
+         /* Gstreamer wants resolutions for YUV formats where the width is
+          * a multiple of 8, and the height is a multiple of 2 */
+         format->width  = cur_width & ~7;
+         format->height = cur_height & ~1;
+ 
+-        cheese_camera_device_add_format (device, format);
++        cheese_camera_device_add_format (device, format, framerate);
+ 
+         cur_width  /= 2;
+         cur_height /= 2;
+-- 
+1.8.2.1
+
diff --git a/0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch b/0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch
new file mode 100644
index 0000000..b3e7d22
--- /dev/null
+++ b/0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch
@@ -0,0 +1,74 @@
+From 0d5c4a4df0836bdbab85b3ccbca1dffeb54affe1 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 14:27:04 +0200
+Subject: [PATCH 11/35] cheese-camera-device: Add
+ cheese_camera_device_find_full_format() helper
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 40 ++++++++++++++++++++++++++++++----------
+ 1 file changed, 30 insertions(+), 10 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index c684367..25d4a51 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -319,6 +319,30 @@ cheese_camera_device_format_update_framerate(CheeseVideoFormatFull *format,
+ }
+ 
+ /*
++ * cheese_camera_device_find_full_format
++ * @device: a #CheeseCameraDevice
++ * @format: #CheeseVideoFormat to find the matching #CheeseVideoFormatFull for
++ *
++ * Find a #CheeseVideoFormatFull matching the passed in #CheeseVideoFormat
++ */
++static CheeseVideoFormatFull *
++cheese_camera_device_find_full_format(CheeseCameraDevice *device,
++  CheeseVideoFormat* format)
++{
++  GList *l;
++
++  for (l = device->priv->formats; l != NULL; l = l->next)
++  {
++    CheeseVideoFormatFull *item = l->data;
++    if ((item != NULL) &&
++        (item->width == format->width) &&
++        (item->height == format->height))
++      return item;
++  }
++  return NULL;
++}
++
++/*
+  * cheese_camera_device_add_format:
+  * @device: a #CheeseCameraDevice
+  * @format: the #CheeseVideoFormatFull to add
+@@ -330,18 +354,14 @@ cheese_camera_device_add_format (CheeseCameraDevice *device,
+   CheeseVideoFormatFull *format, const GValue *framerate)
+ {
+   CheeseCameraDevicePrivate *priv =  device->priv;
+-  GList *l;
++  CheeseVideoFormatFull *existing;
+ 
+-  for (l = priv->formats; l != NULL; l = l->next)
++  existing = cheese_camera_device_find_full_format(device,
++                                                 (CheeseVideoFormat *)format);
++  if (existing)
+   {
+-    CheeseVideoFormatFull *item = l->data;
+-    if ((item != NULL) &&
+-        (item->width == format->width) &&
+-        (item->height == format->height))
+-    {
+-      cheese_camera_device_format_update_framerate (item, framerate);
+-      return;
+-    }
++    cheese_camera_device_format_update_framerate (existing, framerate);
++    return;
+   }
+ 
+   cheese_camera_device_get_highest_framerate (framerate,
+-- 
+1.8.2.1
+
diff --git a/0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch b/0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch
new file mode 100644
index 0000000..5d33b82
--- /dev/null
+++ b/0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch
@@ -0,0 +1,94 @@
+From b9720475545f37baeb2eb1da4f45ca29faeb482f Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 14:47:40 +0200
+Subject: [PATCH 12/35] cheese-camera-device: limit caps to the maximum
+ framerate
+
+Limit the caps returned by cheese_camera_device_get_caps_for_format() to
+the maximum framerate supported at the requested resolution. This is
+necessary because gstreamer first selects a format and then a framerate,
+resulting in it picking for 1280x720 ie yuyv @ 15 fps, instead of mjpg @ 30
+fps (*), or at 1600x1200 yuyv @ 5 fps instead of mjpeg @ 10 fps.
+
+*) Which will be converted to i420 by the videoconvert element in camerabin
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 46 ++++++++++++++++++++++++++++------------
+ 1 file changed, 32 insertions(+), 14 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index 25d4a51..273d530 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -954,35 +954,53 @@ cheese_camera_device_get_best_format (CheeseCameraDevice *device)
+  *
+  * Returns: (transfer full): the #GstCaps for the given @format
+  */
++
++static GstCaps *
++cheese_camera_device_format_to_caps (const char *media_type,
++                                     CheeseVideoFormatFull *format)
++{
++  if (format->fr_numerator != 0 && format->fr_denominator != 0)
++    return gst_caps_new_simple (media_type,
++                                "framerate", GST_TYPE_FRACTION,
++                                  format->fr_numerator, format->fr_denominator,
++                                "width", G_TYPE_INT, format->width,
++                                "height", G_TYPE_INT, format->height, NULL);
++  else
++    return gst_caps_new_simple (media_type,
++                                "width", G_TYPE_INT, format->width,
++                                "height", G_TYPE_INT, format->height, NULL);
++}
++ 
+ GstCaps *
+ cheese_camera_device_get_caps_for_format (CheeseCameraDevice *device,
+                                           CheeseVideoFormat  *format)
+ {
++  CheeseVideoFormatFull *full_format;
+   GstCaps *desired_caps;
+   GstCaps *subset_caps;
+   guint    i, length;
+ 
+   g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
+ 
+-  GST_INFO ("Getting caps for %dx%d", format->width, format->height);
+-
+-  desired_caps = gst_caps_new_simple (supported_formats[0],
+-                                      "width", G_TYPE_INT,
+-                                      format->width,
+-                                      "height", G_TYPE_INT,
+-                                      format->height,
+-                                      NULL);
++  full_format = cheese_camera_device_find_full_format(device, format);
++  if (!full_format)
++  {
++    GST_INFO ("Getting caps for %dx%d: no such format!",
++              format->width, format->height);
++    return gst_caps_new_empty ();
++  }
++  GST_INFO ("Getting caps for %dx%d @ %d/%d fps",
++            full_format->width, full_format->height,
++            full_format->fr_numerator, full_format->fr_denominator);
+ 
++  desired_caps = cheese_camera_device_format_to_caps(supported_formats[0],
++                                                     full_format);
+   length = g_strv_length (supported_formats);
+   for (i = 1; i < length; i++)
+   {
+     gst_caps_append (desired_caps,
+-                     gst_caps_new_simple (supported_formats[i],
+-                                          "width", G_TYPE_INT,
+-                                          format->width,
+-                                          "height", G_TYPE_INT,
+-                                          format->height,
+-                                          NULL));
++                     cheese_camera_device_format_to_caps(supported_formats[i],
++                                                         full_format));
+   }
+ 
+   subset_caps = gst_caps_intersect (desired_caps, device->priv->caps);
+-- 
+1.8.2.1
+
diff --git a/0013-cheese-camera-device-get_caps_for_format-simplify-th.patch b/0013-cheese-camera-device-get_caps_for_format-simplify-th.patch
new file mode 100644
index 0000000..906146f
--- /dev/null
+++ b/0013-cheese-camera-device-get_caps_for_format-simplify-th.patch
@@ -0,0 +1,29 @@
+From af213c390521acf0c73a440a8f0ccf42e7393195 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 20:25:44 +0200
+Subject: [PATCH 13/35] cheese-camera-device: get_caps_for_format: simplify the
+ returned caps
+
+This results in much simpler caps, which as main advantage that they are
+way easier to read when trawling to debug logs.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index 273d530..c23069d 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -1004,6 +1004,7 @@ cheese_camera_device_get_caps_for_format (CheeseCameraDevice *device,
+   }
+ 
+   subset_caps = gst_caps_intersect (desired_caps, device->priv->caps);
++  subset_caps = gst_caps_simplify (subset_caps);
+   gst_caps_unref (desired_caps);
+ 
+   GST_INFO ("Got %" GST_PTR_FORMAT, subset_caps);
+-- 
+1.8.2.1
+
diff --git a/0014-cheese-camera-device-Make-get_best_format-smarter.patch b/0014-cheese-camera-device-Make-get_best_format-smarter.patch
new file mode 100644
index 0000000..8288a98
--- /dev/null
+++ b/0014-cheese-camera-device-Make-get_best_format-smarter.patch
@@ -0,0 +1,67 @@
+From 4711194d75b412fe1ba092adbe3101f252ac77fb Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 11:07:37 +0200
+Subject: [PATCH 14/35] cheese-camera-device: Make get_best_format smarter
+
+If we've a device which can do 1600x900 at 10 fps and 1280x800 @ 25 fps,
+then 1600x900 is not really the best format, as 10 fps leads to a bad
+user experience.
+
+So this patch makes get_best_format return the highest resolution at which
+the device can do atleast 15 fps.
+
+Since some (older) cameras may have something like 640x480 @ 10 fps and
+320x240 @ 30 fps as modes, there is an additional check that the mode
+must also have a width of at least 640 pixels.
+
+If no mode matching the widh >= 640 && frame_rate >= 15 criteria is found,
+get_best_format will behave as before as simply return the highest resolution
+mode.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index c23069d..402bbb8 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -935,14 +935,30 @@ cheese_camera_device_get_device_node (CheeseCameraDevice *device)
+ CheeseVideoFormat *
+ cheese_camera_device_get_best_format (CheeseCameraDevice *device)
+ {
+-  CheeseVideoFormat *format;
++  CheeseVideoFormatFull *format = NULL;
++  GList *l;
+ 
+   g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
+ 
+-  format = g_boxed_copy (CHEESE_TYPE_VIDEO_FORMAT, device->priv->formats->data);
++  /* First check for the highest res with width >= 640 and fps >= 15 */
++  for (l = device->priv->formats; l != NULL; l = l->next)
++  {
++    CheeseVideoFormatFull *item = l->data;
++    float frame_rate = (float)item->fr_numerator / (float)item->fr_denominator;
++    if (item->width >= 640 && frame_rate >= 15)
++    {
++      format = item;
++      break;
++    }
++  }
++  /* Else simply return the highest res */
++  if (!format)
++    format = device->priv->formats->data;
++
++  GST_INFO ("%dx%d@%d/%d", format->width, format->height,
++            format->fr_numerator, format->fr_denominator);
+ 
+-  GST_INFO ("%dx%d", format->width, format->height);
+-  return format;
++  return g_boxed_copy (CHEESE_TYPE_VIDEO_FORMAT, format);;
+ }
+ 
+ /**
+-- 
+1.8.2.1
+
diff --git a/0015-cheese-camera-device-Plug-some-memory-leaks.patch b/0015-cheese-camera-device-Plug-some-memory-leaks.patch
new file mode 100644
index 0000000..a055d49
--- /dev/null
+++ b/0015-cheese-camera-device-Plug-some-memory-leaks.patch
@@ -0,0 +1,47 @@
+From 59811406ccd626704a0bb810032c39a089e1965a Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 14:18:52 +0200
+Subject: [PATCH 15/35] cheese-camera-device: Plug some memory leaks
+
+1) If we already have a format in the list, free it
+2) Not only free the formats in the list, but also the actual GList structures
+   themselves
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index 402bbb8..a12b0f7 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -360,6 +360,7 @@ cheese_camera_device_add_format (CheeseCameraDevice *device,
+                                                  (CheeseVideoFormat *)format);
+   if (existing)
+   {
++    g_slice_free (CheeseVideoFormatFull, format);
+     cheese_camera_device_format_update_framerate (existing, framerate);
+     return;
+   }
+@@ -380,7 +381,7 @@ cheese_camera_device_add_format (CheeseCameraDevice *device,
+  * Free the individual #CheeseVideoFormatFull.
+  */
+ static void
+-free_format_list_foreach (gpointer data, G_GNUC_UNUSED gpointer user_data)
++free_format_list_foreach (gpointer data)
+ {
+   g_slice_free (CheeseVideoFormatFull, data);
+ }
+@@ -396,7 +397,7 @@ free_format_list (CheeseCameraDevice *device)
+ {
+   CheeseCameraDevicePrivate *priv = device->priv;
+ 
+-  g_list_foreach (priv->formats, free_format_list_foreach, NULL);
++  g_list_free_full (priv->formats, free_format_list_foreach);
+   priv->formats = NULL;
+ }
+ 
+-- 
+1.8.2.1
+
diff --git a/0016-cheese-camera-Drop-unused-preview_caps.patch b/0016-cheese-camera-Drop-unused-preview_caps.patch
new file mode 100644
index 0000000..5a2dc43
--- /dev/null
+++ b/0016-cheese-camera-Drop-unused-preview_caps.patch
@@ -0,0 +1,26 @@
+From 7cb124b1919198af87013fa5a26d4d11250fbb9f Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 09:22:09 +0200
+Subject: [PATCH 16/35] cheese-camera: Drop unused preview_caps
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index fd5d2bf..eafc381 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -81,8 +81,6 @@ struct _CheeseCameraPrivate
+   GstElement *camera_tee, *effects_tee;
+   GstElement *main_valve, *effects_valve;
+ 
+-  GstCaps *preview_caps;
+-
+   gboolean is_recording;
+   gboolean pipeline_is_playing;
+   gchar *photo_filename;
+-- 
+1.8.2.1
+
diff --git a/0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch b/0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch
new file mode 100644
index 0000000..6e11917
--- /dev/null
+++ b/0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch
@@ -0,0 +1,52 @@
+From 8e50910e9604c5d719397dd3f6a5fccc463eaa35 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 09:05:51 +0200
+Subject: [PATCH 17/35] cheese-camera: Do not add videoconvert elements around
+ the "no effect" effect
+
+The "no effect" effect is our default value, and thus worth optimizing a bit
+for. Clearly in the "no effect" effect case adding a videoconvert element both
+before and after the element is not needed.
+
+Note we also don't add the videoconvert elements when creating the initial
+pipeline, so this also keeps the way the pipeline looks initially and when
+"no-effect" is selected consistent.
+
+When starting cheese with "no-effect" selected, this shaves of another 130ms
+of the initial pipeline creation time, for a total improvement for this patch
+set from aprox 1.1 sec to aprox 220 ms.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index eafc381..7b7fac5 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -888,12 +888,20 @@ void
+ cheese_camera_set_effect (CheeseCamera *camera, CheeseEffect *effect)
+ {
+   GstElement *effect_filter;
++  gchar      *effect_desc;
+ 
+   g_return_if_fail (CHEESE_IS_CAMERA (camera));
+ 
+-  effect_filter = cheese_camera_element_from_effect (camera, effect);
++  g_object_get (G_OBJECT (effect), "pipeline-desc", &effect_desc, NULL);
++
++  if (strcmp(effect_desc, "identity") == 0)
++    effect_filter = gst_element_factory_make ("identity", "effect");
++  else
++    effect_filter = cheese_camera_element_from_effect (camera, effect);
+   if (effect_filter != NULL)
+     cheese_camera_change_effect_filter (camera, effect_filter);
++
++  g_free (effect_desc);
+ }
+ 
+ /**
+-- 
+1.8.2.1
+
diff --git a/0018-cheese-camera-Check-for-the-current-effect-being-the.patch b/0018-cheese-camera-Check-for-the-current-effect-being-the.patch
new file mode 100644
index 0000000..a2bb200
--- /dev/null
+++ b/0018-cheese-camera-Check-for-the-current-effect-being-the.patch
@@ -0,0 +1,81 @@
+From 7f7e1b27e05ce3ba29e409fcf5cb58241ef99067 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 09:35:14 +0200
+Subject: [PATCH 18/35] cheese-camera: Check for the current effect being the
+ same as the one set
+
+And if so, turn the cheese_camera_set_effect call into a nop.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 7b7fac5..9cfaf7e 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -80,6 +80,7 @@ struct _CheeseCameraPrivate
+   GstElement *video_balance;
+   GstElement *camera_tee, *effects_tee;
+   GstElement *main_valve, *effects_valve;
++  gchar *current_effect_desc;
+ 
+   gboolean is_recording;
+   gboolean pipeline_is_playing;
+@@ -587,6 +588,7 @@ cheese_camera_create_video_filter_bin (CheeseCamera *camera, GError **error)
+     cheese_camera_set_error_element_not_found (error, "identity");
+     return FALSE;
+   }
++  priv->current_effect_desc = g_strdup("identity");
+   if ((priv->video_balance = gst_element_factory_make ("videobalance", "video_balance")) == NULL)
+   {
+     cheese_camera_set_error_element_not_found (error, "videobalance");
+@@ -887,19 +889,36 @@ cheese_camera_element_from_effect (CheeseCamera *camera, CheeseEffect *effect)
+ void
+ cheese_camera_set_effect (CheeseCamera *camera, CheeseEffect *effect)
+ {
++  CheeseCameraPrivate *priv;
+   GstElement *effect_filter;
+   gchar      *effect_desc;
+ 
+   g_return_if_fail (CHEESE_IS_CAMERA (camera));
+ 
++  priv = camera->priv;
++
+   g_object_get (G_OBJECT (effect), "pipeline-desc", &effect_desc, NULL);
+ 
++  if (strcmp(priv->current_effect_desc, effect_desc) == 0)
++  {
++    GST_INFO_OBJECT (camera, "Effect is: \"%s\", not updating", effect_desc);
++    g_free (effect_desc);
++    return;
++  }
++
++  GST_INFO_OBJECT (camera, "Changing effect to: \"%s\"", effect_desc);
++
+   if (strcmp(effect_desc, "identity") == 0)
+     effect_filter = gst_element_factory_make ("identity", "effect");
+   else
+     effect_filter = cheese_camera_element_from_effect (camera, effect);
+   if (effect_filter != NULL)
++  {
+     cheese_camera_change_effect_filter (camera, effect_filter);
++    g_free (priv->current_effect_desc);
++    priv->current_effect_desc = effect_desc;
++    return;
++  }
+ 
+   g_free (effect_desc);
+ }
+@@ -1202,6 +1221,7 @@ cheese_camera_finalize (GObject *object)
+ 
+   if (priv->photo_filename)
+     g_free (priv->photo_filename);
++  g_free (priv->current_effect_desc);
+   g_free (priv->device_node);
+   g_boxed_free (CHEESE_TYPE_VIDEO_FORMAT, priv->current_format);
+ 
+-- 
+1.8.2.1
+
diff --git a/0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch b/0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch
new file mode 100644
index 0000000..68c50d2
--- /dev/null
+++ b/0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch
@@ -0,0 +1,30 @@
+From 39c02d60193596a61c00cdc5b5952a425bb5e34b Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 13:14:14 +0200
+Subject: [PATCH 19/35] cheese-camera: Don't block the main valve while
+ recording
+
+Otherwise we end up dropping frames intended for the recording.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 9cfaf7e..2dc5655 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -942,7 +942,8 @@ cheese_camera_toggle_effects_pipeline (CheeseCamera *camera, gboolean active)
+   if (active)
+   {
+     g_object_set (G_OBJECT (priv->effects_valve), "drop", FALSE, NULL);
+-    g_object_set (G_OBJECT (priv->main_valve), "drop", TRUE, NULL);
++    if (!priv->is_recording)
++      g_object_set (G_OBJECT (priv->main_valve), "drop", TRUE, NULL);
+   }
+   else
+   {
+-- 
+1.8.2.1
+
diff --git a/0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch b/0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch
new file mode 100644
index 0000000..143bc75
--- /dev/null
+++ b/0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch
@@ -0,0 +1,119 @@
+From 5cb470a89ed733ef7b0db3c534d1ce6e76648fae Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 16:16:23 +0200
+Subject: [PATCH 20/35] cheese-camera: Downscale image for effects-preview
+ pipeline
+
+Having the whole effects-preview bin deal with ie 1280x800 images is not very
+useful, esp since even when fullscreen on a full-hd monitor, the preview images
+are smaller then 640xXXX. This useless high-res processing for 9 preview images
+in paralellel brings my 2nd gen core i5 @ 3.1 GHz to its knees, resulting in a
+non fluid preview panel.
+
+Also after clicking through all effect preview pages, so that all effect
+preview textures are connected, cheese will use 1GB of *resident* ram with
+the example 1280x800 capture resolution.
+
+This patch fixes this by downscaling the images from the video-source to
+640xXXX where XXX is determined by the original resolution aspect-ratio.
+
+After this patch the effects preview framerate is much smoother, and the
+latency is noticably less. And as a bonus the maximal resident size of cheese
+in this example is reduced to 350 MB.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 42 ++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 34 insertions(+), 8 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 2dc5655..31348d2 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -76,7 +76,7 @@ struct _CheeseCameraPrivate
+ 
+   ClutterTexture *video_texture;
+ 
+-  GstElement *effect_filter;
++  GstElement *effect_filter, *effects_capsfilter;
+   GstElement *video_balance;
+   GstElement *camera_tee, *effects_tee;
+   GstElement *main_valve, *effects_valve;
+@@ -517,27 +517,39 @@ cheese_camera_create_effects_preview_bin (CheeseCamera *camera, GError **error)
+   CheeseCameraPrivate *priv = camera->priv;
+ 
+   gboolean ok = TRUE;
++  GstElement *scale;
+   GstPad  *pad;
+ 
+   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ 
+   priv->effects_preview_bin = gst_bin_new ("effects_preview_bin");
+ 
+-  if ((priv->effects_tee = gst_element_factory_make ("tee", "effects_tee")) == NULL)
++  if ((priv->effects_valve = gst_element_factory_make ("valve", "effects_valve")) == NULL)
+   {
+-    cheese_camera_set_error_element_not_found (error, "tee");
++    cheese_camera_set_error_element_not_found (error, "effects_valve");
+     return FALSE;
+   }
+-  if ((priv->effects_valve = gst_element_factory_make ("valve", "effects_valve")) == NULL)
++  if ((scale = gst_element_factory_make ("videoscale", "effects_scale")) == NULL)
+   {
+-    cheese_camera_set_error_element_not_found (error, "effects_valve");
++    cheese_camera_set_error_element_not_found (error, "videoscale");
++    return FALSE;
++  }
++  if ((priv->effects_capsfilter = gst_element_factory_make ("capsfilter", "effects_capsfilter")) == NULL)
++  {
++    cheese_camera_set_error_element_not_found (error, "capsfilter");
++    return FALSE;
++  }
++  if ((priv->effects_tee = gst_element_factory_make ("tee", "effects_tee")) == NULL)
++  {
++    cheese_camera_set_error_element_not_found (error, "tee");
+     return FALSE;
+   }
+ 
+-  gst_bin_add_many (GST_BIN (priv->effects_preview_bin),
+-		    priv->effects_valve, priv->effects_tee, NULL);
++  gst_bin_add_many (GST_BIN (priv->effects_preview_bin), priv->effects_valve,
++                    scale, priv->effects_capsfilter, priv->effects_tee, NULL);
+ 
+-  ok &= gst_element_link_many (priv->effects_valve, priv->effects_tee, NULL);
++  ok &= gst_element_link_many (priv->effects_valve, scale,
++                           priv->effects_capsfilter, priv->effects_tee, NULL);
+ 
+   /* add ghostpads */
+ 
+@@ -723,6 +735,8 @@ cheese_camera_set_new_caps (CheeseCamera *camera)
+   CheeseCameraPrivate *priv;
+   CheeseCameraDevice *device;
+   GstCaps *caps;
++  gchar *caps_desc;
++  int width, height;
+ 
+   g_return_if_fail (CHEESE_IS_CAMERA (camera));
+ 
+@@ -746,6 +760,18 @@ cheese_camera_set_new_caps (CheeseCamera *camera)
+     g_object_set (priv->camerabin, "viewfinder-caps", caps, NULL);
+     g_object_set (priv->camerabin, "image-capture-caps", caps, NULL);
+     g_object_set (priv->camerabin, "video-capture-caps", caps, NULL);
++    gst_caps_unref (caps);
++
++    width = priv->current_format->width;
++    width = width > 640 ? 640 : width;
++    height = width * priv->current_format->height / priv->current_format->width;
++    /* !! Gstreamer will crash if this is not a multiple of 2 !! */
++    height = (height + 1) & ~1;
++    caps_desc = g_strdup_printf ("video/x-raw, width=%d, height=%d",
++                                 width, height);
++    caps = gst_caps_from_string (caps_desc);
++    g_free (caps_desc);
++    g_object_set (priv->effects_capsfilter, "caps", caps, NULL);
+   }
+   gst_caps_unref (caps);
+ }
+-- 
+1.8.2.1
+
diff --git a/0021-cheese-window-Fix-de-activation-of-effects-button.patch b/0021-cheese-window-Fix-de-activation-of-effects-button.patch
new file mode 100644
index 0000000..d328d14
--- /dev/null
+++ b/0021-cheese-window-Fix-de-activation-of-effects-button.patch
@@ -0,0 +1,51 @@
+From 775c5d479d47c96a1a0e78a852ec31418809c0dc Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 12:51:09 +0200
+Subject: [PATCH 21/35] cheese-window: Fix de-activation of effects button
+
+So that the user does not need to click twice on the effect button to change
+the effect (after the first time the effect was changed).
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-window.vala | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 70293aa..9ebb5e1 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -895,7 +895,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+       else
+       if (is_effects_selector_active)
+       {
+-        // FIXME: Set the effects action to be inactive.
++        effects_toggle_button.set_active (false);
+       }
+     }
+     return false;
+@@ -1031,7 +1031,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+     public void set_effects (bool effects)
+     {
+         toggle_effects_selector (effects);
+-        // FIXME: Set the mode action to be inverse sensitivity to effects.
+     }
+ 
+   /**
+@@ -1045,12 +1044,11 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+                                          Clutter.ButtonEvent event)
+   {
+     /* Disable the effects selector after selecting an effect. */
+-    toggle_effects_selector(false);
++    effects_toggle_button.set_active (false);
+ 
+     selected_effect = source.get_data ("effect");
+     camera.set_effect (selected_effect);
+     settings.set_string ("selected-effect", selected_effect.name);
+-    // FIXME: Set the effects action to be inactive.
+     return false;
+   }
+ 
+-- 
+1.8.2.1
+
diff --git a/0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch b/0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch
new file mode 100644
index 0000000..872413c
--- /dev/null
+++ b/0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch
@@ -0,0 +1,98 @@
+From 113a466ab26633d765cb76461ef8a63b0fa86911 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 13:09:39 +0200
+Subject: [PATCH 22/35] cheese-window: Make mode-toggle and effects button
+ inactive when recording
+
+While at it also fixup the indentation of enable_mode_change / disable, to
+be 2 spaces like most other code in cheese-window.vala.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-window.vala | 44 +++++++++++++++++++++++++++++++-------------
+ 1 file changed, 31 insertions(+), 13 deletions(-)
+
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 9ebb5e1..e8ccb47 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -95,6 +95,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+   private bool is_command_line_startup;
+ 
+   private Gtk.Button[] buttons;
++  private Gtk.Button[] mode_buttons;
+ 
+   private Cheese.Camera   camera;
+   private Cheese.FileUtil fileutil;
+@@ -527,23 +528,37 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+         set_fullscreen_mode (fullscreen);
+     }
+ 
+-    /**
+-     * Make the media capture mode actions sensitive.
+-     */
+-    private void enable_mode_change ()
++  /**
++   * Make the media capture mode actions sensitive.
++   */
++  private void enable_mode_change ()
++  {
++    foreach (Gtk.Button b in mode_buttons)
+     {
+-        // FIXME: Set the mode action to be sensitive
+-        // FIXME: Set the effects action to be sensitive.
++      b.sensitive = true;
+     }
++    effects_toggle_button.sensitive = true;
++  }
+ 
+-    /**
+-     * Make the media capture mode actions insensitive.
+-     */
+-    private void disable_mode_change ()
++  /**
++   * Make the media capture mode actions insensitive.
++   */
++  private void disable_mode_change ()
++  {
++    foreach (Gtk.Button b in mode_buttons)
+     {
+-        // FIXME: Set the mode action to be sensitive
+-        // FIXME: Set the effects action to be insensitive.
++      b.sensitive = false;
+     }
++    /* Allow changing the effects while recording a video */
++    if (current_mode != MediaMode.VIDEO)
++    {
++      effects_toggle_button.sensitive = false;
++      if (is_effects_selector_active)
++      {
++        effects_toggle_button.set_active (false);
++      }
++    }
++  }
+ 
+   /**
+    * Set the capture resolution, based on the current capture mode.
+@@ -966,7 +981,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+     {
+       is_bursting = true;
+       this.disable_mode_change ();
+-      // FIXME: Set the effects action to be inactive.
+       take_action_button_label.label  = "<b>" + _("Stop _Taking Pictures") + "</b>";
+       take_action_button.tooltip_text = _("Stop taking pictures");
+       burst_take_photo ();
+@@ -1416,6 +1430,10 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+                effects_toggle_button,
+                leave_fullscreen_button};
+ 
++    mode_buttons = {photo_toggle_button,
++                    video_toggle_button,
++                    burst_toggle_button};
++
+     video_preview           = clutter_builder.get_object ("video_preview") as Clutter.Texture;
+     viewport_layout         = clutter_builder.get_object ("viewport_layout") as Clutter.Box;
+     viewport_layout_manager = clutter_builder.get_object ("viewport_layout_manager") as Clutter.BinLayout;
+-- 
+1.8.2.1
+
diff --git a/0023-libcheese-Add-_init_with_args-init-function-variants.patch b/0023-libcheese-Add-_init_with_args-init-function-variants.patch
new file mode 100644
index 0000000..661796b
--- /dev/null
+++ b/0023-libcheese-Add-_init_with_args-init-function-variants.patch
@@ -0,0 +1,213 @@
+From e7b7314b5af40aaf9aa2a782a1fd025f2e08345e Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 12:07:20 +0200
+Subject: [PATCH 23/35] libcheese: Add _init_with_args init function variants
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ docs/reference/cheese-sections.txt |  2 ++
+ libcheese/cheese-gtk.c             | 57 ++++++++++++++++++++++++++++++++++++++
+ libcheese/cheese-gtk.h             |  5 ++++
+ libcheese/cheese-gtk.symbols       |  1 +
+ libcheese/cheese.c                 | 25 +++++++++++++++++
+ libcheese/cheese.h                 |  5 ++++
+ src/vapi/cheese-common.vapi        | 14 ++++++++++
+ 7 files changed, 109 insertions(+)
+
+diff --git a/docs/reference/cheese-sections.txt b/docs/reference/cheese-sections.txt
+index 81e835c..bed1e75 100644
+--- a/docs/reference/cheese-sections.txt
++++ b/docs/reference/cheese-sections.txt
+@@ -2,12 +2,14 @@
+ <FILE>cheese-init</FILE>
+ <TITLE>Initializing libcheese</TITLE>
+ cheese_init
++cheese_init_with_args
+ </SECTION>
+ 
+ <SECTION>
+ <FILE>cheese-gtk-init</FILE>
+ <TITLE>Initializing libcheese-gtk</TITLE>
+ cheese_gtk_init
++cheese_gtk_init_with_args
+ </SECTION>
+ 
+ <SECTION>
+diff --git a/libcheese/cheese-gtk.c b/libcheese/cheese-gtk.c
+index f6f7715..008ebef 100644
+--- a/libcheese/cheese-gtk.c
++++ b/libcheese/cheese-gtk.c
+@@ -18,6 +18,7 @@
+  */
+ 
+ #include <gtk/gtk.h>
++#include <gst/gst.h>
+ #ifdef GDK_WINDOWING_X11
+   #include <X11/Xlib.h>
+ #endif
+@@ -65,3 +66,59 @@ cheese_gtk_init (int *argc, char ***argv)
+ 
+     return TRUE;
+ }
++
++/**
++ * cheese_gtk_init_with_args:
++ * @argc: pointer to the argument list count
++ * @argv: pointer to the argument list vector
++ * @parameter_string:  string which is displayed in the first line of --help
++ * output, after programname [OPTION...]
++ * @entries: a NULL-terminated array of GOptionEntries describing the options
++ * of your program
++ * @translation_domain: a translation domain to use for translating the
++ * --help output for the options in entries with gettext(), or NULL
++ * @error: a return location for errors
++ *
++ * Initialize libcheese-gtk, by initializing Clutter, GStreamer and GTK+. This
++ * automatically calls cheese_init_with_args(), initializing libcheese.
++ *
++ * Returns: %TRUE if the initialization was successful, %FALSE otherwise
++ */
++gboolean
++cheese_gtk_init_with_args (int *argc, char ***argv,
++                           const char *parameter_string,
++                           GOptionEntry *entries,
++                           const char *translation_domain,
++                           GError **error)
++{
++    GOptionContext *context;
++    gboolean res;
++
++#ifdef GDK_WINDOWING_X11
++    /* We can't call clutter_gst_init() before gtk_clutter_init(), so no
++     * choice but to initialise X11 threading ourself */
++    XInitThreads ();
++#endif
++
++    /* We cannot simply call gtk_clutter_init_with_args() here, since that
++     * will result in the commandline being parsed without gst support. */
++    context = g_option_context_new (parameter_string);
++    g_option_context_add_main_entries (context, entries, translation_domain);
++    g_option_context_set_translation_domain (context, translation_domain);
++    g_option_context_add_group (context, gst_init_get_option_group ());
++    g_option_context_add_group (context, gtk_get_option_group (TRUE));
++    g_option_context_add_group (context, cogl_get_option_group ());
++    g_option_context_add_group (context,
++        clutter_get_option_group_without_init ());
++    g_option_context_add_group (context, gtk_clutter_get_option_group ());
++
++    res = g_option_context_parse (context, argc, argv, error);
++
++    g_option_context_free (context);
++
++    if (!res)
++        return FALSE;
++
++    return cheese_init_with_args (argc, argv, parameter_string, entries,
++                                  translation_domain, error);
++}
+diff --git a/libcheese/cheese-gtk.h b/libcheese/cheese-gtk.h
+index 77640e2..1a4f1b8 100644
+--- a/libcheese/cheese-gtk.h
++++ b/libcheese/cheese-gtk.h
+@@ -25,6 +25,11 @@
+ G_BEGIN_DECLS
+ 
+ gboolean cheese_gtk_init (int *argc, char ***argv);
++gboolean cheese_gtk_init_with_args (int *argc, char ***argv,
++                                    const char *parameter_string,
++                                    GOptionEntry *entries,
++                                    const char *translation_domain,
++                                    GError **error);
+ 
+ G_END_DECLS
+ 
+diff --git a/libcheese/cheese-gtk.symbols b/libcheese/cheese-gtk.symbols
+index fc43faf..a207c3d 100644
+--- a/libcheese/cheese-gtk.symbols
++++ b/libcheese/cheese-gtk.symbols
+@@ -1,4 +1,5 @@
+ cheese_gtk_init
++cheese_gtk_init_with_args
+ cheese_widget_get_type
+ cheese_widget_new
+ cheese_widget_get_camera
+diff --git a/libcheese/cheese.c b/libcheese/cheese.c
+index 0393562..fcab5a8 100644
+--- a/libcheese/cheese.c
++++ b/libcheese/cheese.c
+@@ -52,3 +52,28 @@ cheese_init (int *argc, char ***argv)
+ 
+     return TRUE;
+ }
++
++/**
++ * cheese_init_with_args:
++ * @argc: pointer to the argument list count
++ * @argv: pointer to the argument list vector
++ * @parameter_string:  string which is displayed in the first line of --help
++ * output, after programname [OPTION...]
++ * @entries: a NULL-terminated array of GOptionEntries describing the options
++ * of your program
++ * @translation_domain: a translation domain to use for translating the
++ * --help output for the options in entries with gettext(), or NULL
++ * @error: a return location for errors
++ *
++ * Initialize libcheese, by initializing Clutter and GStreamer.
++ *
++ * Returns: %TRUE if the initialization was successful, %FALSE otherwise
++ */
++gboolean
++cheese_init_with_args (int *argc, char ***argv, const char *parameter_string,
++                       GOptionEntry *entries, const char *translation_domain,
++                       GError **error)
++{
++    return clutter_gst_init_with_args (argc, argv, parameter_string, entries,
++                translation_domain, error) == CLUTTER_INIT_SUCCESS;
++}
+diff --git a/libcheese/cheese.h b/libcheese/cheese.h
+index ec3239f..0f6e06c 100644
+--- a/libcheese/cheese.h
++++ b/libcheese/cheese.h
+@@ -25,6 +25,11 @@
+ G_BEGIN_DECLS
+ 
+ gboolean cheese_init (int *argc, char ***argv);
++gboolean cheese_init_with_args (int *argc, char ***argv,
++                                const char *parameter_string,
++                                GOptionEntry *entries,
++                                const char *translation_domain,
++                                GError **error);
+ 
+ G_END_DECLS
+ 
+diff --git a/src/vapi/cheese-common.vapi b/src/vapi/cheese-common.vapi
+index 075b594..e4d4bec 100644
+--- a/src/vapi/cheese-common.vapi
++++ b/src/vapi/cheese-common.vapi
+@@ -6,9 +6,23 @@ namespace Cheese
+   [CCode (cheader_filename = "cheese.h")]
+   public static bool init([CCode (array_length_pos = 0.9)] ref unowned string[] argv);
+ 
++  [CCode (cheader_filename = "cheese.h")]
++  public static bool init_with_args(
++    [CCode (array_length_pos = 0.9)] ref unowned string[] argv,
++    string parameter_string,
++    [CCode (array_length = false)] GLib.OptionEntry[] entries,
++    string? translation_domain) throws GLib.OptionError;
++
+   [CCode (cheader_filename = "cheese-gtk.h")]
+   public static bool gtk_init([CCode (array_length_pos = 0.9)] ref unowned string[] argv);
+ 
++  [CCode (cheader_filename = "cheese-gtk.h")]
++  public static bool gtk_init_with_args(
++    [CCode (array_length_pos = 0.9)] ref unowned string[] argv,
++    string parameter_string,
++    [CCode (array_length = false)] GLib.OptionEntry[] entries,
++    string? translation_domain) throws GLib.OptionError;
++
+   [CCode (cheader_filename = "cheese-effect.h")]
+   public class Effect : GLib.Object
+   {
+-- 
+1.8.2.1
+
diff --git a/0024-cheese-Use-cheese_gtk_init_with_args.patch b/0024-cheese-Use-cheese_gtk_init_with_args.patch
new file mode 100644
index 0000000..4f1d063
--- /dev/null
+++ b/0024-cheese-Use-cheese_gtk_init_with_args.patch
@@ -0,0 +1,196 @@
+From 5bcbdb44dd1cd4f0ed0a69a92a27634616e8df3e Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 13:28:11 +0200
+Subject: [PATCH 24/35] cheese: Use cheese_gtk_init_with_args
+
+Currently our --help output only shows gstreamer related info:
+
+[hans at shalem cheese]$ cheese --help
+Usage:
+  cheese [OPTION...] - GStreamer initialization
+
+Help Options:
+  -h, --help                        Show help options
+  --help-all                        Show all help options
+  --help-gst                        Show GStreamer Options
+
+This is caused by this gstreamer bug:
+https://bugzilla.gnome.org/show_bug.cgi?id=702089
+
+Besides suffering from this bug, our commandline parsing code also is not
+exactly pretty, and not a good example of how to do commandline parsing
+for other libcheese using applications.
+
+Also adding all the various option_groups manually is rather error prone
+ie currently the cogl group is missing.
+
+This patch fixes all this (including working around the --help issue)
+by using cheese_gtk_init_with_args, resulting in much simpler code.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 124 +++++++++++++--------------------------------------
+ 1 file changed, 30 insertions(+), 94 deletions(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index ac5ba6f..5905597 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -24,12 +24,21 @@ using Gtk;
+ using Clutter;
+ using Gst;
+ 
++static bool wide;
++static string device;
++static bool version;
++static bool fullscreen;
++
++const OptionEntry[] options = {
++  {"wide",       'w', 0, OptionArg.NONE,     ref wide,       N_("Start in wide mode"),                  null        },
++  {"device",     'd', 0, OptionArg.FILENAME, ref device,     N_("Device to use as a camera"),           N_("DEVICE")},
++  {"version",    'v', 0, OptionArg.NONE,     ref version,    N_("Output version information and exit"), null        },
++  {"fullscreen", 'f', 0, OptionArg.NONE,     ref fullscreen, N_("Start in fullscreen mode"),            null        },
++  {null}
++};
++
+ public class Cheese.Main : Gtk.Application
+ {
+-    static bool wide;
+-    static string device;
+-    static bool version;
+-    static bool fullscreen;
+ 
+     static MainWindow main_window;
+ 
+@@ -47,14 +56,6 @@ public class Cheese.Main : Gtk.Application
+         { "quit", on_quit }
+     };
+ 
+-  const OptionEntry[] options = {
+-    {"wide",       'w', 0, OptionArg.NONE,     ref wide,       N_("Start in wide mode"),                  null        },
+-    {"device",     'd', 0, OptionArg.FILENAME, ref device,     N_("Device to use as a camera"),           N_("DEVICE")},
+-    {"version",    'v', 0, OptionArg.NONE,     ref version,    N_("Output version information and exit"), null        },
+-    {"fullscreen", 'f', 0, OptionArg.NONE,     ref fullscreen, N_("Start in fullscreen mode"),            null        },
+-    {null}
+-  };
+-
+   public Main (string app_id, ApplicationFlags flags)
+   {
+     GLib.Object (application_id: app_id, flags: flags);
+@@ -140,87 +141,6 @@ public class Cheese.Main : Gtk.Application
+     }
+   }
+ 
+-  /**
+-   * Overridden method of GApplication, to handle the arguments locally.
+-   *
+-   * @param arguments the command-line arguments
+-   * @param exit_status the exit status to return to the OS
+-   * @return true if the arguments were successfully processed, false otherwise
+-   */
+-  public override bool local_command_line ([CCode (array_null_terminated = true, array_length = false)]
+-                                           ref unowned string[] arguments,
+-                                           out int exit_status)
+-  {
+-    // Try to register.
+-    try
+-    {
+-      register();
+-    }
+-    catch (Error e)
+-    {
+-      stdout.printf ("Error: %s\n", e.message);
+-      exit_status = 1;
+-      return true;
+-    }
+-
+-    // Workaround until bug 642885 is solved.
+-    unowned string[] local_args = arguments;
+-
+-    // Check command line parameters.
+-    int n_args = local_args.length;
+-    if (n_args <= 1)
+-    {
+-      Gst.init (ref local_args);
+-      activate ();
+-      exit_status = 0;
+-    }
+-    else
+-    {
+-      // Set parser.
+-      try
+-      {
+-        var context = new OptionContext (_("- Take photos and videos from your webcam"));
+-        context.set_translation_domain (Config.GETTEXT_PACKAGE);
+-        context.set_help_enabled (true);
+-        context.add_main_entries (options, null);
+-        context.add_group (Gtk.get_option_group (true));
+-        context.add_group (Clutter.get_option_group ());
+-        context.add_group (Gst.init_get_option_group ());
+-        context.parse (ref local_args);
+-      }
+-      catch (OptionError e)
+-      {
+-        stdout.printf ("%s\n", e.message);
+-        stdout.printf (_("Run '%s --help' to see a full list of available command line options.\n"), arguments[0]);
+-        exit_status = 1;
+-        return true;
+-      }
+-
+-      if (version)
+-      {
+-        stdout.printf ("%s %s\n", Config.PACKAGE_NAME, Config.PACKAGE_VERSION);
+-        exit_status = 1;
+-        return true;
+-      }
+-
+-      //Remote instance process commands locally.
+-      if (get_is_remote ())
+-      {
+-          stdout.printf (_("Another instance of Cheese is currently running\n"));
+-          exit_status = 1;
+-          return true;
+-      }
+-      //Primary instance.
+-      else
+-      {
+-        Gst.init (ref local_args);
+-        activate ();
+-        exit_status=0;
+-      }
+-    }
+-    return true;
+-  }
+-
+     /**
+      * Setup the camera listed in GSettings.
+      *
+@@ -543,8 +463,24 @@ public class Cheese.Main : Gtk.Application
+     Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8");
+     Intl.textdomain (Config.GETTEXT_PACKAGE);
+ 
+-    if (!Cheese.gtk_init (ref args))
++    try
++    {
++      Cheese.gtk_init_with_args (ref args,
++                            _("- Take photos and videos from your webcam"),
++                            options, Config.GETTEXT_PACKAGE);
++    }
++    catch (OptionError e)
++    {
++      stdout.printf ("%s\n", e.message);
++      stdout.printf (_("Run '%s --help' to see a full list of available command line options.\n"), args[0]);
+       return Posix.EXIT_FAILURE;
++    }
++
++    if (version)
++    {
++      stdout.printf ("%s %s\n", Config.PACKAGE_NAME, Config.PACKAGE_VERSION);
++      return Posix.EXIT_SUCCESS;
++    }
+ 
+     Cheese.Main app;
+     app = new Cheese.Main ("org.gnome.Cheese", ApplicationFlags.FLAGS_NONE);
+-- 
+1.8.2.1
+
diff --git a/0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch b/0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch
new file mode 100644
index 0000000..6e18eaa
--- /dev/null
+++ b/0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch
@@ -0,0 +1,206 @@
+From 29a1bab965e67b39eb0eef44038a1400d6de6029 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 17:26:25 +0200
+Subject: [PATCH 25/35] cheese: Remove last remnants of the old menu code
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ data/cheese-actions.ui | 18 -----------
+ src/cheese-window.vala | 85 +++++++++++++++++---------------------------------
+ 2 files changed, 29 insertions(+), 74 deletions(-)
+
+diff --git a/data/cheese-actions.ui b/data/cheese-actions.ui
+index 2374c36..8657c08 100644
+--- a/data/cheese-actions.ui
++++ b/data/cheese-actions.ui
+@@ -46,24 +46,6 @@
+           </object>
+           <accelerator key="Delete" modifiers="GDK_SHIFT_MASK"/>
+         </child>
+-        <child>
+-          <object class="GtkAction" id="move_all_to_trash">
+-            <property name="name">RemoveAll</property>
+-            <property name="label" translatable="yes">Move _All to Trash</property>
+-            <signal name="activate" handler="cheese_main_window_on_file_move_to_trash_all"/>
+-          </object>
+-        </child>
+-      </object>
+-    </child>
+-    <child>
+-      <object class="GtkActionGroup" id="layout_actions">
+-        <child>
+-          <object class="GtkToggleAction" id="wide_mode">
+-            <property name="name">WideMode</property>
+-            <property name="label" translatable="yes">_Wide Mode</property>
+-            <signal name="toggled" handler="cheese_main_window_on_layout_wide_mode"/>
+-          </object>
+-        </child>
+       </object>
+     </child>
+     <child>
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index e8ccb47..6425a7f 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -79,7 +79,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+   private List<Clutter.Box> effects_grids;
+ 
+   private HashTable<string, bool> action_sensitivities;
+-  private Gtk.ToggleAction wide_mode_action;
+   private Gtk.Action       countdown_action;
+   private Gtk.Action       effects_page_prev_action;
+   private Gtk.Action       effects_page_next_action;
+@@ -494,41 +493,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+   }
+ 
+   /**
+-   * Toggle wide mode and save the preference to GSettings.
+-   *
+-   * @param action the action that emitted the signal
+-   */
+-  [CCode (instance_pos = -1)]
+-  public void on_layout_wide_mode (ToggleAction action)
+-  {
+-    if (!is_command_line_startup)
+-    {
+-     /* Don't save to settings when using -w mode from command-line, so
+-      * command-line options change the mode for one run only. */
+-      settings.set_boolean ("wide-mode", action.active);
+-    }
+-    set_wide_mode (action.active);
+-  }
+-
+-    /**
+-     * Toggle fullscreen mode and save the preference to GSettings.
+-     *
+-     * @param fullscreen whether the window should be fullscreean
+-     */
+-    [CCode (instance_pos = -1)]
+-    public void set_fullscreen (bool fullscreen)
+-    {
+-        if (!is_command_line_startup)
+-        {
+-            /* Don't save to settings when using -f mode from command-line, so
+-             * command-line options change the mode for one run only. */
+-            settings.set_boolean ("fullscreen", fullscreen);
+-        }
+-
+-        set_fullscreen_mode (fullscreen);
+-    }
+-
+-  /**
+    * Make the media capture mode actions sensitive.
+    */
+   private void enable_mode_change ()
+@@ -657,19 +621,28 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+   }
+ 
+   /**
+-   * Enable or disable fullscreen mode to the requested state.
++   * Enable or disable fullscreen mode
+    *
+-   * @param fullscreen_mode whether to enable or disable fullscreen mode
++   * @param fullscreen whether the window should be fullscreean
+    */
+-  private void set_fullscreen_mode (bool fullscreen_mode)
++  [CCode (instance_pos = -1)]
++  public void set_fullscreen (bool fullscreen)
+   {
+     /* After the first time the window has been shown using this.show_all (),
+      * the value of leave_fullscreen_button_container.no_show_all should be set to false
+      * So that the next time leave_fullscreen_button_container.show_all () is called, the button is actually shown
+      * FIXME: If this code can be made cleaner/clearer, please do */
+ 
+-    is_fullscreen = fullscreen_mode;
+-    if (fullscreen_mode)
++    is_fullscreen = fullscreen;
++
++    if (!is_command_line_startup)
++    {
++      /* Don't save to settings when using -f mode from command-line, so
++       * command-line options change the mode for one run only. */
++      settings.set_boolean ("fullscreen", is_fullscreen);
++    }
++
++    if (is_fullscreen)
+     {
+       if (is_wide_mode)
+       {
+@@ -722,14 +695,23 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+   }
+ 
+   /**
+-   * Enable or disable wide mode to the requested state.
++   * Enable or disable wide mode to the requested state and save the
++   * preference to GSettings.
+    *
+    * @param wide_mode whether to enable or disable wide mode
+    */
+-  private void set_wide_mode (bool wide_mode)
++  [CCode (instance_pos = -1)]
++  public void set_wide_mode (bool wide_mode)
+   {
+     is_wide_mode = wide_mode;
+ 
++    if (!is_command_line_startup)
++    {
++     /* Don't save to settings when using -w mode from command-line, so
++      * command-line options change the mode for one run only. */
++      settings.set_boolean ("wide-mode", is_wide_mode);
++    }
++
+     /* keep the viewport to its current size while rearranging the ui,
+      * so that thumbview moves from right to bottom and viceversa
+      * while the rest of the window stays unchanged */
+@@ -1298,13 +1280,12 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ 
+           /* Keep only these actions sensitive. */
+           string [] active_actions = { "quit",
+-                                       "help_contents",
++                                       "help",
+                                        "about",
+                                        "open",
+                                        "save_as",
+                                        "move_to_trash",
+-                                       "delete",
+-                                       "move_all_to_trash"};
++                                       "delete"};
+ 
+           /* Gross hack because Vala's `in` operator doesn't really work */
+           bool flag;
+@@ -1358,7 +1339,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+     }
+ 
+     is_command_line_startup = true;
+-    wide_mode_action.set_active (true);
++    set_wide_mode (true);
+     is_command_line_startup = false;
+   }
+ 
+@@ -1414,7 +1395,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+     thumbnail_popup                   = gtk_builder.get_object ("thumbnail_popup") as Gtk.Menu;
+ 
+     countdown_action         = gtk_builder.get_object ("countdown") as Gtk.Action;
+-    wide_mode_action         = gtk_builder.get_object ("wide_mode") as Gtk.ToggleAction;
+     effects_page_next_action = gtk_builder.get_object ("effects_page_next") as Gtk.Action;
+     effects_page_prev_action = gtk_builder.get_object ("effects_page_prev") as Gtk.Action;
+     share_action             = gtk_builder.get_object ("share") as Gtk.Action;
+@@ -1477,14 +1457,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+      * if the widget is not realized */
+     viewport_widget.realize ();
+ 
+-    /* call set_active instead of our set_wide_mode so that the toggle
+-     * action state is updated */
+-    wide_mode_action.set_active (settings.get_boolean ("wide-mode"));
+-
+-    /* apparently set_active doesn't emit toggled nothing has
+-     * changed, do it manually */
+-    if (!settings.get_boolean ("wide-mode"))
+-      wide_mode_action.toggled ();
++    set_wide_mode (settings.get_boolean ("wide-mode"));
+ 
+     set_mode (MediaMode.PHOTO);
+     setup_effects_selector ();
+-- 
+1.8.2.1
+
diff --git a/0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch b/0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch
new file mode 100644
index 0000000..5413575
--- /dev/null
+++ b/0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch
@@ -0,0 +1,52 @@
+From b0bdc5489ab2476bac63fcf2919f92efe743c828 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 17:54:02 +0200
+Subject: [PATCH 26/35] cheese: Protect set_wide_mode / set_fullscreen against
+ double calls
+
+Make it safe to call set_wide_mode / set_fullscreen twice with the same
+value.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-window.vala | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 6425a7f..906105b 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -86,6 +86,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ 
+   private bool is_fullscreen;
+   private bool is_wide_mode;
++  private bool is_wide_mode_initialized;
+   private bool is_recording;       /* Video Recording Flag */
+   private bool is_bursting;
+   private bool is_effects_selector_active;
+@@ -633,6 +634,10 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+      * So that the next time leave_fullscreen_button_container.show_all () is called, the button is actually shown
+      * FIXME: If this code can be made cleaner/clearer, please do */
+ 
++    if (is_fullscreen == fullscreen)
++    {
++      return;
++    }
+     is_fullscreen = fullscreen;
+ 
+     if (!is_command_line_startup)
+@@ -703,6 +708,11 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+   [CCode (instance_pos = -1)]
+   public void set_wide_mode (bool wide_mode)
+   {
++    if (is_wide_mode_initialized && is_wide_mode == wide_mode)
++    {
++      return;
++    }
++    is_wide_mode_initialized = true;
+     is_wide_mode = wide_mode;
+ 
+     if (!is_command_line_startup)
+-- 
+1.8.2.1
+
diff --git a/0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch b/0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch
new file mode 100644
index 0000000..9b3d5d6
--- /dev/null
+++ b/0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch
@@ -0,0 +1,94 @@
+From bd78a9a2a02dbc8c7513c73579dfd5ce848ae9f2 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 17:59:13 +0200
+Subject: [PATCH 27/35] cheese: Get rid of special set_startup_foo() functions
+
+So that cheese-main can toggle / activate the related actions when parsing
+the cmdline and thus have the action state properly reflects the actual state,
+avoiding ie the need to press F11 twice to leave fullscreen after starting
+cheese with -f.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala   |  7 +++++--
+ src/cheese-window.vala | 31 ++-----------------------------
+ 2 files changed, 7 insertions(+), 31 deletions(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index 5905597..e4f2460 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -126,9 +126,12 @@ public class Cheese.Main : Gtk.Application
+       main_window.start_thumbview_monitors ();
+ 
+       if (wide)
+-        main_window.set_startup_wide_mode ();
++        main_window.set_wide_mode (true);
+       if (fullscreen)
+-        main_window.set_startup_fullscreen_mode ();
++        main_window.set_fullscreen (true);
++
++      /* Tell the main window to save any changes from here on to GSettings */
++      main_window.is_command_line_startup = false;
+ 
+       /* Shoot when the webcam capture button is pressed. */
+       main_window.add_events (Gdk.EventMask.KEY_PRESS_MASK
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 906105b..7a3db6b 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -92,7 +92,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+   private bool is_effects_selector_active;
+   private bool is_camera_actions_sensitive;
+   private bool action_cancelled;
+-  private bool is_command_line_startup;
++  public  bool is_command_line_startup;
+ 
+   private Gtk.Button[] buttons;
+   private Gtk.Button[] mode_buttons;
+@@ -122,6 +122,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+     public MainWindow (Gtk.Application application)
+     {
+         GLib.Object (application: application);
++        is_command_line_startup = true;
+     }
+ 
+   /**
+@@ -1337,34 +1338,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+     }
+ 
+   /**
+-   * Set wide mode active when started from the command line (and do not change
+-   * the GSetting).
+-   */
+-  public void set_startup_wide_mode ()
+-  {
+-    if (is_wide_mode)
+-    {
+-      /* Cheese was already in wide mode, avoid setting it again. */
+-      return;
+-    }
+-
+-    is_command_line_startup = true;
+-    set_wide_mode (true);
+-    is_command_line_startup = false;
+-  }
+-
+-  /**
+-   * Set fullscreen mode active when started from the command line (and do not
+-   * change the GSetting).
+-   */
+-  public void set_startup_fullscreen_mode ()
+-  {
+-    is_command_line_startup = true;
+-    set_fullscreen (true);
+-    is_command_line_startup = false;
+-  }
+-
+-  /**
+    * Load the UI from the GtkBuilder description.
+    */
+   public void setup_ui ()
+-- 
+1.8.2.1
+
diff --git a/0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch b/0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch
new file mode 100644
index 0000000..f07b6e1
--- /dev/null
+++ b/0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch
@@ -0,0 +1,32 @@
+From cfc2a636dca6e859e0c6ae8ea4a5fd53238dc9b9 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 18:03:23 +0200
+Subject: [PATCH 28/35] cheese: Fix the need to press F11 twice after starting
+ with -f
+
+Change the fullscreen action state, rather then directly calling set_fullscreen
+so that the action state properly reflects the actual fullscreen state,
+avoiding the need to press F11 twice to leave fullscreen after starting
+cheese with -f.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index e4f2460..032e8cb 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -128,7 +128,7 @@ public class Cheese.Main : Gtk.Application
+       if (wide)
+         main_window.set_wide_mode (true);
+       if (fullscreen)
+-        main_window.set_fullscreen (true);
++        change_action_state("fullscreen", true);
+ 
+       /* Tell the main window to save any changes from here on to GSettings */
+       main_window.is_command_line_startup = false;
+-- 
+1.8.2.1
+
diff --git a/0029-cheese-Make-widemode-controllable-from-the-app-menu.patch b/0029-cheese-Make-widemode-controllable-from-the-app-menu.patch
new file mode 100644
index 0000000..f14bfef
--- /dev/null
+++ b/0029-cheese-Make-widemode-controllable-from-the-app-menu.patch
@@ -0,0 +1,68 @@
+From 7ca2edc8abfcba8384455a180a3c2e4f841abdfd Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 09:40:18 +0200
+Subject: [PATCH 29/35] cheese: Make widemode controllable from the app menu
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index 032e8cb..2adfdc0 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -49,6 +49,7 @@ public class Cheese.Main : Gtk.Application
+         { "shoot", on_shoot },
+         { "mode", on_action_radio, "s", "'photo'", on_mode_change },
+         { "fullscreen", on_action_toggle, null, "false", on_fullscreen_change },
++        { "widemode", on_action_toggle, null, "false", on_widemode_change },
+         { "effects", on_action_toggle, null, "false", on_effects_change },
+         { "preferences", on_preferences },
+         { "about", on_about },
+@@ -103,6 +104,9 @@ public class Cheese.Main : Gtk.Application
+             item = new GLib.MenuItem (_("_Fullscreen"), "app.fullscreen");
+             item.set_attribute ("accel", "s", "F11");
+             section.append_item (item);
++            item = new GLib.MenuItem (_("_Wide Mode"), "app.widemode");
++            item.set_attribute ("accel", "s", "w");
++            section.append_item (item);
+             section = new GLib.Menu ();
+             menu.append_section (null, section);
+             section.append (_("_Effects"), "app.effects");
+@@ -126,7 +130,7 @@ public class Cheese.Main : Gtk.Application
+       main_window.start_thumbview_monitors ();
+ 
+       if (wide)
+-        main_window.set_wide_mode (true);
++        change_action_state("widemode", true);
+       if (fullscreen)
+         change_action_state("fullscreen", true);
+ 
+@@ -324,6 +328,23 @@ public class Cheese.Main : Gtk.Application
+     }
+ 
+     /**
++     * Handle wide mode being toggled on / off.
++     *
++     * @param action the action that emitted the signal
++     * @param value the state to switch to
++     */
++    private void on_widemode_change (SimpleAction action, Variant? value)
++    {
++        return_if_fail (value != null);
++
++        var state = value.get_boolean ();
++
++        main_window.set_wide_mode (state);
++
++        action.set_state (value);
++    }
++
++    /**
+      * Handle the effects state being changed.
+      *
+      * @param action the action that emitted the signal
+-- 
+1.8.2.1
+
diff --git a/0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch b/0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch
new file mode 100644
index 0000000..d3e27b9
--- /dev/null
+++ b/0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch
@@ -0,0 +1,54 @@
+From ac1d5ac64b9c8371bfabb144a77e053b38ff63c5 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 09:48:11 +0200
+Subject: [PATCH 30/35] cheese: Move reading of widemode setting to cheese-main
+
+So that the actiontoggle's state always properly reflects the actual
+wide-mode setting.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala   | 4 ++++
+ src/cheese-window.vala | 4 ++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index 2adfdc0..d0f9b41 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -129,6 +129,10 @@ public class Cheese.Main : Gtk.Application
+       main_window.setup_ui ();
+       main_window.start_thumbview_monitors ();
+ 
++      /* If not set from the cmdline, get the settings from config file */
++      if (!wide)
++        wide = main_window.settings.get_boolean ("wide-mode");
++
+       if (wide)
+         change_action_state("widemode", true);
+       if (fullscreen)
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 7a3db6b..c75c5f0 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -44,7 +44,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+   private Gtk.Builder    gtk_builder;
+   private Clutter.Script clutter_builder;
+ 
+-  private GLib.Settings settings;
++  public  GLib.Settings settings;
+ 
+   private Gtk.Widget       thumbnails;
+   private GtkClutter.Embed viewport_widget;
+@@ -1440,7 +1440,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+      * if the widget is not realized */
+     viewport_widget.realize ();
+ 
+-    set_wide_mode (settings.get_boolean ("wide-mode"));
++    set_wide_mode (false);
+ 
+     set_mode (MediaMode.PHOTO);
+     setup_effects_selector ();
+-- 
+1.8.2.1
+
diff --git a/0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch b/0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch
new file mode 100644
index 0000000..e36b16f
--- /dev/null
+++ b/0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch
@@ -0,0 +1,34 @@
+From 435f7bb98f99affa437dd3cc2cd71fafb4a42332 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 09:51:04 +0200
+Subject: [PATCH 31/35] cheese: Fix reading of fullscreen setting from config
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index d0f9b41..9ba1a5f 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -124,14 +124,14 @@ public class Cheese.Main : Gtk.Application
+             section.append_item (item);
+             set_app_menu (menu);
+ 
+-            // FIXME: Read fullscreen state from GSettings.
+-
+       main_window.setup_ui ();
+       main_window.start_thumbview_monitors ();
+ 
+       /* If not set from the cmdline, get the settings from config file */
+       if (!wide)
+         wide = main_window.settings.get_boolean ("wide-mode");
++      if (!fullscreen)
++        fullscreen = main_window.settings.get_boolean ("fullscreen");
+ 
+       if (wide)
+         change_action_state("widemode", true);
+-- 
+1.8.2.1
+
diff --git a/0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch b/0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch
new file mode 100644
index 0000000..9c07761
--- /dev/null
+++ b/0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch
@@ -0,0 +1,53 @@
+From fa71136c97624724befd0d35cb5a319da30c0afd Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 10:05:46 +0200
+Subject: [PATCH 32/35] cheese: Don't show thumbnails when toggling widemode in
+ fullscreen
+
+This can be done for example from the app-menu when in fullscreen mode on
+a secondary monitor.
+
+Also remove the unnecessary resize calls.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-window.vala | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index c75c5f0..25d9506 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -739,9 +739,11 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+         thumbnails_bottom.remove (thumb_nav);
+       }
+       thumbnails_right.add (thumb_nav);
+-      thumbnails_right.show_all ();
+-      thumbnails_right.resize_children ();
+-      thumbnails_bottom.hide ();
++      if (!is_fullscreen)
++      {
++        thumbnails_right.show_all ();
++        thumbnails_bottom.hide ();
++      }
+     }
+     else
+     {
+@@ -752,9 +754,11 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+         thumbnails_right.remove (thumb_nav);
+       }
+       thumbnails_bottom.add (thumb_nav);
+-      thumbnails_bottom.show_all ();
+-      thumbnails_bottom.resize_children ();
+-      thumbnails_right.hide ();
++      if (!is_fullscreen)
++      {
++        thumbnails_bottom.show_all ();
++        thumbnails_right.hide ();
++      }
+     }
+ 
+     /* handy trick to keep the window to the desired size while not
+-- 
+1.8.2.1
+
diff --git a/0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch b/0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch
new file mode 100644
index 0000000..cafd6bb
--- /dev/null
+++ b/0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch
@@ -0,0 +1,54 @@
+From 1b2af9add59924b46b524bd7b64bbaf12e875a57 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 10:30:02 +0200
+Subject: [PATCH 33/35] cheese: Fix updating of device selection combo
+ sensitivity on hotplug
+
+If one started cheese with 1 device, and then added a 2nd, the device selection
+stayed inactive, making it impossible to select the 2nd device.
+
+This fixes this, and also makes the combo go insensitive again when going from
+>= 2 devices to <= 1 device.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-preferences.vala | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala
+index d4d5501..e078cbb 100644
+--- a/src/cheese-preferences.vala
++++ b/src/cheese-preferences.vala
+@@ -136,8 +136,7 @@ public class Cheese.PreferencesDialog : GLib.Object
+     camera_model = new ListStore (2, typeof (string), typeof (Cheese.CameraDevice));
+ 
+     source_combo.model = camera_model;
+-    if (devices.len <= 1)
+-      source_combo.sensitive = false;
++    source_combo.sensitive = false;
+ 
+     devices.foreach(add_camera_device);
+ 
+@@ -499,6 +498,9 @@ public class Cheese.PreferencesDialog : GLib.Object
+ 
+     if (camera.get_selected_device ().get_device_node () == dev.get_device_node ())
+         source_combo.set_active_iter (iter);
++
++    if (camera_model.iter_n_children (null) > 1)
++      source_combo.sensitive = true;
+   }
+ 
+   /**
+@@ -522,6 +524,9 @@ public class Cheese.PreferencesDialog : GLib.Object
+           this.dialog.hide();
+       }
+       camera_model.remove (iter);
++
++      if (camera_model.iter_n_children (null) <= 1)
++        source_combo.sensitive = false;
+   }
+ 
+   /**
+-- 
+1.8.2.1
+
diff --git a/0034-cheese-Fix-assert-failures-when-taking-a-photo.patch b/0034-cheese-Fix-assert-failures-when-taking-a-photo.patch
new file mode 100644
index 0000000..6e7dd37
--- /dev/null
+++ b/0034-cheese-Fix-assert-failures-when-taking-a-photo.patch
@@ -0,0 +1,38 @@
+From f6d7f1e2a240641080b8d87a169c22571d39316c Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 11:37:19 +0200
+Subject: [PATCH 34/35] cheese: Fix assert failures when taking a photo
+
+Before this patch, cheese would log the following each time the user takes
+a photo:
+
+(cheese:21719): GLib-GIO-CRITICAL **: g_file_info_get_size: assertion `G_IS_FILE_INFO (info)' failed
+
+(cheese:21719): GLib-GObject-CRITICAL **: g_object_unref: assertion `G_IS_OBJECT (object)' failed
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/thumbview/cheese-thumb-view.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/thumbview/cheese-thumb-view.c b/src/thumbview/cheese-thumb-view.c
+index c229b1a..a702fc0 100644
+--- a/src/thumbview/cheese-thumb-view.c
++++ b/src/thumbview/cheese-thumb-view.c
+@@ -205,6 +205,13 @@ cheese_thumb_view_append_item (CheeseThumbView *thumb_view, GFile *file)
+ 
+   info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, 0, NULL,
+                             NULL);
++  if (!info)
++  {
++    /* This is normal since photos first get created with a tmpname, ie:
++     * "2013-06-13-113155.jpg.DQRGYW" and then moved to their final name,
++     * we will get another append_item call for the final name. */
++    return;
++  }
+   size = g_file_info_get_size (info);
+   g_object_unref (info);
+ 
+-- 
+1.8.2.1
+
diff --git a/0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch b/0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch
new file mode 100644
index 0000000..475c67e
--- /dev/null
+++ b/0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch
@@ -0,0 +1,65 @@
+From 81ad92ad8228ba36209130ed4eaf67752ea79bb8 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 12:39:44 +0200
+Subject: [PATCH 35/35] cheese-flash: Fix the flash no longer being white
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-flash.c | 23 ++++-------------------
+ 1 file changed, 4 insertions(+), 19 deletions(-)
+
+diff --git a/libcheese/cheese-flash.c b/libcheese/cheese-flash.c
+index fd46818..37cd36d 100644
+--- a/libcheese/cheese-flash.c
++++ b/libcheese/cheese-flash.c
+@@ -76,29 +76,13 @@ struct _CheeseFlashPrivate
+   guint fade_timeout_tag;
+ };
+ 
+-/*
+- * cheese_flash_draw_event_cb:
+- * @widget: the #CheeseFlash
+- * @cr: the Cairo context
+- * @user_data: the user data of the signal
+- *
+- * Draw the flash.
+- *
+- * Returns: %TRUE
+- */
+-static gboolean
+-cheese_flash_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer user_data)
+-{
+-  cairo_fill (cr);
+-  return TRUE;
+-}
+-
+ static void
+ cheese_flash_init (CheeseFlash *self)
+ {
+   CheeseFlashPrivate *priv = self->priv = CHEESE_FLASH_GET_PRIVATE (self);
+   cairo_region_t *input_region;
+   GtkWindow *window = GTK_WINDOW (self);
++  const GdkColor white = { 0, 65535, 65535, 65535 };
+ 
+   priv->flash_timeout_tag = 0;
+   priv->fade_timeout_tag  = 0;
+@@ -113,13 +97,14 @@ cheese_flash_init (CheeseFlash *self)
+   gtk_window_set_accept_focus (window, FALSE);
+   gtk_window_set_focus_on_map (window, FALSE);
+ 
++  /* Make it white */
++  gtk_widget_modify_bg (GTK_WIDGET (window), GTK_STATE_NORMAL, &white);
++
+   /* Don't consume input */
+   gtk_widget_realize (GTK_WIDGET (window));
+   input_region = cairo_region_create ();
+   gdk_window_input_shape_combine_region (gtk_widget_get_window (GTK_WIDGET (window)), input_region, 0, 0);
+   cairo_region_destroy (input_region);
+-
+-  g_signal_connect (G_OBJECT (window), "draw", G_CALLBACK (cheese_flash_draw_event_cb), NULL);
+ }
+ 
+ static void
+-- 
+1.8.2.1
+
diff --git a/cheese.spec b/cheese.spec
index f40674e..4284d5f 100644
--- a/cheese.spec
+++ b/cheese.spec
@@ -1,7 +1,7 @@
 Name:           cheese
 Epoch:          2
 Version:        3.8.2
-Release:        2%{?dist}
+Release:        3%{?dist}
 Summary:        Application for taking pictures and movies from a webcam
 
 Group:          Amusements/Graphics
@@ -9,6 +9,49 @@ License:        GPLv2+
 URL:            http://projects.gnome.org/cheese/
 #VCS: git:git://git.gnome.org/cheese
 Source0:        http://download.gnome.org/sources/cheese/3.8/%{name}-%{version}.tar.xz
+
+# HdG: since I hit a couple of issues in cheese, and cheese needed some loving
+# in general I ended up doing a whole lot of *bugfix* patches for cheese,
+# fixing various performance / device compatibility issues, but also things
+# like needing to press some buttons twice before they work, etc.
+# See here for a bug for tracking the upstreaming of this patchset:
+# https://bugzilla.gnome.org/show_bug.cgi?id=702264
+Patch1:         0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch
+Patch2:         0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch
+Patch3:         0003-cheese-camera-Set-image-and-video-capture-caps.patch
+Patch4:         0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch
+Patch5:         0005-cheese-camera-2-minor-error-handling-cleanups.patch
+Patch6:         0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch
+Patch7:         0007-cheese-camera-Remove-unused-enum.patch
+Patch8:         0008-cheese-camera-device-Fix-compiler-warning.patch
+Patch9:         0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch
+Patch10:        0010-cheese-camera-device-Keep-track-of-highest-available.patch
+Patch11:        0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch
+Patch12:        0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch
+Patch13:        0013-cheese-camera-device-get_caps_for_format-simplify-th.patch
+Patch14:        0014-cheese-camera-device-Make-get_best_format-smarter.patch
+Patch15:        0015-cheese-camera-device-Plug-some-memory-leaks.patch
+Patch16:        0016-cheese-camera-Drop-unused-preview_caps.patch
+Patch17:        0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch
+Patch18:        0018-cheese-camera-Check-for-the-current-effect-being-the.patch
+Patch19:        0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch
+Patch20:        0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch
+Patch21:        0021-cheese-window-Fix-de-activation-of-effects-button.patch
+Patch22:        0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch
+Patch23:        0023-libcheese-Add-_init_with_args-init-function-variants.patch
+Patch24:        0024-cheese-Use-cheese_gtk_init_with_args.patch
+Patch25:        0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch
+Patch26:        0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch
+Patch27:        0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch
+Patch28:        0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch
+Patch29:        0029-cheese-Make-widemode-controllable-from-the-app-menu.patch
+Patch30:        0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch
+Patch31:        0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch
+Patch32:        0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch
+Patch33:        0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch
+Patch34:        0034-cheese-Fix-assert-failures-when-taking-a-photo.patch
+Patch35:        0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch
+
 # https://bugzilla.gnome.org/show_bug.cgi?id=678447
 # Patch2: 0002-Setup-vp8enc-in-a-way-suitable-for-realtime-encoding.patch
 
@@ -41,7 +84,7 @@ BuildRequires: libxslt
 BuildRequires: docbook-style-xsl
 BuildRequires: /usr/bin/convert
 
-Requires: %{name}-libs = %{epoch}:%{version}-%{release}
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
 Requires: gstreamer1-plugins-good
 Requires: gstreamer1-plugins-bad-free
 Requires: gnome-video-effects
@@ -51,19 +94,19 @@ Cheese is a Photobooth-inspired GNOME application for taking pictures and
 videos from a webcam. It can also apply fancy graphical effects.
 
 %package libs
-Summary:	Webcam display and capture widgets
-Group:		System Environment/Libraries
-License:	GPLv2+
+Summary:        Webcam display and capture widgets
+Group:          System Environment/Libraries
+License:        GPLv2+
 
 %description libs
 This package contains libraries needed for applications that
 want to display a webcam in their interface.
 
 %package libs-devel
-Summary:	Development files for %{name}-libs
-Group:		Development/Libraries
-License:	GPLv2+
-Requires:	%{name}-libs = %{epoch}:%{version}-%{release}
+Summary:        Development files for %{name}-libs
+Group:          Development/Libraries
+License:        GPLv2+
+Requires:       %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
 
 %description libs-devel
 This package contains the libraries and header files that are needed
@@ -71,7 +114,41 @@ for writing applications that require a webcam display widget.
 
 %prep
 %setup -q
-# %patch2 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
+%patch33 -p1
+%patch34 -p1
+%patch35 -p1
 
 
 %build
@@ -85,10 +162,10 @@ make install DESTDIR=$RPM_BUILD_ROOT
 rm -f $RPM_BUILD_ROOT%{_libdir}/libcheese.{a,la}
 rm -f $RPM_BUILD_ROOT%{_libdir}/libcheese-gtk.{a,la}
 
-desktop-file-install --delete-original --vendor="" 	\
- 	--dir=$RPM_BUILD_ROOT%{_datadir}/applications 	\
-	--add-category X-AudioVideoImport		\
-	$RPM_BUILD_ROOT%{_datadir}/applications/cheese.desktop
+desktop-file-install --delete-original --vendor=""    \
+    --dir=$RPM_BUILD_ROOT%{_datadir}/applications     \
+    --add-category X-AudioVideoImport                 \
+    $RPM_BUILD_ROOT%{_datadir}/applications/cheese.desktop
 
 %find_lang %{name} --with-gnome
 
@@ -123,7 +200,7 @@ fi
 glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
 
 %files
-%doc AUTHORS COPYING README
+%doc AUTHORS README
 %{_bindir}/cheese
 %{_datadir}/applications/cheese.desktop
 %{_datadir}/cheese
@@ -131,17 +208,15 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
 %{_datadir}/icons/hicolor/*/actions/*.png
 %{_datadir}/icons/hicolor/scalable/actions/*.svg
 %{_mandir}/man1/cheese.1.gz
-# FIXME find-lang is supposed to pick these up
-%doc %{_datadir}/help/*/cheese
 
 %files -f %{name}.lang libs
+%doc COPYING
 %{_libdir}/libcheese.so.*
 %{_libdir}/libcheese-gtk.so.*
 %{_datadir}/glib-2.0/schemas/org.gnome.Cheese.gschema.xml
 %{_libdir}/girepository-1.0/Cheese-3.0.typelib
 
 %files libs-devel
-%doc COPYING
 %{_libdir}/libcheese.so
 %{_libdir}/libcheese-gtk.so
 %{_includedir}/cheese/
@@ -151,6 +226,15 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
 %{_datadir}/gir-1.0/Cheese-3.0.gir
 
 %changelog
+* Mon Jun 17 2013 Hans de Goede <hdegoede at redhat.com> - 2:3.8.2-3
+- Add a number of bug-fixes to deal better with high res cams (#873434)
+- Fix cheese-introduction.png being in both cheese and cheese-libs (#893756)
+- Put the COPYING file in the docs for cheese-libs (#893800)
+- Fix the flash when taking a photo being dark grey instead of white (#965813)
+- Fix needing to press the effects button twice to select effects after
+  selecting an effect for the first time
+- Various other bug-fixes
+
 * Tue May 14 2013 Matthias Clasen <mclasen at redhat.com> - 2:3.8.2-2
 - Conserve space by shrinking images
 
@@ -357,7 +441,7 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
 * Thu Aug 19 2010 Matthias Clasen <mclasen at redhat.com> 1:2.31.90-1
 - Update to 2.31.90
 
-* Fri Aug 11 2010 Matthias Clasen <mclasen at redhat.com> 1:2.31.1-2
+* Wed Aug 11 2010 Matthias Clasen <mclasen at redhat.com> 1:2.31.1-2
 - Add an epoch to stay ahead of F14
 
 * Fri Aug  6 2010 Matthias Clasen <mclasen at redhat.com> 2.31.1-1
@@ -457,7 +541,7 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
 * Wed Dec  3 2008 Matthias Clasen  <mclasen at redhat.com> 2.25.2-1
 - Update to 2.25.2
 
-* Thu Nov 21 2008 Matthias Clasen  <mclasen at redhat.com> 2.25.1-4
+* Fri Nov 21 2008 Matthias Clasen  <mclasen at redhat.com> 2.25.1-4
 - Better URL
 
 * Thu Nov 13 2008 Matthias Clasen  <mclasen at redhat.com> 2.25.1-3


More information about the scm-commits mailing list