diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gtkutil.c | 69 |
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 | ||
| 283 | static GdkPixbuf * | ||
| 284 | xg_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 | |||
| 282 | static Lisp_Object | 327 | static Lisp_Object |
| 283 | file_for_image (Lisp_Object image) | 328 | file_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 |