<commit_before>#include <gtk/gtk.h>
#include <gdk/gdkscreen.h>
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>

#include <unistd.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 void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer user_data);
static gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
static void clicked(GtkWindow *win, GdkEventButton *event, gpointer user_data);

int main(int argc, char **argv)
{
    /* boilerplate initialization code */
    gtk_init(&argc, &argv);

    GtkWidget *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);
    g_signal_connect(G_OBJECT(window), "screen-changed", G_CALLBACK(screen_changed), NULL);

    /* toggle title bar on click - we add the mask to tell X we are interested in this event */
    gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
    gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
    g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(clicked), NULL);

    /* initialize for the current display */
    screen_changed(window, NULL, NULL);

    /* Run the program */
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}


/* Only some X servers support alpha channels. Always have a fallback */
gboolean supports_alpha = FALSE;

static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer userdata)
{
    /* To check if the display supports alpha channels, get the colormap */
    GdkScreen *screen = gtk_widget_get_screen(widget);
    GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);

    if (!colormap)
    {
        printf("Your screen does not support alpha channels!\n");
        colormap = gdk_screen_get_rgb_colormap(screen);
        supports_alpha = FALSE;
    }
    else
    {
        printf("Your screen supports alpha channels!\n");
        supports_alpha = TRUE;
    }

    /* Now we have a colormap appropriate for the screen, use it */
    gtk_widget_set_colormap(widget, colormap);
}

/* 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);

    //if (supports_alpha)
    //    cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
    //else
    //    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */

    /* 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);

    cairo_surface_t *img;
    int imgw, imgh;
    char *imgpath;

    imgpath = "/home/mertyildiran/Downloads/pony.gif";
    if (imgpath == NULL) {
        fprintf(stderr, "usage: see image.png\n");
        exit(1);
    }

    GdkPixbuf *pixbuf;
    GdkPixbufAnimation *pixbuf_animation;
    cairo_format_t format;
    /* load image and get dimantions */
    pixbuf_animation = gdk_pixbuf_animation_new_from_file (imgpath, NULL);
    //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);



    // Mostly taken from -> https://github.com/acg/w3m/blob/553eff53243049c1da5918adb1b25297d19f619a/w3mimg/fb/fb_gdkpixbuf.c
    GdkPixbufAnimationIter *iter;
    GTimeVal time;
    g_get_current_time(&time);

    iter = gdk_pixbuf_animation_get_iter (pixbuf_animation, &time);

    int n, i, d = -1;
    for (i = 1; gdk_pixbuf_animation_iter_on_currently_loading_frame(iter) != TRUE; i++) {
        int tmp;
        tmp = gdk_pixbuf_animation_iter_get_delay_time(iter);
        g_time_val_add(&time, tmp * 1000);
        if (tmp > d) {
            d = tmp;
            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_pixbuf_animation_iter_advance(iter, &time);
    }


<commit_msg>Fix the animated GIF support<commit_after>#include <gtk/gtk.h>
#include <gdk/gdkscreen.h>
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.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 void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer user_data);
static gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
static void clicked(GtkWindow *win, GdkEventButton *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 = "/home/mertyildiran/Downloads/pony.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);
    g_signal_connect(G_OBJECT(window), "screen-changed", G_CALLBACK(screen_changed), NULL);

    /* toggle title bar on click - we add the mask to tell X we are interested in this event */
    gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
    gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
    g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(clicked), NULL);

    /* initialize for the current display */
    screen_changed(window, NULL, NULL);

    /* Run the program */
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}


/* Only some X servers support alpha channels. Always have a fallback */
gboolean supports_alpha = FALSE;

static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer userdata)
{
    /* To check if the display supports alpha channels, get the colormap */
    GdkScreen *screen = gtk_widget_get_screen(widget);
    GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);

    if (!colormap)
    {
        printf("Your screen does not support alpha channels!\n");
        colormap = gdk_screen_get_rgb_colormap(screen);
        supports_alpha = FALSE;
    }
    else
    {
        printf("Your screen supports alpha channels!\n");
        supports_alpha = TRUE;
    }

    /* Now we have a colormap appropriate for the screen, use it */
    gtk_widget_set_colormap(widget, colormap);
}

/* 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);

    //if (supports_alpha)
    //    cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
    //else
    //    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */

    /* 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;

    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);



{'fraction_non_alphanumeric': 0.10057163272597357, 'fraction_numerical': 0.010628795998570919, 'mean_word_length': 3.5350344268934792, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2461126', 'n_tokens_mistral': 3856, 'n_tokens_neox': 3679, 'n_words': 1029}