/dev/twasilczyk/screenshot: 06a7dd03173c: scrncap: draw over the...

Tomasz Wasilczyk twasilczyk at pidgin.im
Tue Apr 29 12:10:12 EDT 2014


Changeset: 06a7dd03173ce0a69ab9077342c3cb2b0e1c49ec
Author:	 Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date:	 2014-04-29 18:10 +0200
Branch:	 default
URL: https://hg.pidgin.im/dev/twasilczyk/screenshot/rev/06a7dd03173c

Description:

scrncap: draw over the drawing area

diffstat:

 pidgin/plugins/screencap.c |  132 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 126 insertions(+), 6 deletions(-)

diffs (168 lines):

diff --git a/pidgin/plugins/screencap.c b/pidgin/plugins/screencap.c
--- a/pidgin/plugins/screencap.c
+++ b/pidgin/plugins/screencap.c
@@ -44,6 +44,11 @@ static gint crop_origin_x, crop_origin_y
 static gboolean crop_active;
 static gint crop_x, crop_y, crop_w, crop_h;
 
+static gint draw_origin_x, draw_origin_y;
+static gboolean draw_active;
+
+static gint line_width = 2;
+
 /******************************************************************************
  * libpidgin helper functions
  ******************************************************************************/
@@ -112,6 +117,62 @@ scrncap_pixbuf_darken(GdkPixbuf *pixbuf)
  * Draw window
  ******************************************************************************/
 
+static gboolean
+scrncap_drawing_area_btnpress(GtkWidget *draw_area, GdkEventButton *event,
+	gpointer _unused)
+{
+	g_return_val_if_fail(!draw_active, TRUE);
+
+	draw_origin_x = event->x;
+	draw_origin_y = event->y;
+	draw_active = TRUE;
+
+	return TRUE;
+}
+
+static gboolean
+scrncap_drawing_area_btnrelease(GtkWidget *draw_area, GdkEvent *event,
+	gpointer _unused)
+{
+	g_return_val_if_fail(draw_active, TRUE);
+
+	draw_active = FALSE;
+
+	return TRUE;
+}
+
+static gboolean
+scrncap_drawing_area_motion(GtkWidget *draw_area, GdkEventButton *event,
+	gpointer _cr)
+{
+	cairo_t *cr = _cr;
+	int x, y;
+	int redraw_x, redraw_y, redraw_w, redraw_h;
+
+	g_return_val_if_fail(draw_active, FALSE);
+
+	x = event->x;
+	y = event->y;
+
+	cairo_move_to(cr, draw_origin_x, draw_origin_y);
+	cairo_line_to(cr, x, y);
+	cairo_set_line_width(cr, line_width);
+	cairo_stroke(cr);
+
+	redraw_x = MIN(draw_origin_x, x) - line_width - 1;
+	redraw_y = MIN(draw_origin_y, y) - line_width - 1;
+	redraw_w = MAX(draw_origin_x, x) - redraw_x + line_width + 1;
+	redraw_h = MAX(draw_origin_y, y) - redraw_y + line_width + 1;
+
+	draw_origin_x = x;
+	draw_origin_y = y;
+
+	gtk_widget_queue_draw_area(draw_area,
+		redraw_x, redraw_y, redraw_w, redraw_h);
+
+	return FALSE;
+}
+
 static void
 scrncap_draw_window_close(GtkWidget *window, gpointer _unused)
 {
@@ -122,11 +183,41 @@ scrncap_draw_window_close(GtkWidget *win
 	current_window = NULL;
 }
 
+static gboolean
+scrncap_draw_window_paint(GtkWidget *widget, cairo_t *cr, gpointer _surface)
+{
+	cairo_surface_t *surface = _surface;
+
+	cairo_set_source_surface(cr, surface, 0, 0);
+	cairo_paint(cr);
+
+	return FALSE;
+}
+
+#if !GTK_CHECK_VERSION(3,0,0)
+static gboolean
+scrncap_draw_window_expose(GtkWidget *widget, GdkEventExpose *event,
+	gpointer _surface)
+{
+	cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
+
+	scrncap_draw_window_paint(widget, cr, _surface);
+
+	cairo_destroy(cr);
+
+	return FALSE;
+}
+#endif
+
 static void
 scrncap_draw_window(GdkPixbuf *screen)
 {
 	GtkWidget *draw_window;
-	GtkWidget *image;
+	GtkWidget *drawing_area;
+	GtkWidget *scroll_area;
+	int width, height;
+	cairo_t *cr;
+	cairo_surface_t *surface;
 
 	is_shooting = TRUE;
 
@@ -137,12 +228,41 @@ scrncap_draw_window(GdkPixbuf *screen)
 	g_signal_connect(G_OBJECT(draw_window), "destroy",
 		G_CALLBACK(scrncap_draw_window_close), NULL);
 
-	image = gtk_image_new_from_pixbuf(screen);
+	width = gdk_pixbuf_get_width(screen);
+	height = gdk_pixbuf_get_height(screen);
+
+	surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
+	cr = cairo_create(surface);
+
+	gdk_cairo_set_source_pixbuf(cr, screen, 0, 0);
+	cairo_rectangle(cr, 0, 0, width, height);
+	cairo_fill(cr);
 	g_object_unref(screen);
-	gtk_container_add(GTK_CONTAINER(draw_window),
-		pidgin_make_scrollable(image,
-			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
-			GTK_SHADOW_IN, -1, -1));
+
+	cairo_set_source_rgb(cr, 1, 0, 0);
+
+	drawing_area = gtk_drawing_area_new();
+	gtk_widget_set_size_request(drawing_area, width, height);
+#if GTK_CHECK_VERSION(3,0,0)
+	g_signal_connect(G_OBJECT(drawing_area), "draw",
+		G_CALLBACK(scrncap_draw_window_paint), surface);
+#else
+	g_signal_connect(G_OBJECT(drawing_area), "expose_event",
+		G_CALLBACK(scrncap_draw_window_expose), surface);
+#endif
+	gtk_widget_add_events(drawing_area, GDK_BUTTON_PRESS_MASK |
+		GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK);
+	g_signal_connect(G_OBJECT(drawing_area), "button-press-event",
+		G_CALLBACK(scrncap_drawing_area_btnpress), NULL);
+	g_signal_connect(G_OBJECT(drawing_area), "button-release-event",
+		G_CALLBACK(scrncap_drawing_area_btnrelease), NULL);
+	g_signal_connect(G_OBJECT(drawing_area), "motion-notify-event",
+		G_CALLBACK(scrncap_drawing_area_motion), cr);
+
+	scroll_area = pidgin_make_scrollable(drawing_area,
+		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
+		GTK_SHADOW_IN, -1, -1);
+	gtk_container_add(GTK_CONTAINER(draw_window), scroll_area);
 
 	gtk_widget_show_all(GTK_WIDGET(draw_window));
 }



More information about the Commits mailing list