pidgin/plugins/screencap.c

changeset 35946
44e9ed3cc8fe
parent 35945
8d17d321e66c
child 35947
0c93751c7c96
equal deleted inserted replaced
35945:8d17d321e66c 35946:44e9ed3cc8fe
111 *pixels /= 2; 111 *pixels /= 2;
112 pixels += pad; 112 pixels += pad;
113 } 113 }
114 } 114 }
115 115
116 static gboolean
117 scrncap_pixbuf_to_image_cb(const gchar *buf, gsize count, GError **error,
118 gpointer _image)
119 {
120 PurpleImage *image = PURPLE_IMAGE(_image);
121
122 purple_image_transfer_write(image, buf, count);
123
124 return TRUE;
125 }
126
127 static PurpleImage *
128 scrncap_pixbuf_to_image(GdkPixbuf *pixbuf)
129 {
130 PurpleImage *image;
131 GError *error = NULL;
132
133 image = purple_image_transfer_new();
134
135 gdk_pixbuf_save_to_callback(pixbuf, scrncap_pixbuf_to_image_cb, image,
136 "png", &error, NULL);
137
138 purple_image_transfer_close(image);
139
140 if (error != NULL) {
141 purple_debug_error("screencap", "Failed saving an image: %s",
142 error->message);
143 g_error_free(error);
144 g_object_unref(image);
145 return NULL;
146 }
147
148 if (purple_image_is_ready(image)) {
149 if (purple_image_get_extension(image) == NULL) {
150 purple_debug_error("screencap", "Invalid image format");
151 g_object_unref(image);
152 return NULL;
153 }
154 } else {
155 purple_debug_error("screencap", "Image is not ready");
156 g_object_unref(image);
157 return NULL;
158 }
159
160 return image;
161 }
162
116 /****************************************************************************** 163 /******************************************************************************
117 * Draw window 164 * Draw window
118 ******************************************************************************/ 165 ******************************************************************************/
119 166
120 static gboolean 167 static gboolean
121 scrncap_drawing_area_btnpress(GtkWidget *draw_area, GdkEventButton *event, 168 scrncap_drawing_area_btnpress(GtkWidget *draw_area, GdkEventButton *event,
122 gpointer _unused) 169 gpointer _unused)
123 { 170 {
124 g_return_val_if_fail(!draw_active, TRUE); 171 if (draw_active)
172 return TRUE;
125 173
126 draw_origin_x = event->x; 174 draw_origin_x = event->x;
127 draw_origin_y = event->y; 175 draw_origin_y = event->y;
128 draw_active = TRUE; 176 draw_active = TRUE;
129 177
132 180
133 static gboolean 181 static gboolean
134 scrncap_drawing_area_btnrelease(GtkWidget *draw_area, GdkEvent *event, 182 scrncap_drawing_area_btnrelease(GtkWidget *draw_area, GdkEvent *event,
135 gpointer _unused) 183 gpointer _unused)
136 { 184 {
137 g_return_val_if_fail(draw_active, TRUE); 185 if (!draw_active)
186 return TRUE;
138 187
139 draw_active = FALSE; 188 draw_active = FALSE;
140 189
141 return TRUE; 190 return TRUE;
142 } 191 }
147 { 196 {
148 cairo_t *cr = _cr; 197 cairo_t *cr = _cr;
149 int x, y; 198 int x, y;
150 int redraw_x, redraw_y, redraw_w, redraw_h; 199 int redraw_x, redraw_y, redraw_w, redraw_h;
151 200
152 g_return_val_if_fail(draw_active, FALSE);
153
154 x = event->x; 201 x = event->x;
155 y = event->y; 202 y = event->y;
203
204 if (!draw_active) {
205 draw_origin_x = x;
206 draw_origin_y = y;
207 draw_active = TRUE;
208 return FALSE;
209 }
156 210
157 cairo_move_to(cr, draw_origin_x, draw_origin_y); 211 cairo_move_to(cr, draw_origin_x, draw_origin_y);
158 cairo_line_to(cr, x, y); 212 cairo_line_to(cr, x, y);
159 cairo_set_line_width(cr, line_width); 213 cairo_set_line_width(cr, line_width);
160 cairo_stroke(cr); 214 cairo_stroke(cr);
208 return FALSE; 262 return FALSE;
209 } 263 }
210 #endif 264 #endif
211 265
212 static void 266 static void
213 scrncap_draw_window(GdkPixbuf *screen) 267 scrncap_draw_window_response(GtkDialog *draw_window, gint response_id,
214 { 268 gpointer _webview)
215 GtkWidget *draw_window; 269 {
270 PidginWebView *webview = PIDGIN_WEBVIEW(_webview);
271 GdkPixbuf *result = NULL;
272 PurpleImage *image;
273
274 if (response_id == GTK_RESPONSE_OK) {
275 cairo_surface_t *surface = g_object_get_data(
276 G_OBJECT(draw_window), "surface");
277 result = gdk_pixbuf_get_from_surface(surface, 0, 0,
278 cairo_image_surface_get_width(surface),
279 cairo_image_surface_get_height(surface));
280 }
281
282 gtk_widget_destroy(GTK_WIDGET(draw_window));
283
284 if (result == NULL)
285 return;
286
287 image = scrncap_pixbuf_to_image(result);
288 pidgin_webview_insert_image(webview, image);
289 g_object_unref(image);
290 }
291
292 static void
293 scrncap_draw_window(PidginWebView *webview, GdkPixbuf *screen)
294 {
295 GtkDialog *draw_window;
216 GtkWidget *drawing_area, *box; 296 GtkWidget *drawing_area, *box;
217 GtkWidget *scroll_area; 297 GtkWidget *scroll_area;
218 int width, height; 298 int width, height;
219 cairo_t *cr; 299 cairo_t *cr;
220 cairo_surface_t *surface; 300 cairo_surface_t *surface;
221 301
222 is_shooting = TRUE; 302 is_shooting = TRUE;
223 303
224 current_window = draw_window = pidgin_create_window( 304 current_window = pidgin_create_dialog(
225 _("Insert screenshot"), 0, "insert-screenshot", TRUE); 305 _("Insert screenshot"), 0, "insert-screenshot", TRUE);
226 gtk_widget_set_size_request(draw_window, 400, 300); 306 draw_window = GTK_DIALOG(current_window);
307 gtk_widget_set_size_request(GTK_WIDGET(draw_window), 400, 300);
227 gtk_window_set_position(GTK_WINDOW(draw_window), GTK_WIN_POS_CENTER); 308 gtk_window_set_position(GTK_WINDOW(draw_window), GTK_WIN_POS_CENTER);
228 g_signal_connect(G_OBJECT(draw_window), "destroy", 309 g_signal_connect(G_OBJECT(draw_window), "destroy",
229 G_CALLBACK(scrncap_draw_window_close), NULL); 310 G_CALLBACK(scrncap_draw_window_close), NULL);
230 311
231 width = gdk_pixbuf_get_width(screen); 312 width = gdk_pixbuf_get_width(screen);
232 height = gdk_pixbuf_get_height(screen); 313 height = gdk_pixbuf_get_height(screen);
233 314
234 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height); 315 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
235 cr = cairo_create(surface); 316 cr = cairo_create(surface);
317 g_signal_connect_swapped(G_OBJECT(draw_window), "destroy",
318 G_CALLBACK(cairo_destroy), cr);
319 g_object_set_data_full(G_OBJECT(draw_window), "surface",
320 surface, (GDestroyNotify)cairo_surface_destroy);
236 321
237 gdk_cairo_set_source_pixbuf(cr, screen, 0, 0); 322 gdk_cairo_set_source_pixbuf(cr, screen, 0, 0);
238 cairo_rectangle(cr, 0, 0, width, height); 323 cairo_rectangle(cr, 0, 0, width, height);
239 cairo_fill(cr); 324 cairo_fill(cr);
240 g_object_unref(screen); 325 g_object_unref(screen);
262 box = gtk_alignment_new(0.5, 0.5, 0, 0); 347 box = gtk_alignment_new(0.5, 0.5, 0, 0);
263 gtk_container_add(GTK_CONTAINER(box), drawing_area); 348 gtk_container_add(GTK_CONTAINER(box), drawing_area);
264 scroll_area = pidgin_make_scrollable(box, 349 scroll_area = pidgin_make_scrollable(box,
265 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, 350 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
266 GTK_SHADOW_IN, -1, -1); 351 GTK_SHADOW_IN, -1, -1);
267 gtk_container_add(GTK_CONTAINER(draw_window), scroll_area); 352 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(
353 GTK_DIALOG(draw_window))), scroll_area);
354
355 gtk_dialog_add_button(draw_window, GTK_STOCK_ADD, GTK_RESPONSE_OK);
356 gtk_dialog_add_button(draw_window, GTK_STOCK_CANCEL,
357 GTK_RESPONSE_CANCEL);
358 gtk_dialog_set_default_response(draw_window, GTK_RESPONSE_OK);
359 g_signal_connect(G_OBJECT(draw_window), "response",
360 G_CALLBACK(scrncap_draw_window_response), webview);
268 361
269 gtk_widget_show_all(GTK_WIDGET(draw_window)); 362 gtk_widget_show_all(GTK_WIDGET(draw_window));
270 } 363 }
271 364
272 /****************************************************************************** 365 /******************************************************************************
283 current_window = NULL; 376 current_window = NULL;
284 } 377 }
285 378
286 static gboolean 379 static gboolean
287 scrncap_crop_window_keypress(GtkWidget *crop_window, GdkEventKey *event, 380 scrncap_crop_window_keypress(GtkWidget *crop_window, GdkEventKey *event,
288 gpointer _unused) 381 gpointer _webview)
289 { 382 {
383 PidginWebView *webview = PIDGIN_WEBVIEW(_webview);
290 guint key = event->keyval; 384 guint key = event->keyval;
291 385
292 if (key == GDK_Escape) { 386 if (key == GDK_Escape) {
293 gtk_widget_destroy(crop_window); 387 gtk_widget_destroy(crop_window);
294 return TRUE; 388 return TRUE;
303 result = gdk_pixbuf_copy(subscreen); 397 result = gdk_pixbuf_copy(subscreen);
304 g_object_unref(subscreen); 398 g_object_unref(subscreen);
305 399
306 gtk_widget_destroy(crop_window); 400 gtk_widget_destroy(crop_window);
307 401
308 scrncap_draw_window(result); 402 scrncap_draw_window(webview, result);
309 403
310 return TRUE; 404 return TRUE;
311 } 405 }
312 406
313 return FALSE; 407 return FALSE;
461 g_signal_connect(G_OBJECT(crop_window), "realize", 555 g_signal_connect(G_OBJECT(crop_window), "realize",
462 G_CALLBACK(scrncap_crop_window_realize), NULL); 556 G_CALLBACK(scrncap_crop_window_realize), NULL);
463 g_signal_connect(G_OBJECT(crop_window), "destroy", 557 g_signal_connect(G_OBJECT(crop_window), "destroy",
464 G_CALLBACK(scrncap_crop_window_close), NULL); 558 G_CALLBACK(scrncap_crop_window_close), NULL);
465 g_signal_connect(G_OBJECT(crop_window), "key-press-event", 559 g_signal_connect(G_OBJECT(crop_window), "key-press-event",
466 G_CALLBACK(scrncap_crop_window_keypress), NULL); 560 G_CALLBACK(scrncap_crop_window_keypress), webview);
467 g_signal_connect(G_OBJECT(crop_window), "focus-out-event", 561 g_signal_connect(G_OBJECT(crop_window), "focus-out-event",
468 G_CALLBACK(scrncap_crop_window_focusout), NULL); 562 G_CALLBACK(scrncap_crop_window_focusout), NULL);
469 g_signal_connect(G_OBJECT(crop_window), "button-press-event", 563 g_signal_connect(G_OBJECT(crop_window), "button-press-event",
470 G_CALLBACK(scrncap_crop_window_btnpress), NULL); 564 G_CALLBACK(scrncap_crop_window_btnpress), NULL);
471 g_signal_connect(G_OBJECT(crop_window), "button-release-event", 565 g_signal_connect(G_OBJECT(crop_window), "button-release-event",

mercurial