aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gtkutil.c69
1 files changed, 64 insertions, 5 deletions
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 43918dd3da5..c6534585f8d 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -279,6 +279,51 @@ xg_get_pixbuf_from_pix_and_mask (struct frame *f,
279 return icon_buf; 279 return icon_buf;
280} 280}
281 281
282#if defined USE_CAIRO && !defined HAVE_GTK3
283static GdkPixbuf *
284xg_get_pixbuf_from_surface (struct frame *f, cairo_surface_t *surface)
285{
286 int width = cairo_image_surface_get_width (surface);
287 int height = cairo_image_surface_get_height (surface);
288 GdkPixbuf *icon_buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
289 width, height);
290 if (icon_buf)
291 {
292 guchar *pixels = gdk_pixbuf_get_pixels (icon_buf);
293 int rowstride = gdk_pixbuf_get_rowstride (icon_buf);
294 cairo_surface_t *icon_surface
295 = cairo_image_surface_create_for_data (pixels, CAIRO_FORMAT_ARGB32,
296 width, height, rowstride);
297 cairo_t *cr = cairo_create (icon_surface);
298 cairo_surface_destroy (icon_surface);
299 cairo_set_source_surface (cr, surface, 0, 0);
300 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
301 cairo_paint (cr);
302 cairo_destroy (cr);
303
304 for (int y = 0; y < height; y++)
305 {
306 for (int x = 0; x < width; x++)
307 {
308 guint32 argb = ((guint32 *) pixels)[x];
309#ifdef WORDS_BIGENDIAN
310 /* ARGB -> RGBA (gdk_pixbuf, big endian) */
311 ((guint32 *) pixels)[x] = (argb << 8) | (argb >> 24);
312#else /* !WORDS_BIGENDIAN */
313 /* ARGB -> ABGR (gdk_pixbuf, little endian) */
314 ((guint32 *) pixels)[x] = (( argb & 0xff00ff00)
315 | ((argb << 16) & 0x00ff0000)
316 | ((argb >> 16) & 0x000000ff));
317#endif /* !WORDS_BIGENDIAN */
318 }
319 pixels += rowstride;
320 }
321 }
322
323 return icon_buf;
324}
325#endif /* USE_CAIRO && !HAVE_GTK3 */
326
282static Lisp_Object 327static Lisp_Object
283file_for_image (Lisp_Object image) 328file_for_image (Lisp_Object image)
284{ 329{
@@ -311,7 +356,7 @@ xg_get_image_for_pixmap (struct frame *f,
311 GtkWidget *widget, 356 GtkWidget *widget,
312 GtkImage *old_widget) 357 GtkImage *old_widget)
313{ 358{
314#if defined USE_CAIRO && defined HAVE_GTK3 359#ifdef USE_CAIRO
315 cairo_surface_t *surface; 360 cairo_surface_t *surface;
316#else 361#else
317 GdkPixbuf *icon_buf; 362 GdkPixbuf *icon_buf;
@@ -343,15 +388,29 @@ xg_get_image_for_pixmap (struct frame *f,
343 on a monochrome display, and sometimes bad on all displays with 388 on a monochrome display, and sometimes bad on all displays with
344 certain themes. */ 389 certain themes. */
345 390
346#if defined USE_CAIRO && defined HAVE_GTK3 391#ifdef USE_CAIRO
347 surface = img->cr_data; 392 surface = img->cr_data;
348 393
349 if (surface) 394 if (surface)
350 { 395 {
396#ifdef HAVE_GTK3
351 if (! old_widget) 397 if (! old_widget)
352 old_widget = GTK_IMAGE (gtk_image_new_from_surface (surface)); 398 old_widget = GTK_IMAGE (gtk_image_new_from_surface (surface));
353 else 399 else
354 gtk_image_set_from_surface (old_widget, surface); 400 gtk_image_set_from_surface (old_widget, surface);
401#else /* !HAVE_GTK3 */
402 GdkPixbuf *icon_buf = xg_get_pixbuf_from_surface (f, surface);
403
404 if (icon_buf)
405 {
406 if (! old_widget)
407 old_widget = GTK_IMAGE (gtk_image_new_from_pixbuf (icon_buf));
408 else
409 gtk_image_set_from_pixbuf (old_widget, icon_buf);
410
411 g_object_unref (G_OBJECT (icon_buf));
412 }
413#endif /* !HAVE_GTK3 */
355 } 414 }
356#else 415#else
357 /* This is a workaround to make icons look good on pseudo color 416 /* This is a workaround to make icons look good on pseudo color
@@ -4689,7 +4748,7 @@ xg_tool_item_stale_p (GtkWidget *wbutton, const char *stock_name,
4689 { 4748 {
4690 gpointer gold_img = g_object_get_data (G_OBJECT (wimage), 4749 gpointer gold_img = g_object_get_data (G_OBJECT (wimage),
4691 XG_TOOL_BAR_IMAGE_DATA); 4750 XG_TOOL_BAR_IMAGE_DATA);
4692#if defined USE_CAIRO && defined HAVE_GTK3 4751#ifdef USE_CAIRO
4693 void *old_img = (void *) gold_img; 4752 void *old_img = (void *) gold_img;
4694 if (old_img != img->cr_data) 4753 if (old_img != img->cr_data)
4695 return 1; 4754 return 1;
@@ -4990,7 +5049,7 @@ update_frame_tool_bar (struct frame *f)
4990 prepare_image_for_display (f, img); 5049 prepare_image_for_display (f, img);
4991 5050
4992 if (img->load_failed_p 5051 if (img->load_failed_p
4993#if defined USE_CAIRO && defined HAVE_GTK3 5052#ifdef USE_CAIRO
4994 || img->cr_data == NULL 5053 || img->cr_data == NULL
4995#else 5054#else
4996 || img->pixmap == None 5055 || img->pixmap == None
@@ -5045,7 +5104,7 @@ update_frame_tool_bar (struct frame *f)
5045 { 5104 {
5046 w = xg_get_image_for_pixmap (f, img, x->widget, NULL); 5105 w = xg_get_image_for_pixmap (f, img, x->widget, NULL);
5047 g_object_set_data (G_OBJECT (w), XG_TOOL_BAR_IMAGE_DATA, 5106 g_object_set_data (G_OBJECT (w), XG_TOOL_BAR_IMAGE_DATA,
5048#if defined USE_CAIRO && defined HAVE_GTK3 5107#ifdef USE_CAIRO
5049 (gpointer)img->cr_data 5108 (gpointer)img->cr_data
5050#else 5109#else
5051 (gpointer)img->pixmap 5110 (gpointer)img->pixmap