implement preview mirroring
This commit is contained in:
parent
98ad876efc
commit
984dd3cbb8
5 changed files with 51 additions and 7 deletions
34
photobooth.c
34
photobooth.c
|
@ -28,6 +28,8 @@
|
|||
#include <gst/app/app.h>
|
||||
#include <curl/curl.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
// #ifdef HAVE_LIBCANBERRA
|
||||
#include <canberra-gtk.h>
|
||||
// #endif
|
||||
|
@ -96,6 +98,7 @@ struct _PhotoBoothPrivate
|
|||
GThread *upload_thread;
|
||||
GMutex upload_mutex;
|
||||
gboolean do_twitter;
|
||||
gboolean do_flip;
|
||||
|
||||
PhotoBoothLed *led;
|
||||
};
|
||||
|
@ -106,6 +109,7 @@ struct _PhotoBoothPrivate
|
|||
#define DEFAULT_COUNTDOWN 5
|
||||
#define DEFAULT_SAVE_PATH_TEMPLATE "./snapshot%03d.jpg"
|
||||
#define DEFAULT_SCREENSAVER_TIMEOUT -1
|
||||
#define DEFAULT_FLIP TRUE
|
||||
#define PRINT_DPI 346
|
||||
#define PRINT_WIDTH 2076
|
||||
#define PRINT_HEIGHT 1384
|
||||
|
@ -128,6 +132,7 @@ static void photo_booth_dispose (GObject *object);
|
|||
static void photo_booth_finalize (GObject *object);
|
||||
PhotoBooth *photo_booth_new (void);
|
||||
void photo_booth_background_clicked (GtkWidget *widget, GdkEventButton *event, PhotoBoothWindow *win);
|
||||
void photo_booth_flip_switched (GtkSwitch *widget, gboolean state, PhotoBoothWindow *win);
|
||||
void photo_booth_button_cancel_clicked (GtkButton *button, PhotoBoothWindow *win);
|
||||
void photo_booth_cancel (PhotoBooth *pb);
|
||||
|
||||
|
@ -274,6 +279,7 @@ static void photo_booth_init (PhotoBooth *pb)
|
|||
priv->imgur_description = NULL;
|
||||
priv->upload_thread = NULL;
|
||||
priv->do_twitter = TRUE;
|
||||
priv->do_flip = DEFAULT_FLIP;
|
||||
priv->state_change_watchdog_timeout_id = 0;
|
||||
|
||||
priv->led = photo_booth_led_new ();
|
||||
|
@ -852,7 +858,7 @@ static GstElement *build_video_bin (PhotoBooth *pb)
|
|||
{
|
||||
PhotoBoothPrivate *priv;
|
||||
GstElement *video_bin;
|
||||
GstElement *mjpeg_source, *mjpeg_decoder, *mjpeg_filter, *video_filter, *video_scale, *video_convert, *video_overlay;
|
||||
GstElement *mjpeg_source, *mjpeg_decoder, *mjpeg_filter, *video_filter, *video_scale, *video_flip, *video_convert, *video_overlay;
|
||||
GstCaps *caps;
|
||||
GstPad *ghost, *pad;
|
||||
|
||||
|
@ -872,6 +878,8 @@ static GstElement *build_video_bin (PhotoBooth *pb)
|
|||
mjpeg_decoder = gst_element_factory_make ("jpegdec", "mjpeg-decoder");
|
||||
video_scale = gst_element_factory_make ("videoscale", "mjpeg-videoscale");
|
||||
video_convert = gst_element_factory_make ("videoconvert", "mjpeg-videoconvert");
|
||||
video_flip = gst_element_factory_make ("videoflip", "video-flip");
|
||||
g_object_set (G_OBJECT (video_flip), "method", priv->do_flip?4:0, NULL);
|
||||
video_filter = gst_element_factory_make ("capsfilter", "video-capsfilter");
|
||||
caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, priv->preview_width, "height", G_TYPE_INT, priv->preview_height, NULL);
|
||||
g_object_set (G_OBJECT (video_filter), "caps", caps, NULL);
|
||||
|
@ -881,16 +889,16 @@ static GstElement *build_video_bin (PhotoBooth *pb)
|
|||
if (priv->overlay_image)
|
||||
g_object_set (video_overlay, "location", priv->overlay_image, NULL);
|
||||
|
||||
if (!(mjpeg_source && mjpeg_filter && mjpeg_decoder && video_scale && video_convert && video_filter && video_overlay))
|
||||
if (!(mjpeg_source && mjpeg_filter && mjpeg_decoder && video_scale && video_convert && video_flip && video_filter && video_overlay))
|
||||
{
|
||||
GST_ERROR_OBJECT (video_bin, "Failed to make videobin pipeline element(s):%s%s%s%s%s%s%s", mjpeg_source?"":" fdsrc", mjpeg_filter?"":" capsfilter", mjpeg_decoder?"":" jpegdec",
|
||||
video_scale?"":" videoscale", video_convert?"":" videoconvert", video_filter?"":" capsfilter", video_overlay?"":" gdkpixbufoverlay");
|
||||
video_scale?"":" videoscale", video_convert?"":" videoconvert", video_flip?"":" videoflip", video_filter?"":" capsfilter", video_overlay?"":" gdkpixbufoverlay");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_bin_add_many (GST_BIN (video_bin), mjpeg_source, mjpeg_filter, mjpeg_decoder, video_scale, video_convert, video_filter, video_overlay, NULL);
|
||||
gst_bin_add_many (GST_BIN (video_bin), mjpeg_source, mjpeg_filter, mjpeg_decoder, video_scale, video_convert, video_flip, video_filter, video_overlay, NULL);
|
||||
|
||||
if (!gst_element_link_many (mjpeg_source, mjpeg_filter, mjpeg_decoder, video_scale, video_convert, video_filter, video_overlay, NULL))
|
||||
if (!gst_element_link_many (mjpeg_source, mjpeg_filter, mjpeg_decoder, video_scale, video_convert, video_flip, video_filter, video_overlay, NULL))
|
||||
{
|
||||
GST_ERROR_OBJECT (video_bin, "couldn't link videobin elements!");
|
||||
return FALSE;
|
||||
|
@ -1182,6 +1190,7 @@ static gboolean photo_booth_preview_ready (PhotoBooth *pb)
|
|||
photo_booth_change_state (pb, PB_STATE_PREVIEW);
|
||||
gtk_label_set_text (priv->win->status, _("Touch screen to take a photo!"));
|
||||
photo_booth_window_hide_cursor (priv->win);
|
||||
gtk_widget_show (GTK_WIDGET (priv->win->switch_flip));
|
||||
|
||||
if (priv->screensaver_timeout > 0)
|
||||
priv->screensaver_timeout_id = g_timeout_add_seconds (priv->screensaver_timeout, (GSourceFunc) photo_booth_screensaver, pb);
|
||||
|
@ -1349,6 +1358,19 @@ void photo_booth_background_clicked (GtkWidget *widget, GdkEventButton *event, P
|
|||
// photo_booth_get_printer_status (pb);
|
||||
}
|
||||
|
||||
void photo_booth_flip_switched (GtkSwitch *widget, gboolean state, PhotoBoothWindow *win)
|
||||
{
|
||||
PhotoBooth *pb = PHOTO_BOOTH_FROM_WINDOW (win);
|
||||
PhotoBoothPrivate *priv = photo_booth_get_instance_private (pb);
|
||||
priv = photo_booth_get_instance_private (pb);
|
||||
GST_INFO_OBJECT (pb, "photo_booth_flip_switched state %i", state);
|
||||
priv->do_flip = state;
|
||||
GstElement *video_flip = gst_bin_get_by_name (GST_BIN (pb->video_bin), "video-flip");
|
||||
g_object_set (G_OBJECT (video_flip), "method", priv->do_flip?4:0, NULL);
|
||||
gst_object_unref (video_flip);
|
||||
}
|
||||
|
||||
|
||||
static gboolean photo_booth_get_printer_status (PhotoBooth *pb)
|
||||
{
|
||||
PhotoBoothPrivate *priv = photo_booth_get_instance_private (pb);
|
||||
|
@ -1428,6 +1450,8 @@ static void photo_booth_snapshot_start (PhotoBooth *pb)
|
|||
priv = photo_booth_get_instance_private (pb);
|
||||
photo_booth_change_state (pb, PB_STATE_COUNTDOWN);
|
||||
photo_booth_window_start_countdown (priv->win, priv->countdown);
|
||||
gtk_widget_hide (GTK_WIDGET (priv->win->switch_flip));
|
||||
|
||||
if (priv->countdown > 1)
|
||||
{
|
||||
pretrigger_delay = (priv->countdown*1000)-1000;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include <glib-unix.h>
|
||||
#include <glib-object.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gphoto2/gphoto2.h>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<property name="value">1</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">1</property>
|
||||
<property name="page_size">0</property>
|
||||
</object>
|
||||
<template class="PhotoBoothWindow" parent="GtkApplicationWindow">
|
||||
<property name="can_focus">False</property>
|
||||
|
@ -130,6 +129,23 @@
|
|||
<property name="y">100</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switch_flip">
|
||||
<property name="width_request">360</property>
|
||||
<property name="height_request">120</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="opacity">0.59999999999999998</property>
|
||||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="state-set" handler="photo_booth_flip_switched" object="PhotoBoothWindow" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="x">460</property>
|
||||
<property name="y">640</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="transparentbg"/>
|
||||
</style>
|
||||
|
@ -240,5 +256,8 @@
|
|||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
|
|
|
@ -67,6 +67,7 @@ static void photo_booth_window_class_init (PhotoBoothWindowClass *klass)
|
|||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), PhotoBoothWindow, button_cancel);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), PhotoBoothWindow, button_print);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), PhotoBoothWindow, button_upload);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), PhotoBoothWindow, switch_flip);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), PhotoBoothWindow, status_clock);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), PhotoBoothWindow, status);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), PhotoBoothWindow, status_printer);
|
||||
|
|
|
@ -35,6 +35,7 @@ struct _PhotoBoothWindow
|
|||
GtkApplicationWindow parent;
|
||||
GtkWidget *gtkgstwidget;
|
||||
GtkButton *button_cancel, *button_print, *button_upload;
|
||||
GtkSwitch *switch_flip;
|
||||
GtkLabel *status_clock, *status, *status_printer;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue