Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-utils/gnome-screenshot/ChangeLog,v
retrieving revision 1.10
diff -u -p -r1.10 ChangeLog
--- ChangeLog	16 May 2005 19:32:04 -0000	1.10
+++ ChangeLog	17 Jul 2005 17:42:08 -0000
@@ -1,3 +1,23 @@
+2005-07-17	Madhan Raj M <madhanrm@cvs.gnome.org>
+
+	* gnome-panel-screenshot.c: (prepare_screenshot_selection)
+		
+	* screenshot-dialog.c: (on_selection_button_clicked),
+	  (screenshot_dialog_new)
+		
+	* screenshot-utils.c: (screenshot_get_pixbuf)
+		
+	* screenshot-selection.c: New functions added to capture 
+	  a selection. Most of the code is from panel-force-quit.c.
+	  
+	* screenshot-selection.h: (ScreenshotSelection)
+
+	* gnome-screenshot.glade: Create a new button "Selection"
+
+	* Makefile.am:
+	Added a feature to capture screen selection. 
+	Fixes bug #155061.
+	
 2005-05-16  Olav Vitters <olav@bkor.dhs.org>
 
 	* gnome-panel-screenshot.c: Fix typo in gconf key (gnome_screenshot
Index: gnome-panel-screenshot.c
===================================================================
RCS file: /cvs/gnome/gnome-utils/gnome-screenshot/gnome-panel-screenshot.c,v
retrieving revision 1.85
diff -u -p -r1.85 gnome-panel-screenshot.c
--- gnome-panel-screenshot.c	16 May 2005 19:32:04 -0000	1.85
+++ gnome-panel-screenshot.c	17 Jul 2005 17:42:09 -0000
@@ -284,7 +284,7 @@ run_dialog (ScreenshotDialog *dialog)
 }
 
 static void
-prepare_screenshot (void)
+prepare_screenshot (ScreenshotSelection *selection)
 {
   ScreenshotDialog *dialog;
   Window win;
@@ -316,7 +316,7 @@ prepare_screenshot (void)
       win = GDK_ROOT_WINDOW ();
     }
 
-  screenshot = screenshot_get_pixbuf (win);
+  screenshot = screenshot_get_pixbuf (win, selection);
 
   if (take_window_shot && drop_shadow)
     {
@@ -357,11 +357,17 @@ static gboolean
 prepare_screenshot_timeout (gpointer data)
 {
   gtk_main_quit ();
-  prepare_screenshot ();
+  prepare_screenshot (NULL);
 
   return FALSE;
 }
 
+void
+prepare_screenshot_selection (ScreenshotSelection *selection)
+{
+	prepare_screenshot (selection); 	
+}
+
 /* Load options */
 static void
 load_options (void)
@@ -455,7 +461,7 @@ main (int argc, char *argv[])
     }
   else
     {
-      prepare_screenshot ();
+      prepare_screenshot (NULL);
     }
 
   return 0;
Index: screenshot-dialog.c
===================================================================
RCS file: /cvs/gnome/gnome-utils/gnome-screenshot/screenshot-dialog.c,v
retrieving revision 1.6
diff -u -p -r1.6 screenshot-dialog.c
--- screenshot-dialog.c	22 Jan 2005 12:34:12 -0000	1.6
+++ screenshot-dialog.c	17 Jul 2005 17:42:09 -0000
@@ -1,6 +1,7 @@
 #include <config.h>
 #include "screenshot-dialog.h"
 #include "screenshot-save.h"
+#include "screenshot-selection.h"
 #include <gnome.h>
 
 
@@ -155,6 +156,12 @@ drag_begin (GtkWidget        *widget,
 			    dialog->drag_x, dialog->drag_y);
 }
 
