[gnome-utils] screenshot: move the interactive area selection into a separate file



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 (&region_rect);
+          region_rect.x++;
+          region_rect.y++;
+          region_rect.width -= 2;
+          region_rect.height -= 2;
+          cairo_region_subtract_rectangle (region, &region_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 (&region_rect);
-          region_rect.x++;
-          region_rect.y++;
-          region_rect.width -= 2;
-          region_rect.height -= 2;
-          cairo_region_subtract_rectangle (region, &region_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]