[gnome-flashback] screenshot: implement FlashArea method
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] screenshot: implement FlashArea method
- Date: Thu, 10 Sep 2015 12:10:29 +0000 (UTC)
commit 2c344cd347e23ecc8d4b87910ed268cb53f40f41
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Thu Sep 10 15:07:50 2015 +0300
screenshot: implement FlashArea method
https://bugzilla.gnome.org/show_bug.cgi?id=753529
gnome-flashback/libscreenshot/Makefile.am | 2 +
gnome-flashback/libscreenshot/gf-flashspot.c | 200 +++++++++++++++++++++++++
gnome-flashback/libscreenshot/gf-flashspot.h | 38 +++++
gnome-flashback/libscreenshot/gf-screenshot.c | 69 +++++++++-
4 files changed, 308 insertions(+), 1 deletions(-)
---
diff --git a/gnome-flashback/libscreenshot/Makefile.am b/gnome-flashback/libscreenshot/Makefile.am
index 38d1d20..2a8a024 100644
--- a/gnome-flashback/libscreenshot/Makefile.am
+++ b/gnome-flashback/libscreenshot/Makefile.am
@@ -12,6 +12,8 @@ libscreenshot_la_CFLAGS = \
$(NULL)
libscreenshot_la_SOURCES = \
+ gf-flashspot.c \
+ gf-flashspot.h \
gf-screenshot.c \
gf-screenshot.h \
gf-select-area.c \
diff --git a/gnome-flashback/libscreenshot/gf-flashspot.c b/gnome-flashback/libscreenshot/gf-flashspot.c
new file mode 100644
index 0000000..ef29ba8
--- /dev/null
+++ b/gnome-flashback/libscreenshot/gf-flashspot.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * 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 3 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/>.
+ *
+ * Based on code in gnome-screenshot:
+ * https://git.gnome.org/browse/gnome-screenshot/tree/src/cheese-flash.c
+ * Copyright (C) 2008 Alexander “weej” Jones, 2008 Thomas Perl,
+ * 2009 daniel g. siegel
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "gf-flashspot.h"
+
+#define FLASH_DURATION 100
+#define FLASH_ANIMATION_RATE 200
+#define FLASH_FADE_FACTOR 0.95
+
+struct _GfFlashspot
+{
+ GObject parent;
+
+ GtkWidget *window;
+
+ guint flash_id;
+ guint fade_id;
+};
+
+G_DEFINE_TYPE (GfFlashspot, gf_flashspot, G_TYPE_OBJECT)
+
+static gboolean
+fade (gpointer user_data)
+{
+ GfFlashspot *flashspot;
+ gdouble opacity;
+
+ flashspot = GF_FLASHSPOT (user_data);
+ opacity = gtk_widget_get_opacity (flashspot->window);
+
+ gtk_widget_set_opacity (flashspot->window, opacity * FLASH_FADE_FACTOR);
+
+ if (opacity <= 0.01)
+ {
+ gtk_widget_hide (flashspot->window);
+
+ flashspot->fade_id = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+static gboolean
+start_fade (gpointer user_data)
+{
+ GfFlashspot *flashspot;
+ GdkScreen *screen;
+
+ flashspot = GF_FLASHSPOT (user_data);
+ screen = gtk_widget_get_screen (flashspot->window);
+
+ if (!gdk_screen_is_composited (screen))
+ {
+ gtk_widget_hide (flashspot->window);
+
+ flashspot->flash_id = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ flashspot->fade_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
+ 1000.0 / FLASH_ANIMATION_RATE,
+ fade,
+ g_object_ref (flashspot),
+ g_object_unref);
+
+ flashspot->flash_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static void
+gf_flashspot_dispose (GObject *object)
+{
+ GfFlashspot *flashspot;
+
+ flashspot = GF_FLASHSPOT (object);
+
+ if (flashspot->window != NULL)
+ {
+ gtk_widget_destroy (flashspot->window);
+ flashspot->window = NULL;
+ }
+
+ if (flashspot->flash_id > 0)
+ {
+ g_source_remove (flashspot->flash_id);
+ flashspot->flash_id = 0;
+ }
+
+ if (flashspot->fade_id > 0)
+ {
+ g_source_remove (flashspot->fade_id);
+ flashspot->fade_id = 0;
+ }
+
+ G_OBJECT_CLASS (gf_flashspot_parent_class)->dispose (object);
+}
+
+static void
+gf_flashspot_class_init (GfFlashspotClass *flashspot_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (flashspot_class);
+
+ object_class->dispose = gf_flashspot_dispose;
+}
+
+static void
+gf_flashspot_init (GfFlashspot *flashspot)
+{
+ GtkWindow *window;
+ GdkScreen *screen;
+ GdkVisual *visual;
+ cairo_region_t *input_region;
+
+ flashspot->window = gtk_window_new (GTK_WINDOW_POPUP);
+
+ window = GTK_WINDOW (flashspot->window);
+ screen = gtk_widget_get_screen (flashspot->window);
+ visual = gdk_screen_get_rgba_visual (screen);
+
+ if (visual == NULL)
+ visual = gdk_screen_get_system_visual (screen);
+
+ 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);
+ gtk_window_set_accept_focus (window, FALSE);
+ gtk_window_set_focus_on_map (window, FALSE);
+
+ gtk_widget_set_visual (flashspot->window, visual);
+ gtk_widget_realize (flashspot->window);
+
+ input_region = cairo_region_create ();
+ gdk_window_input_shape_combine_region (gtk_widget_get_window (flashspot->window),
+ input_region, 0, 0);
+ cairo_region_destroy (input_region);
+}
+
+GfFlashspot *
+gf_flashspot_new (void)
+{
+ return g_object_new (GF_TYPE_FLASHSPOT, NULL);
+}
+
+void
+gf_flashspot_fire (GfFlashspot *flashspot,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GtkWindow *window;
+
+ if (flashspot->flash_id > 0)
+ g_source_remove (flashspot->flash_id);
+
+ if (flashspot->fade_id > 0)
+ g_source_remove (flashspot->fade_id);
+
+ window = GTK_WINDOW (flashspot->window);
+
+ gtk_window_move (window, x, y);
+ gtk_window_resize (window, width, height);
+
+ gtk_widget_set_opacity (flashspot->window, 0.99);
+ gtk_widget_show_all (flashspot->window);
+
+ flashspot->flash_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
+ FLASH_DURATION,
+ start_fade,
+ g_object_ref (flashspot),
+ g_object_unref);
+}
diff --git a/gnome-flashback/libscreenshot/gf-flashspot.h b/gnome-flashback/libscreenshot/gf-flashspot.h
new file mode 100644
index 0000000..47421ea
--- /dev/null
+++ b/gnome-flashback/libscreenshot/gf-flashspot.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * 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 3 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 GF_FLASHSPOT_H
+#define GF_FLASHSPOT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GF_TYPE_FLASHSPOT gf_flashspot_get_type ()
+G_DECLARE_FINAL_TYPE (GfFlashspot, gf_flashspot, GF, FLASHSPOT, GObject)
+
+GfFlashspot *gf_flashspot_new (void);
+
+void gf_flashspot_fire (GfFlashspot *flashspot,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+
+G_END_DECLS
+
+#endif
diff --git a/gnome-flashback/libscreenshot/gf-screenshot.c b/gnome-flashback/libscreenshot/gf-screenshot.c
index c4aad08..70940ca 100644
--- a/gnome-flashback/libscreenshot/gf-screenshot.c
+++ b/gnome-flashback/libscreenshot/gf-screenshot.c
@@ -20,6 +20,7 @@
#include <gtk/gtk.h>
#include "gf-dbus-screenshot.h"
+#include "gf-flashspot.h"
#include "gf-screenshot.h"
#include "gf-select-area.h"
@@ -32,10 +33,46 @@ struct _GfScreenshot
gint bus_name;
GfDBusScreenshot *dbus_screenshot;
+
+ GfFlashspot *flashspot;
};
G_DEFINE_TYPE (GfScreenshot, gf_screenshot, G_TYPE_OBJECT)
+static void
+scale_area (gint *x,
+ gint *y,
+ gint *width,
+ gint *height)
+{
+}
+
+static void
+unscale_area (gint *x,
+ gint *y,
+ gint *width,
+ gint *height)
+{
+}
+
+static gboolean
+check_area (gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GdkScreen *screen;
+ gint screen_width;
+ gint screen_height;
+
+ screen = gdk_screen_get_default ();
+ screen_width = gdk_screen_get_width (screen);
+ screen_height = gdk_screen_get_height (screen);
+
+ return x >= 0 && y >= 0 && width > 0 && height > 0 &&
+ x + width <= screen_width && y + height <= screen_height;
+}
+
static gboolean
handle_screenshot (GfDBusScreenshot *dbus_screenshot,
GDBusMethodInvocation *invocation,
@@ -78,6 +115,17 @@ handle_screenshot_area (GfDBusScreenshot *dbus_screenshot,
const gchar *filename,
gpointer user_data)
{
+ if (!check_area (x, y, width, height))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ "Invalid params");
+
+ return TRUE;
+ }
+
+ scale_area (&x, &y, &width, &height);
+
g_warning ("screenshot: screenshot-area");
gf_dbus_screenshot_complete_screenshot_area (dbus_screenshot, invocation,
FALSE, "");
@@ -94,7 +142,22 @@ handle_flash_area (GfDBusScreenshot *dbus_screenshot,
gint height,
gpointer user_data)
{
- g_warning ("screenshot: flash-area");
+ GfScreenshot *screenshot;
+
+ if (!check_area (x, y, width, height))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ "Invalid params");
+
+ return TRUE;
+ }
+
+ screenshot = GF_SCREENSHOT (user_data);
+
+ scale_area (&x, &y, &width, &height);
+ gf_flashspot_fire (screenshot->flashspot, x, y, width, height);
+
gf_dbus_screenshot_complete_flash_area (dbus_screenshot, invocation);
return TRUE;
@@ -116,6 +179,7 @@ handle_select_area (GfDBusScreenshot *dbus_screenshot,
if (gf_select_area_select (select_area, &x, &y, &width, &height))
{
+ unscale_area (&x, &y, &width, &height);
gf_dbus_screenshot_complete_select_area (dbus_screenshot, invocation,
x, y, width, height);
}
@@ -193,6 +257,8 @@ gf_screenshot_dispose (GObject *object)
screenshot->bus_name = 0;
}
+ g_clear_object (&screenshot->flashspot);
+
G_OBJECT_CLASS (gf_screenshot_parent_class)->dispose (object);
}
@@ -216,6 +282,7 @@ gf_screenshot_init (GfScreenshot *screenshot)
G_BUS_NAME_OWNER_FLAGS_REPLACE,
(GBusAcquiredCallback) bus_acquired_handler,
NULL, NULL, screenshot, NULL);
+ screenshot->flashspot = gf_flashspot_new ();
}
GfScreenshot *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]