Skip to content

Instantly share code, notes, and snippets.

@mertyildiran
Last active Jul 2, 2017
Embed
What would you like to do?
Run animated GIF with black background using Gtk
#include <gtk/gtk.h>
#include <gdk/gdkscreen.h>
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <unistd.h>
#include <stdlib.h>
/*
* This program shows you how to create semi-transparent windows,
* without any of the historical screenshot hacks. It requires
* a modern system, with a compositing manager. I use xcompmgr
* and the nvidia drivers with RenderAccel, and it works well.
*
* I'll take you through each step as we go. Minimal GTK+ knowledge is
* assumed.
*
* gcc alphademo.c -o alphademo $( pkg-config --cflags --libs gtk+-2.0 )
*
* https://web.archive.org/web/20121027002505/http://plan99.net/~mike/files/alphademo.c
*/
static gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
static GdkPixbufAnimation *pixbuf_animation;
static GdkPixbufAnimationIter *iter;
static GtkWidget *window;
static gboolean timer(gpointer user_data)
{
GTimeVal time;
g_get_current_time(&time);
gdk_pixbuf_animation_iter_advance(iter, &time);
g_timeout_add(gdk_pixbuf_animation_iter_get_delay_time(iter), timer, NULL);
gtk_widget_queue_draw(window);
return FALSE;
}
int main(int argc, char **argv)
{
/* boilerplate initialization code */
gtk_init(&argc, &argv);
const char *imgpath = "/tmp/giphy.gif";
if (imgpath == NULL) {
fprintf(stderr, "usage: see image.png\n");
exit(1);
}
pixbuf_animation = gdk_pixbuf_animation_new_from_file (imgpath, NULL);
GTimeVal time;
g_get_current_time(&time);
iter = gdk_pixbuf_animation_get_iter (pixbuf_animation, &time);
timer(NULL);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Alpha Demo");
g_signal_connect(G_OBJECT(window), "delete-event", gtk_main_quit, NULL);
/* Tell GTK+ that we want to draw the windows background ourself.
* If we don't do this then GTK+ will clear the window to the
* opaque theme default color, which isn't what we want.
*/
gtk_widget_set_app_paintable(window, TRUE);
/* We need to handle two events ourself: "expose-event" and "screen-changed".
*
* The X server sends us an expose event when the window becomes
* visible on screen. It means we need to draw the contents. On a
* composited desktop expose is normally only sent when the window
* is put on the screen. On a non-composited desktop it can be
* sent whenever the window is uncovered by another.
*
* The screen-changed event means the display to which we are
* drawing changed. GTK+ supports migration of running
* applications between X servers, which might not support the
* same features, so we need to check each time.
*/
g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(expose), NULL);
/* Run the program */
gtk_widget_show_all(window);
gtk_main();
return 0;
}
/* This is called when we need to draw the windows contents */
static gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer userdata)
{
cairo_t *cr = gdk_cairo_create(widget->window);
/* draw the background */
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
//cairo_paint (cr);
/* draw a circle */
int width, height;
gtk_window_get_size(GTK_WINDOW(widget), &width, &height);
int imgw, imgh;
GdkPixbuf *pixbuf;
/* load image and get dimantions */
//format = (gdk_pixbuf_get_has_alpha (pixbuf)) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
imgw = gdk_pixbuf_animation_get_width (pixbuf_animation);
imgh = gdk_pixbuf_animation_get_height (pixbuf_animation);
gtk_window_resize(GTK_WINDOW(widget), imgw, imgh);
pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(iter);
//g_timeout_add(1000, pixbuf, NULL);
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
cairo_paint (cr);
//gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
//cairo_paint (cr);
cairo_destroy(cr);
return FALSE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment