[gnome-contacts] Adding cheese-flash effect support.



commit 5c990b42676aea13413fe55a0d7225a0119c35d2
Author: Erick PÃrez Castellanos <erick red gmail com>
Date:   Fri Feb 24 00:58:00 2012 -0500

    Adding cheese-flash effect support.
    
    Old files from gnome-screenshot, not the ones from actual cheese since does involves more stuff.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=657978

 src/Makefile.am    |    2 +
 src/cheese-flash.c |  215 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/cheese-flash.h |   52 +++++++++++++
 vapi/custom.vapi   |    9 ++
 4 files changed, 278 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 31269f8..3fc3dfd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,6 +59,7 @@ contact-resources.c: contacts.gresource.xml app-menu.ui
 		--target=$@ --sourcedir=$(srcdir) --c-name contacts --generate-source
 
 gnome_contacts_SOURCES = \
+	cheese-flash.c \
 	um-crop-area.c \
 	contact-resources.c \
 	gtk-notification.c   \
@@ -78,6 +79,7 @@ CLEANFILES = \
 	*.vapi *.stamp
 
 EXTRA_DIST = \
+	cheese-flash.h \
 	um-crop-area.h \
 	gtk-notification.h   \
 	contacts.gresource.xml \
diff --git a/src/cheese-flash.c b/src/cheese-flash.c
new file mode 100644
index 0000000..131c9b3
--- /dev/null
+++ b/src/cheese-flash.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright  2008 Alexander âweejâ Jones <alex weej com>
+ * Copyright  2008 Thomas Perl <thp thpinfo com>
+ * Copyright  2009 daniel g. siegel <dgsiegel gnome org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This is a "flash" object that you can create and invoke a method "flash" on to
+ * flood the screen with white temporarily */
+
+#include <gtk/gtk.h>
+
+#include "cheese-flash.h"
+
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xproto.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <gdk/gdkx.h>
+#endif /* GDK_WINDOWING_X11 */
+
+/* How long to hold the flash for */
+#define FLASH_DURATION 150
+
+/* The factor which defines how much the flash fades per frame */
+#define FLASH_FADE_FACTOR 0.95
+
+/* How many frames per second */
+#define FLASH_ANIMATION_RATE 120
+
+/* When to consider the flash finished so we can stop fading */
+#define FLASH_LOW_THRESHOLD 0.01
+
+G_DEFINE_TYPE (CheeseFlash, cheese_flash, G_TYPE_OBJECT);
+
+#define CHEESE_FLASH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHEESE_TYPE_FLASH, CheeseFlashPrivate))
+
+typedef struct
+{
+  GtkWindow *window;
+  guint flash_timeout_tag;
+  guint fade_timeout_tag;
+} CheeseFlashPrivate;
+
+static gboolean
+cheese_flash_window_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 = CHEESE_FLASH_GET_PRIVATE (self);
+  cairo_region_t *input_region;
+  GtkWindow *window;
+  GdkScreen *screen;
+  GdkVisual *visual;
+
+  priv->flash_timeout_tag = 0;
+  priv->fade_timeout_tag  = 0;
+
+  window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_POPUP));
+
+  /* make it so it doesn't look like a window on the desktop (+fullscreen) */
+  gtk_window_set_decorated (window, FALSE);
+  gtk_window_set_skip_taskbar_hint (window, TRUE);
+  gtk_window_set_skip_pager_hint (window, TRUE);
+  gtk_window_set_keep_above (window, TRUE);
+  gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_NOTIFICATION);
+
+  /* Don't take focus */
+  gtk_window_set_accept_focus (window, FALSE);
+  gtk_window_set_focus_on_map (window, FALSE);
+
+  /* no shadow */
+  screen = gtk_widget_get_screen (GTK_WIDGET (window));
+  visual = gdk_screen_get_rgba_visual (screen);
+  if (visual == NULL)
+    visual = gdk_screen_get_system_visual (screen);
+
+  gtk_widget_set_visual (GTK_WIDGET (window), visual);
+
+  /* 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_window_draw_event_cb), NULL);
+  priv->window = window;
+}
+
+static void
+cheese_flash_dispose (GObject *object)
+{
+  CheeseFlashPrivate *priv = CHEESE_FLASH_GET_PRIVATE (object);
+
+  if (priv->window != NULL)
+  {
+    gtk_widget_destroy (GTK_WIDGET (priv->window));
+    priv->window = NULL;
+  }
+
+  if (G_OBJECT_CLASS (cheese_flash_parent_class)->dispose)
+    G_OBJECT_CLASS (cheese_flash_parent_class)->dispose (object);
+}
+
+static void
+cheese_flash_finalize (GObject *object)
+{
+  if (G_OBJECT_CLASS (cheese_flash_parent_class)->finalize)
+    G_OBJECT_CLASS (cheese_flash_parent_class)->finalize (object);
+}
+
+static void
+cheese_flash_class_init (CheeseFlashClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (CheeseFlashPrivate));
+
+  object_class->dispose      = cheese_flash_dispose;
+  object_class->finalize     = cheese_flash_finalize;
+}
+
+static gboolean
+cheese_flash_opacity_fade (gpointer data)
+{
+  CheeseFlash        *flash        = data;
+  CheeseFlashPrivate *flash_priv   = CHEESE_FLASH_GET_PRIVATE (flash);
+  GtkWindow          *flash_window = flash_priv->window;
+  double              opacity      = gtk_window_get_opacity (flash_window);
+
+  /* exponentially decrease */
+  gtk_window_set_opacity (flash_window, opacity * FLASH_FADE_FACTOR);
+
+  if (opacity <= FLASH_LOW_THRESHOLD)
+  {
+    /* the flasher has finished when we reach the quit value */
+    gtk_widget_hide (GTK_WIDGET (flash_window));
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+static gboolean
+cheese_flash_start_fade (gpointer data)
+{
+  CheeseFlash *self = data;
+  CheeseFlashPrivate *flash_priv = CHEESE_FLASH_GET_PRIVATE (self);
+  GtkWindow *flash_window = flash_priv->window;
+
+  /* If the screen is non-composited, just hide and finish up */
+  if (!gdk_screen_is_composited (gtk_window_get_screen (flash_window)))
+  {
+    gtk_widget_hide (GTK_WIDGET (flash_window));
+    return FALSE;
+  }
+
+  flash_priv->fade_timeout_tag = 
+    g_timeout_add_full (G_PRIORITY_DEFAULT,
+                        1000.0 / FLASH_ANIMATION_RATE,
+                        cheese_flash_opacity_fade,
+                        g_object_ref (self), g_object_unref);
+  return FALSE;
+}
+
+void
+cheese_flash_fire (CheeseFlash  *flash,
+                   GdkRectangle *rect)
+{
+  CheeseFlashPrivate *flash_priv = CHEESE_FLASH_GET_PRIVATE (flash);
+  GtkWindow *flash_window = flash_priv->window;
+
+  if (flash_priv->flash_timeout_tag > 0)
+    g_source_remove (flash_priv->flash_timeout_tag);
+  if (flash_priv->fade_timeout_tag > 0)
+    g_source_remove (flash_priv->fade_timeout_tag);
+
+  gtk_window_resize (flash_window, rect->width, rect->height);
+  gtk_window_move (flash_window, rect->x, rect->y);
+
+  gtk_window_set_opacity (flash_window, 0.99);
+  gtk_widget_show_all (GTK_WIDGET (flash_window));
+  flash_priv->flash_timeout_tag = 
+    g_timeout_add_full (G_PRIORITY_DEFAULT,
+                        FLASH_DURATION,
+                        cheese_flash_start_fade,
+                        g_object_ref (flash), g_object_unref);
+}
+
+CheeseFlash *
+cheese_flash_new (void)
+{
+  return g_object_new (CHEESE_TYPE_FLASH, NULL);
+}
diff --git a/src/cheese-flash.h b/src/cheese-flash.h
new file mode 100644
index 0000000..6248aea
--- /dev/null
+++ b/src/cheese-flash.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright  2008 Alexander âweejâ Jones <alex weej com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CHEESE_FLASH_H_
+#define _CHEESE_FLASH_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CHEESE_TYPE_FLASH (cheese_flash_get_type ())
+#define CHEESE_FLASH(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHEESE_TYPE_FLASH, CheeseFlash))
+#define CHEESE_FLASH_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CHEESE_TYPE_FLASH, CheeseFlashClass))
+#define CHEESE_IS_FLASH(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHEESE_TYPE_FLASH))
+#define CHEESE_IS_FLASH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CHEESE_TYPE_FLASH))
+#define CHEESE_FLASH_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), CHEESE_TYPE_FLASH, CheeseFlashClass))
+
+typedef struct
+{
+  GObjectClass parent_class;
+} CheeseFlashClass;
+
+typedef struct
+{
+  GObject parent_instance;
+} CheeseFlash;
+
+GType        cheese_flash_get_type (void) G_GNUC_CONST;
+CheeseFlash *cheese_flash_new (void);
+
+void cheese_flash_fire (CheeseFlash *flash,
+                        GdkRectangle *rect);
+
+G_END_DECLS
+
+#endif /* _CHEESE_FLASH_H_ */
diff --git a/vapi/custom.vapi b/vapi/custom.vapi
index c046977..d4372a3 100644
--- a/vapi/custom.vapi
+++ b/vapi/custom.vapi
@@ -69,3 +69,12 @@ namespace Um {
 		public Gdk.Pixbuf get_picture ();
 	}
 }
+
+[CCode (cprefix = "Cheese", lower_case_cprefix = "cheese_", cheader_filename = "cheese-flash.h")]
+namespace Cheese {
+	public class Flash : Gtk.Window {
+		[CCode (has_construct_function = false, type = "CheeseFlash*")]
+		public Flash ();
+		public void fire (Gdk.Rectangle rect);
+	}
+}



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