+static void
+on_selection_button_clicked (GtkButton *button, gpointer data)
+{
+	GtkWidget *widget = GTK_WIDGET (button), *toplevel = data;	
+	selection_info_dialog (gtk_widget_get_screen (widget), toplevel);	
+}
 
 ScreenshotDialog *
 screenshot_dialog_new (GdkPixbuf *screenshot,
@@ -162,6 +169,7 @@ screenshot_dialog_new (GdkPixbuf *screen
 		       gboolean   take_window_shot)
 {
   ScreenshotDialog *dialog;
+  GtkWidget *selection_button;
   GtkWidget *toplevel;
   GtkWidget *preview_darea;
   GtkWidget *aspect_frame;
@@ -205,6 +213,7 @@ screenshot_dialog_new (GdkPixbuf *screen
   height /= 5;
 
   toplevel = glade_xml_get_widget (dialog->xml, "toplevel");
+  selection_button = glade_xml_get_widget (dialog->xml, "selection_button");
   aspect_frame = glade_xml_get_widget (dialog->xml, "aspect_frame");
   preview_darea = glade_xml_get_widget (dialog->xml, "preview_darea");
   dialog->filename_entry = glade_xml_get_widget (dialog->xml, "filename_entry");
@@ -225,6 +234,7 @@ screenshot_dialog_new (GdkPixbuf *screen
 			(gfloat) gdk_pixbuf_get_height (screenshot),
 			FALSE);
   g_signal_connect (toplevel, "key_press_event", G_CALLBACK (on_toplevel_key_press_event), dialog);
+  g_signal_connect (selection_button, "clicked", G_CALLBACK (on_selection_button_clicked), toplevel);
   g_signal_connect (preview_darea, "expose_event", G_CALLBACK (on_preview_expose_event), dialog);
   g_signal_connect (preview_darea, "button_press_event", G_CALLBACK (on_preview_button_press_event), dialog);
   g_signal_connect (preview_darea, "button_release_event", G_CALLBACK (on_preview_button_release_event), dialog);
Index: screenshot-utils.c
===================================================================
RCS file: /cvs/gnome/gnome-utils/gnome-screenshot/screenshot-utils.c,v
retrieving revision 1.2
diff -u -p -r1.2 screenshot-utils.c
--- screenshot-utils.c	24 Oct 2004 01:23:39 -0000	1.2
+++ screenshot-utils.c	17 Jul 2005 17:42:10 -0000
@@ -455,7 +455,7 @@ screenshot_find_current_window (gboolean
 }
 
 GdkPixbuf *
-screenshot_get_pixbuf (Window w)
+screenshot_get_pixbuf (Window w, ScreenshotSelection *selection)
 {
   GdkWindow *window;
   GdkPixbuf *screenshot;
@@ -476,9 +476,16 @@ screenshot_get_pixbuf (Window w)
   if (window == NULL)
     return NULL;
 
-  gdk_drawable_get_size (window, &real_width, &real_height);
-  gdk_window_get_origin (window, &x_real_orig, &y_real_orig);
-
+  if (selection == NULL) {
+  	gdk_drawable_get_size (window, &real_width, &real_height);
+  	gdk_window_get_origin (window, &x_real_orig, &y_real_orig);
+  } else {
+    real_width = selection->width;
+    real_height = selection->height;
+    x = x_real_orig = selection->start_x;
+    y = y_real_orig = selection->start_y;
+  }
+  
   x_orig = x_real_orig;
   y_orig = y_real_orig;
   width = real_width;
@@ -510,7 +517,7 @@ screenshot_get_pixbuf (Window w)
 
   rectangles = XShapeGetRectangles (GDK_DISPLAY (), GDK_WINDOW_XWINDOW (window),
 				    ShapeBounding, &rectangle_count, &rectangle_order);
-  if (rectangle_count > 0)
+  if (rectangle_count > 0 && selection == NULL)
     {
       gboolean has_alpha = gdk_pixbuf_get_has_alpha (tmp);
 
@@ -579,6 +586,8 @@ screenshot_get_pixbuf (Window w)
 					     x, y, 0, 0,
 					     width, height);
 #endif /* HAVE_X11_EXTENSIONS_SHAPE_H */
+  if (selection)
+  	g_free (selection);
 
   return screenshot;
 }
Index: gnome-screenshot.glade
===================================================================
RCS file: /cvs/gnome/gnome-utils/gnome-screenshot/gnome-screenshot.glade,v
retrieving revision 1.3
diff -u -p -r1.3 gnome-screenshot.glade
--- gnome-screenshot.glade	21 Dec 2004 23:33:59 -0000	1.3
+++ gnome-screenshot.glade	17 Jul 2005 17:42:10 -0000
@@ -45,6 +45,19 @@
 	  </child>
 
 	  <child>
+	    <widget class="GtkButton" id="selection_button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">Se_lection</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">0</property>
+	    </widget>
+	  </child>
+
+	  <child>
 	    <widget class="GtkButton" id="cancel_button">
 	      <property name="visible">True</property>
 	      <property name="can_default">True</property>
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-utils/gnome-screenshot/Makefile.am,v
retrieving revision 1.1
diff -u -p -r1.1 Makefile.am
--- Makefile.am	3 Nov 2004 16:45:00 -0000	1.1
+++ Makefile.am	17 Jul 2005 17:42:10 -0000
@@ -27,6 +27,8 @@ gnome_screenshot_SOURCES = \
 	screenshot-dialog.h		\
 	screenshot-shadow.c		\
 	screenshot-shadow.h		\
+	screenshot-selection.c		\
+	screenshot-selection.h		\
 	screenshot-utils.c		\
 	screenshot-utils.h		\
 	gnome-egg-xfer-dialog.c		\
--- /dev/null	2005-07-16 02:37:44.277102296 +0530
+++ screenshot-selection.c	2005-07-17 23:10:39.519826136 +0530
@@ -0,0 +1,197 @@
+#include <config.h>
+
+#include "screenshot-selection.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+
+static GdkFilterReturn popup_filter (GdkXEvent *gdk_xevent,
+				GdkEvent  *event,
+				GtkWidget *popup);
+
+static Atom wm_state_atom = None;
+static GtkWidget *label;
+static ScreenshotSelection *selection;
+
+static GtkWidget *
+display_popup_window (GdkScreen * screen)
+{
+  GtkWidget *info;
+  GtkWidget *vbox;
+  GtkWidget *image;
+  GtkWidget *frame;
+  int screen_width, screen_height;
+
+  info = gtk_window_new (GTK_WINDOW_POPUP);
+  atk_object_set_role (gtk_widget_get_accessible (info), ATK_ROLE_ALERT);
+  gtk_window_set_screen (GTK_WINDOW (info), screen);
+  gtk_window_stick (GTK_WINDOW (info));
+  gtk_widget_add_events (info, 
+				 GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_MOTION_NOTIFY );
+  frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
+  gtk_container_add (GTK_CONTAINER (info), frame);
+  gtk_widget_show (frame);
+
+  vbox = gtk_vbox_new (FALSE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
+  gtk_container_add (GTK_CONTAINER (frame), vbox);
+  gtk_widget_show (vbox);
+
+  label = gtk_label_new ("");
+  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+  gtk_label_set_markup (GTK_LABEL (label), _("<b>Select the area on \nthe screen\n ESC to cancel</b>"));
+  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+  gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 4);
+  gtk_widget_show (label);
+
+  label = gtk_label_new (" ");
+  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+  gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 4);
+  gtk_widget_show (label);
+
+  gtk_widget_realize (info);
+  screen_width  = gdk_screen_get_width  (screen);
+  screen_height = gdk_screen_get_height (screen);
+
+  gtk_window_move (GTK_WINDOW (info),
+				  screen_width - 175, screen_height - 100);
+
+  gtk_widget_show (GTK_WIDGET (info));
+  return info;
+}
+
+static void
+remove_popup (GtkWidget *popup)
+{
+  GdkWindow *root;
+
+  root = gdk_screen_get_root_window (
+			gtk_window_get_screen (GTK_WINDOW (popup)));
+  gdk_window_remove_filter (root, (GdkFilterFunc) popup_filter, popup);
+
+  gtk_widget_destroy (popup);
+  gdk_pointer_ungrab (GDK_CURRENT_TIME);
+  gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+  gtk_main_quit ();
+}
+
+static void
+compute_selection_coordinates (gint start_x, gint start_y, gint end_x, gint end_y)
+{
+  if (end_x > start_x && end_y > start_y) {
+  } else if (end_x < start_x && end_y > start_y) {
+	selection->start_x = end_x;
+	selection->start_y = start_y;
+  } else if (end_x < start_x && end_y < start_y) {
+ 	selection->start_x = end_x;
+	selection->start_y = end_y;
+  } else if (end_x > start_x && end_y < start_y) {
+	selection->start_x = start_x;
+	selection->start_y = end_y;
+  }
+  selection->height = end_y - start_y; 
+  selection->width = end_x - start_x;
+  if (selection->height < 0)
+	selection->height = - selection->height;	  
+  if (selection->width < 0)
+	selection->width = - selection->width;
+}
+
+static void
+handle_motion_notify_event (XKeyEvent *event)
+{
+  char *str[20];
+  sprintf (str, "X->%d Y->%d", event->x_root, event->y_root);
+  gtk_label_set_text (GTK_LABEL (label), str);
+}
+
+static void
+handle_button_press_event (XKeyEvent *event)
+{
+  selection->start_x = event->x_root;
+  selection->start_y = event->y_root;
+}
+
+static void
+handle_button_release_event (XKeyEvent *event)
+{
+  compute_selection_coordinates (selection->start_x, selection->start_y, 
+				  				event->x_root, event->y_root);
+}
+
+GdkFilterReturn
+popup_filter (GdkXEvent *gdk_xevent,
+				GdkEvent  *event,
+				GtkWidget *popup)
+{
+  XEvent *xevent = (XEvent *) gdk_xevent;
+
+  switch (xevent->type) {
+ 	case ButtonPress:
+		handle_button_press_event (&xevent->xkey);
+		break;
+	case ButtonRelease:
+		handle_button_release_event (&xevent->xkey);
+		remove_popup (popup);
+		return GDK_FILTER_REMOVE;
+	case MotionNotify:
+		handle_motion_notify_event (&xevent->xkey);
+		return GDK_FILTER_REMOVE;
+	case KeyPress:
+		if (xevent->xkey.keycode == XKeysymToKeycode (gdk_display, XK_Escape)) {
+			remove_popup (popup);
+			exit (0);
+			return GDK_FILTER_REMOVE;
+		}
+		break;
+	default:
+		break;
+  }
+ 
+  return GDK_FILTER_CONTINUE;
+}
+
+void
+selection_info_dialog (GdkScreen *screen, GtkWidget *toplevel)
+{
+  GdkGrabStatus  status;
+  GdkCursor     *cross;
+  GtkWidget     *popup;
+  GdkWindow *root;
+  
+  popup = display_popup_window (screen);
+  
+  gtk_widget_destroy (toplevel); 
+  selection = g_new0 (ScreenshotSelection, 1);
+  
+  root = gdk_screen_get_root_window (screen);
+  
+  gdk_window_add_filter (root, (GdkFilterFunc) popup_filter, popup);
+  cross = gdk_cursor_new (GDK_CROSSHAIR);
+  status = gdk_pointer_grab (root, FALSE,
+				GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK,
+ 				NULL, cross, GDK_CURRENT_TIME);
+  gdk_cursor_unref (cross);
+  if (status != GDK_GRAB_SUCCESS) {
+  	g_warning ("Pointer grab failed\n");
+  	remove_popup (popup);
+  	return;
+  }
+
+  status = gdk_keyboard_grab (root, FALSE, GDK_CURRENT_TIME);
+  if (status != GDK_GRAB_SUCCESS) {
+  		g_warning ("Keyboard grab failed\n");
+  		remove_popup (popup);
+  		return;
+  }
+  gdk_flush ();
+  gtk_main ();
+  prepare_screenshot_selection (selection);
+}
+
--- /dev/null	2005-07-16 02:37:44.277102296 +0530
+++ screenshot-selection.h	2005-07-17 21:25:32.267674208 +0530
@@ -0,0 +1,17 @@
+#ifndef __SCREENSHOT_SELECTION_H__
+#define __SCREENSHOT_SELECTION_H__
+
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+typedef struct ScreenshotSelection
+{
+	gint start_x;
+	gint start_y;
+	gint height;
+	gint width;
+}ScreenshotSelection;
+
+void selection_info_dialog (GdkScreen *screen, GtkWidget *toplevel);
+
+#endif /* __SCREENSHOT_SELECTION_H__ */
