/dev/twasilczyk/screenshot: 44e9ed3cc8fe: scrncap: add resulting...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Tue Apr 29 13:25:25 EDT 2014
Changeset: 44e9ed3cc8fe33712a6a018e70e3d795dc8b7b47
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-04-29 19:25 +0200
Branch: default
URL: https://hg.pidgin.im/dev/twasilczyk/screenshot/rev/44e9ed3cc8fe
Description:
scrncap: add resulting image to the webview
diffstat:
libpurple/image.c | 2 +-
libpurple/image.h | 2 +-
pidgin/plugins/screencap.c | 118 ++++++++++++++++++++++++++++++++++++++++----
3 files changed, 108 insertions(+), 14 deletions(-)
diffs (228 lines):
diff --git a/libpurple/image.c b/libpurple/image.c
--- a/libpurple/image.c
+++ b/libpurple/image.c
@@ -451,7 +451,7 @@ purple_image_transfer_new(void)
}
void
-purple_image_transfer_write(PurpleImage *image, const gpointer data,
+purple_image_transfer_write(PurpleImage *image, gconstpointer data,
gsize length)
{
PurpleImagePrivate *priv =
diff --git a/libpurple/image.h b/libpurple/image.h
--- a/libpurple/image.h
+++ b/libpurple/image.h
@@ -277,7 +277,7 @@ purple_image_transfer_new(void);
* a remote file.
*/
void
-purple_image_transfer_write(PurpleImage *image, const gpointer data,
+purple_image_transfer_write(PurpleImage *image, gconstpointer data,
gsize length);
/**
diff --git a/pidgin/plugins/screencap.c b/pidgin/plugins/screencap.c
--- a/pidgin/plugins/screencap.c
+++ b/pidgin/plugins/screencap.c
@@ -113,6 +113,53 @@ scrncap_pixbuf_darken(GdkPixbuf *pixbuf)
}
}
+static gboolean
+scrncap_pixbuf_to_image_cb(const gchar *buf, gsize count, GError **error,
+ gpointer _image)
+{
+ PurpleImage *image = PURPLE_IMAGE(_image);
+
+ purple_image_transfer_write(image, buf, count);
+
+ return TRUE;
+}
+
+static PurpleImage *
+scrncap_pixbuf_to_image(GdkPixbuf *pixbuf)
+{
+ PurpleImage *image;
+ GError *error = NULL;
+
+ image = purple_image_transfer_new();
+
+ gdk_pixbuf_save_to_callback(pixbuf, scrncap_pixbuf_to_image_cb, image,
+ "png", &error, NULL);
+
+ purple_image_transfer_close(image);
+
+ if (error != NULL) {
+ purple_debug_error("screencap", "Failed saving an image: %s",
+ error->message);
+ g_error_free(error);
+ g_object_unref(image);
+ return NULL;
+ }
+
+ if (purple_image_is_ready(image)) {
+ if (purple_image_get_extension(image) == NULL) {
+ purple_debug_error("screencap", "Invalid image format");
+ g_object_unref(image);
+ return NULL;
+ }
+ } else {
+ purple_debug_error("screencap", "Image is not ready");
+ g_object_unref(image);
+ return NULL;
+ }
+
+ return image;
+}
+
/******************************************************************************
* Draw window
******************************************************************************/
@@ -121,7 +168,8 @@ static gboolean
scrncap_drawing_area_btnpress(GtkWidget *draw_area, GdkEventButton *event,
gpointer _unused)
{
- g_return_val_if_fail(!draw_active, TRUE);
+ if (draw_active)
+ return TRUE;
draw_origin_x = event->x;
draw_origin_y = event->y;
@@ -134,7 +182,8 @@ static gboolean
scrncap_drawing_area_btnrelease(GtkWidget *draw_area, GdkEvent *event,
gpointer _unused)
{
- g_return_val_if_fail(draw_active, TRUE);
+ if (!draw_active)
+ return TRUE;
draw_active = FALSE;
@@ -149,11 +198,16 @@ scrncap_drawing_area_motion(GtkWidget *d
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;
+ if (!draw_active) {
+ draw_origin_x = x;
+ draw_origin_y = y;
+ draw_active = TRUE;
+ return FALSE;
+ }
+
cairo_move_to(cr, draw_origin_x, draw_origin_y);
cairo_line_to(cr, x, y);
cairo_set_line_width(cr, line_width);
@@ -210,9 +264,35 @@ scrncap_draw_window_expose(GtkWidget *wi
#endif
static void
-scrncap_draw_window(GdkPixbuf *screen)
+scrncap_draw_window_response(GtkDialog *draw_window, gint response_id,
+ gpointer _webview)
{
- GtkWidget *draw_window;
+ PidginWebView *webview = PIDGIN_WEBVIEW(_webview);
+ GdkPixbuf *result = NULL;
+ PurpleImage *image;
+
+ if (response_id == GTK_RESPONSE_OK) {
+ cairo_surface_t *surface = g_object_get_data(
+ G_OBJECT(draw_window), "surface");
+ result = gdk_pixbuf_get_from_surface(surface, 0, 0,
+ cairo_image_surface_get_width(surface),
+ cairo_image_surface_get_height(surface));
+ }
+
+ gtk_widget_destroy(GTK_WIDGET(draw_window));
+
+ if (result == NULL)
+ return;
+
+ image = scrncap_pixbuf_to_image(result);
+ pidgin_webview_insert_image(webview, image);
+ g_object_unref(image);
+}
+
+static void
+scrncap_draw_window(PidginWebView *webview, GdkPixbuf *screen)
+{
+ GtkDialog *draw_window;
GtkWidget *drawing_area, *box;
GtkWidget *scroll_area;
int width, height;
@@ -221,9 +301,10 @@ scrncap_draw_window(GdkPixbuf *screen)
is_shooting = TRUE;
- current_window = draw_window = pidgin_create_window(
+ current_window = pidgin_create_dialog(
_("Insert screenshot"), 0, "insert-screenshot", TRUE);
- gtk_widget_set_size_request(draw_window, 400, 300);
+ draw_window = GTK_DIALOG(current_window);
+ gtk_widget_set_size_request(GTK_WIDGET(draw_window), 400, 300);
gtk_window_set_position(GTK_WINDOW(draw_window), GTK_WIN_POS_CENTER);
g_signal_connect(G_OBJECT(draw_window), "destroy",
G_CALLBACK(scrncap_draw_window_close), NULL);
@@ -233,6 +314,10 @@ scrncap_draw_window(GdkPixbuf *screen)
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
cr = cairo_create(surface);
+ g_signal_connect_swapped(G_OBJECT(draw_window), "destroy",
+ G_CALLBACK(cairo_destroy), cr);
+ g_object_set_data_full(G_OBJECT(draw_window), "surface",
+ surface, (GDestroyNotify)cairo_surface_destroy);
gdk_cairo_set_source_pixbuf(cr, screen, 0, 0);
cairo_rectangle(cr, 0, 0, width, height);
@@ -264,7 +349,15 @@ scrncap_draw_window(GdkPixbuf *screen)
scroll_area = pidgin_make_scrollable(box,
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_SHADOW_IN, -1, -1);
- gtk_container_add(GTK_CONTAINER(draw_window), scroll_area);
+ gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(
+ GTK_DIALOG(draw_window))), scroll_area);
+
+ gtk_dialog_add_button(draw_window, GTK_STOCK_ADD, GTK_RESPONSE_OK);
+ gtk_dialog_add_button(draw_window, GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+ gtk_dialog_set_default_response(draw_window, GTK_RESPONSE_OK);
+ g_signal_connect(G_OBJECT(draw_window), "response",
+ G_CALLBACK(scrncap_draw_window_response), webview);
gtk_widget_show_all(GTK_WIDGET(draw_window));
}
@@ -285,8 +378,9 @@ scrncap_crop_window_close(GtkWidget *win
static gboolean
scrncap_crop_window_keypress(GtkWidget *crop_window, GdkEventKey *event,
- gpointer _unused)
+ gpointer _webview)
{
+ PidginWebView *webview = PIDGIN_WEBVIEW(_webview);
guint key = event->keyval;
if (key == GDK_Escape) {
@@ -305,7 +399,7 @@ scrncap_crop_window_keypress(GtkWidget *
gtk_widget_destroy(crop_window);
- scrncap_draw_window(result);
+ scrncap_draw_window(webview, result);
return TRUE;
}
@@ -463,7 +557,7 @@ scrncap_do_screenshot_cb(gpointer _webvi
g_signal_connect(G_OBJECT(crop_window), "destroy",
G_CALLBACK(scrncap_crop_window_close), NULL);
g_signal_connect(G_OBJECT(crop_window), "key-press-event",
- G_CALLBACK(scrncap_crop_window_keypress), NULL);
+ G_CALLBACK(scrncap_crop_window_keypress), webview);
g_signal_connect(G_OBJECT(crop_window), "focus-out-event",
G_CALLBACK(scrncap_crop_window_focusout), NULL);
g_signal_connect(G_OBJECT(crop_window), "button-press-event",
More information about the Commits
mailing list