[gnome-utils] screenshot: move the interactive area selection into a separate file
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-utils] screenshot: move the interactive area selection into a separate file
- Date: Mon, 26 Sep 2011 20:57:14 +0000 (UTC)
commit 64190c8772e2aedbede806f8d7e6770c532eb6be
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Mon Sep 26 16:05:17 2011 -0400
screenshot: move the interactive area selection into a separate file
gnome-screenshot/Makefile.am | 2 +
gnome-screenshot/gnome-screenshot.c | 1 +
gnome-screenshot/screenshot-area-selection.c | 276 ++++++++++++++++++++++++++
gnome-screenshot/screenshot-area-selection.h | 34 ++++
gnome-screenshot/screenshot-utils.c | 252 -----------------------
gnome-screenshot/screenshot-utils.h | 3 -
6 files changed, 313 insertions(+), 255 deletions(-)
---
diff --git a/gnome-screenshot/Makefile.am b/gnome-screenshot/Makefile.am
index 4f0d498..c53a2f5 100644
--- a/gnome-screenshot/Makefile.am
+++ b/gnome-screenshot/Makefile.am
@@ -15,6 +15,8 @@ gnome_screenshot_SOURCES = \
gnome-screenshot.c \
cheese-flash.c \
cheese-flash.h \
+ screenshot-area-selection.c \
+ screenshot-area-selection.h \
screenshot-config.c \
screenshot-config.h \
screenshot-dialog.c \
diff --git a/gnome-screenshot/gnome-screenshot.c b/gnome-screenshot/gnome-screenshot.c
index ed3a3e0..60b58d3 100644
--- a/gnome-screenshot/gnome-screenshot.c
+++ b/gnome-screenshot/gnome-screenshot.c
@@ -41,6 +41,7 @@
#include <X11/Xutil.h>
#include <canberra-gtk.h>
+#include "screenshot-area-selection.h"
#include "screenshot-config.h"
#include "screenshot-filename-builder.h"
#include "screenshot-interactive-dialog.h"
diff --git a/gnome-screenshot/screenshot-area-selection.c b/gnome-screenshot/screenshot-area-selection.c
new file mode 100644
index 0000000..01475d8
--- /dev/null
+++ b/gnome-screenshot/screenshot-area-selection.c
@@ -0,0 +1,276 @@
+/* screenshot-area-selection.c - interactive screenshot area selection
+ *
+ * Copyright (C) 2001-2006 Jonathan Blandford <jrb alum mit edu>
+ * Copyright (C) 2008 Cosimo Cecchi <cosimoc gnome org>
+ *
+ * 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+
+#include "screenshot-area-selection.h"
+
+typedef struct {
+ GdkRectangle rect;
+ gboolean button_pressed;
+ GtkWidget *window;
+} select_area_filter_data;
+
+static gboolean
+select_area_button_press (GtkWidget *window,
+ GdkEventButton *event,
+ select_area_filter_data *data)
+{
+ if (data->button_pressed)
+ return TRUE;
+
+ data->button_pressed = TRUE;
+ data->rect.x = event->x_root;
+ data->rect.y = event->y_root;
+
+ return TRUE;
+}
+
+static gboolean
+select_area_motion_notify (GtkWidget *window,
+ GdkEventMotion *event,
+ select_area_filter_data *data)
+{
+ GdkRectangle draw_rect;
+
+ if (!data->button_pressed)
+ return TRUE;
+
+ draw_rect.width = ABS (data->rect.x - event->x_root);
+ draw_rect.height = ABS (data->rect.y - event->y_root);
+ draw_rect.x = MIN (data->rect.x, event->x_root);
+ draw_rect.y = MIN (data->rect.y, event->y_root);
+
+ if (draw_rect.width <= 0 || draw_rect.height <= 0)
+ {
+ gtk_window_move (GTK_WINDOW (window), -100, -100);
+ gtk_window_resize (GTK_WINDOW (window), 10, 10);
+ return TRUE;
+ }
+
+ gtk_window_move (GTK_WINDOW (window), draw_rect.x, draw_rect.y);
+ gtk_window_resize (GTK_WINDOW (window), draw_rect.width, draw_rect.height);
+
+ /* We (ab)use app-paintable to indicate if we have an RGBA window */
+ if (!gtk_widget_get_app_paintable (window))
+ {
+ GdkWindow *gdkwindow = gtk_widget_get_window (window);
+
+ /* Shape the window to make only the outline visible */
+ if (draw_rect.width > 2 && draw_rect.height > 2)
+ {
+ cairo_region_t *region;
+ cairo_rectangle_int_t region_rect = {
+ 0, 0,
+ draw_rect.width, draw_rect.height
+ };
+
+ region = cairo_region_create_rectangle (®ion_rect);
+ region_rect.x++;
+ region_rect.y++;
+ region_rect.width -= 2;
+ region_rect.height -= 2;
+ cairo_region_subtract_rectangle (region, ®ion_rect);
+
+ gdk_window_shape_combine_region (gdkwindow, region, 0, 0);
+
+ cairo_region_destroy (region);
+ }
+ else
+ gdk_window_shape_combine_region (gdkwindow, NULL, 0, 0);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+select_area_button_release (GtkWidget *window,
+ GdkEventButton *event,
+ select_area_filter_data *data)
+{
+ if (!data->button_pressed)
+ return TRUE;
+
+ data->rect.width = ABS (data->rect.x - event->x_root);
+ data->rect.height = ABS (data->rect.y - event->y_root);
+ data->rect.x = MIN (data->rect.x, event->x_root);
+ data->rect.y = MIN (data->rect.y, event->y_root);
+
+ gtk_main_quit ();
+
+ return TRUE;
+}
+
+static gboolean
+select_area_key_press (GtkWidget *window,
+ GdkEventKey *event,
+ select_area_filter_data *data)
+{
+ if (event->keyval == GDK_KEY_Escape)
+ {
+ data->rect.x = 0;
+ data->rect.y = 0;
+ data->rect.width = 0;
+ data->rect.height = 0;
+ gtk_main_quit ();
+ }
+
+ return TRUE;
+}
+
+static gboolean
+select_window_draw (GtkWidget *window, cairo_t *cr, gpointer unused)
+{
+ GtkAllocation allocation;
+ GtkStyle *style;
+
+ style = gtk_widget_get_style (window);
+
+ if (gtk_widget_get_app_paintable (window))
+ {
+ cairo_set_line_width (cr, 1.0);
+
+ gtk_widget_get_allocation (window, &allocation);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_SELECTED]);
+ cairo_paint_with_alpha (cr, 0.25);
+
+ cairo_rectangle (cr,
+ allocation.x + 0.5, allocation.y + 0.5,
+ allocation.width - 1, allocation.height - 1);
+ cairo_stroke (cr);
+ }
+ else
+ {
+ gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_SELECTED]);
+ cairo_paint (cr);
+ }
+
+ return TRUE;
+}
+
+static GtkWidget *
+create_select_window (void)
+{
+ GtkWidget *window;
+ GdkScreen *screen;
+ GdkVisual *visual;
+
+ screen = gdk_screen_get_default ();
+ visual = gdk_screen_get_rgba_visual (screen);
+
+ window = gtk_window_new (GTK_WINDOW_POPUP);
+ if (gdk_screen_is_composited (screen) && visual)
+ {
+ gtk_widget_set_visual (window, visual);
+ gtk_widget_set_app_paintable (window, TRUE);
+ }
+
+ g_signal_connect (window, "draw", G_CALLBACK (select_window_draw), NULL);
+
+ gtk_window_move (GTK_WINDOW (window), -100, -100);
+ gtk_window_resize (GTK_WINDOW (window), 10, 10);
+ gtk_widget_show (window);
+
+ return window;
+}
+
+typedef struct {
+ GdkRectangle rectangle;
+ SelectAreaCallback callback;
+} CallbackData;
+
+static gboolean
+emit_select_callback_in_idle (gpointer user_data)
+{
+ CallbackData *data = user_data;
+
+ data->callback (&data->rectangle);
+
+ g_slice_free (CallbackData, data);
+
+ return FALSE;
+}
+
+void
+screenshot_select_area_async (SelectAreaCallback callback)
+{
+ GdkCursor *cursor;
+ select_area_filter_data data;
+ CallbackData *cb_data;
+
+ data.rect.x = 0;
+ data.rect.y = 0;
+ data.rect.width = 0;
+ data.rect.height = 0;
+ data.button_pressed = FALSE;
+ data.window = create_select_window();
+
+ cb_data = g_slice_new0 (CallbackData);
+ cb_data->callback = callback;
+
+ g_signal_connect (data.window, "key-press-event", G_CALLBACK (select_area_key_press), &data);
+ g_signal_connect (data.window, "button-press-event", G_CALLBACK (select_area_button_press), &data);
+ g_signal_connect (data.window, "button-release-event", G_CALLBACK (select_area_button_release), &data);
+ g_signal_connect (data.window, "motion-notify-event", G_CALLBACK (select_area_motion_notify), &data);
+
+ cursor = gdk_cursor_new (GDK_CROSSHAIR);
+
+ if (gdk_pointer_grab (gtk_widget_get_window (data.window), FALSE,
+ GDK_POINTER_MOTION_MASK|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK,
+ NULL, cursor,
+ GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
+ {
+ gdk_cursor_unref (cursor);
+ goto out;
+ }
+
+ if (gdk_keyboard_grab (gtk_widget_get_window (data.window), FALSE, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
+ {
+ gdk_pointer_ungrab (GDK_CURRENT_TIME);
+ gdk_cursor_unref (cursor);
+ goto out;
+ }
+
+ gtk_main ();
+
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+ gdk_pointer_ungrab (GDK_CURRENT_TIME);
+
+ gtk_widget_destroy (data.window);
+ gdk_cursor_unref (cursor);
+
+ gdk_flush ();
+
+ out:
+ cb_data->rectangle = data.rect;
+
+ /* FIXME: we should actually be emitting the callback When
+ * the compositor has finished re-drawing, but there seems to be no easy
+ * way to know that.
+ */
+ g_timeout_add (200, emit_select_callback_in_idle, cb_data);
+}
diff --git a/gnome-screenshot/screenshot-area-selection.h b/gnome-screenshot/screenshot-area-selection.h
new file mode 100644
index 0000000..c2f556a
--- /dev/null
+++ b/gnome-screenshot/screenshot-area-selection.h
@@ -0,0 +1,34 @@
+/* screenshot-area-selection.h - interactive screenshot area selection
+ *
+ * Copyright (C) 2001-2006 Jonathan Blandford <jrb alum mit edu>
+ * Copyright (C) 2008 Cosimo Cecchi <cosimoc gnome org>
+ *
+ * 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ */
+
+#ifndef __SCREENSHOT_AREA_SELECTION_H__
+#define __SCREENSHOT_AREA_SELECTION_H__
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+typedef void (* SelectAreaCallback) (GdkRectangle *rectangle);
+
+void screenshot_select_area_async (SelectAreaCallback callback);
+
+G_END_DECLS
+
+#endif /* __SCREENSHOT_AREA_SELECTION_H__ */
diff --git a/gnome-screenshot/screenshot-utils.c b/gnome-screenshot/screenshot-utils.c
index 47ec592..4346f0d 100644
--- a/gnome-screenshot/screenshot-utils.c
+++ b/gnome-screenshot/screenshot-utils.c
@@ -141,258 +141,6 @@ screenshot_find_current_window ()
return current_window;
}
-typedef struct {
- GdkRectangle rect;
- gboolean button_pressed;
- GtkWidget *window;
-} select_area_filter_data;
-
-static gboolean
-select_area_button_press (GtkWidget *window,
- GdkEventButton *event,
- select_area_filter_data *data)
-{
- if (data->button_pressed)
- return TRUE;
-
- data->button_pressed = TRUE;
- data->rect.x = event->x_root;
- data->rect.y = event->y_root;
-
- return TRUE;
-}
-
-static gboolean
-select_area_motion_notify (GtkWidget *window,
- GdkEventMotion *event,
- select_area_filter_data *data)
-{
- GdkRectangle draw_rect;
-
- if (!data->button_pressed)
- return TRUE;
-
- draw_rect.width = ABS (data->rect.x - event->x_root);
- draw_rect.height = ABS (data->rect.y - event->y_root);
- draw_rect.x = MIN (data->rect.x, event->x_root);
- draw_rect.y = MIN (data->rect.y, event->y_root);
-
- if (draw_rect.width <= 0 || draw_rect.height <= 0)
- {
- gtk_window_move (GTK_WINDOW (window), -100, -100);
- gtk_window_resize (GTK_WINDOW (window), 10, 10);
- return TRUE;
- }
-
- gtk_window_move (GTK_WINDOW (window), draw_rect.x, draw_rect.y);
- gtk_window_resize (GTK_WINDOW (window), draw_rect.width, draw_rect.height);
-
- /* We (ab)use app-paintable to indicate if we have an RGBA window */
- if (!gtk_widget_get_app_paintable (window))
- {
- GdkWindow *gdkwindow = gtk_widget_get_window (window);
-
- /* Shape the window to make only the outline visible */
- if (draw_rect.width > 2 && draw_rect.height > 2)
- {
- cairo_region_t *region;
- cairo_rectangle_int_t region_rect = {
- 0, 0,
- draw_rect.width, draw_rect.height
- };
-
- region = cairo_region_create_rectangle (®ion_rect);
- region_rect.x++;
- region_rect.y++;
- region_rect.width -= 2;
- region_rect.height -= 2;
- cairo_region_subtract_rectangle (region, ®ion_rect);
-
- gdk_window_shape_combine_region (gdkwindow, region, 0, 0);
-
- cairo_region_destroy (region);
- }
- else
- gdk_window_shape_combine_region (gdkwindow, NULL, 0, 0);
- }
-
- return TRUE;
-}
-
-static gboolean
-select_area_button_release (GtkWidget *window,
- GdkEventButton *event,
- select_area_filter_data *data)
-{
- if (!data->button_pressed)
- return TRUE;
-
- data->rect.width = ABS (data->rect.x - event->x_root);
- data->rect.height = ABS (data->rect.y - event->y_root);
- data->rect.x = MIN (data->rect.x, event->x_root);
- data->rect.y = MIN (data->rect.y, event->y_root);
-
- gtk_main_quit ();
-
- return TRUE;
-}
-
-static gboolean
-select_area_key_press (GtkWidget *window,
- GdkEventKey *event,
- select_area_filter_data *data)
-{
- if (event->keyval == GDK_KEY_Escape)
- {
- data->rect.x = 0;
- data->rect.y = 0;
- data->rect.width = 0;
- data->rect.height = 0;
- gtk_main_quit ();
- }
-
- return TRUE;
-}
-
-static gboolean
-select_window_draw (GtkWidget *window, cairo_t *cr, gpointer unused)
-{
- GtkAllocation allocation;
- GtkStyle *style;
-
- style = gtk_widget_get_style (window);
-
- if (gtk_widget_get_app_paintable (window))
- {
- cairo_set_line_width (cr, 1.0);
-
- gtk_widget_get_allocation (window, &allocation);
-
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba (cr, 0, 0, 0, 0);
- cairo_paint (cr);
-
- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
- gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_SELECTED]);
- cairo_paint_with_alpha (cr, 0.25);
-
- cairo_rectangle (cr,
- allocation.x + 0.5, allocation.y + 0.5,
- allocation.width - 1, allocation.height - 1);
- cairo_stroke (cr);
- }
- else
- {
- gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_SELECTED]);
- cairo_paint (cr);
- }
-
- return TRUE;
-}
-
-static GtkWidget *
-create_select_window (void)
-{
- GtkWidget *window;
- GdkScreen *screen;
- GdkVisual *visual;
-
- screen = gdk_screen_get_default ();
- visual = gdk_screen_get_rgba_visual (screen);
-
- window = gtk_window_new (GTK_WINDOW_POPUP);
- if (gdk_screen_is_composited (screen) && visual)
- {
- gtk_widget_set_visual (window, visual);
- gtk_widget_set_app_paintable (window, TRUE);
- }
-
- g_signal_connect (window, "draw", G_CALLBACK (select_window_draw), NULL);
-
- gtk_window_move (GTK_WINDOW (window), -100, -100);
- gtk_window_resize (GTK_WINDOW (window), 10, 10);
- gtk_widget_show (window);
-
- return window;
-}
-
-typedef struct {
- GdkRectangle rectangle;
- SelectAreaCallback callback;
-} CallbackData;
-
-static gboolean
-emit_select_callback_in_idle (gpointer user_data)
-{
- CallbackData *data = user_data;
-
- data->callback (&data->rectangle);
-
- g_slice_free (CallbackData, data);
-
- return FALSE;
-}
-
-void
-screenshot_select_area_async (SelectAreaCallback callback)
-{
- GdkCursor *cursor;
- select_area_filter_data data;
- CallbackData *cb_data;
-
- data.rect.x = 0;
- data.rect.y = 0;
- data.rect.width = 0;
- data.rect.height = 0;
- data.button_pressed = FALSE;
- data.window = create_select_window();
-
- cb_data = g_slice_new0 (CallbackData);
- cb_data->callback = callback;
-
- g_signal_connect (data.window, "key-press-event", G_CALLBACK (select_area_key_press), &data);
- g_signal_connect (data.window, "button-press-event", G_CALLBACK (select_area_button_press), &data);
- g_signal_connect (data.window, "button-release-event", G_CALLBACK (select_area_button_release), &data);
- g_signal_connect (data.window, "motion-notify-event", G_CALLBACK (select_area_motion_notify), &data);
-
- cursor = gdk_cursor_new (GDK_CROSSHAIR);
-
- if (gdk_pointer_grab (gtk_widget_get_window (data.window), FALSE,
- GDK_POINTER_MOTION_MASK|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK,
- NULL, cursor,
- GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
- {
- gdk_cursor_unref (cursor);
- goto out;
- }
-
- if (gdk_keyboard_grab (gtk_widget_get_window (data.window), FALSE, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
- {
- gdk_pointer_ungrab (GDK_CURRENT_TIME);
- gdk_cursor_unref (cursor);
- goto out;
- }
-
- gtk_main ();
-
- gdk_keyboard_ungrab (GDK_CURRENT_TIME);
- gdk_pointer_ungrab (GDK_CURRENT_TIME);
-
- gtk_widget_destroy (data.window);
- gdk_cursor_unref (cursor);
-
- gdk_flush ();
-
- out:
- cb_data->rectangle = data.rect;
-
- /* FIXME: we should actually be emitting the callback When
- * the compositor has finished re-drawing, but there seems to be no easy
- * way to know that.
- */
- g_timeout_add (200, emit_select_callback_in_idle, cb_data);
-}
-
static Window
find_wm_window (GdkWindow *window)
{
diff --git a/gnome-screenshot/screenshot-utils.h b/gnome-screenshot/screenshot-utils.h
index 5de53c4..c6697eb 100644
--- a/gnome-screenshot/screenshot-utils.h
+++ b/gnome-screenshot/screenshot-utils.h
@@ -25,14 +25,11 @@
G_BEGIN_DECLS
-typedef void (* SelectAreaCallback) (GdkRectangle *rectangle);
-
gboolean screenshot_grab_lock (void);
void screenshot_release_lock (void);
void screenshot_get_window_rect (GdkWindow *win,
GdkRectangle *rect);
GdkWindow *screenshot_find_current_window (void);
-void screenshot_select_area_async (SelectAreaCallback callback);
GdkPixbuf *screenshot_get_pixbuf (GdkWindow *win,
GdkRectangle *rectangle);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]