Gabriele Greco wrote:

The source file as attach was cutted,  I'm pasting it inline, it's short :)
> I've wrote this example code and it seems to work properly both on 
> Linux and Win32, I'm wandering if some GTK guru has some suggestions 
> to improve it, obviously it's only an example, but this will be the 
> structure that will be included in the application, the thread that 
> build the image will be an h263 decoder that get the video through the 
> net, this is why the simple image creation of the demo is made in a 
> separate thread. It works without changes both in win32/linux and uses 
> 5/10% of CPU of pretty old machines.
>
> I'm wandering what happens if I set an idle_function with g_idle_add() 
> while the previous idle cbk has not yet completed (the coherence of 
> the image is not a problem because I already plan to use a SpinBuffer 
> for it in the real app).
>
> I'm wandering also if it's better to use gdk_flush() when I draw a 
> frame or it's also safe/fast to do gtk_widget_queue_redraw() for the 
> drawing
> area widget...
>
> Compile with:
>
> gcc -o test gtkview.c `pkg-config gtk+-2.0 --cflags --libs` 
> `pkg-config gthread-2.0 --cflags --libs`
#include <gtk/gtk.h>
#include <stdlib.h>

GtkWidget *label;
GdkGC *mygc;
GdkDrawable *mydest;

gboolean blit_fast(GdkImage *img)
{
    static int frames = 0;
    static time_t timer = 0;

    gdk_draw_image(mydest, mygc, img, 0, 0, 0, 0, img->width, img->height);
    gdk_flush();

    if ((frames % 100) == 0) {
        time_t newtime = time(NULL);

        if (timer != 0) {
            char buffer[80];
            newtime -= timer;

            if (newtime != 0) {
                sprintf(buffer, "Frames: %d time: %d, %d fps", frames, 
newtime, frames / newtime);
                gtk_label_set(GTK_LABEL(label), buffer);
            }
        }
        else
            timer = newtime;
    }

    frames++;

    return FALSE;
}

void *myloop(GdkImage *img)
{
    static int pos = 0;
    int i, j;
    GTimer *t = g_timer_new();
    gdouble needed = 0.0f;
    g_timer_start(t);

    for(;;) {
        unsigned long *ptr = img->mem;

        for (j = 0; j < img->height; ++j) {
            for (i = 0; i < img->width; ++i) {
                if (i < pos || i > (pos + 100))
                    *ptr = 0;
                else {
                    *ptr = 0xff0000;
                }
                ptr++;
            }
        }
        pos ++;
        if (pos == 640)
            pos = -99;

        while (g_timer_elapsed(t, NULL) < needed)
            g_usleep(10000);

        g_idle_add(blit_fast, img);
        needed += 0.040;
    }
}


int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    g_thread_init(NULL);

    GdkVisual *vis = gdk_visual_get_system ();

    GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget *box = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(win), box);
    GtkWidget *area = gtk_drawing_area_new();
    gtk_widget_set_usize(area, 640, 480);
    gtk_box_pack_start_defaults(GTK_BOX(box), area);
    label = gtk_label_new("--- fps");
    gtk_box_pack_end_defaults(GTK_BOX(box), label);

    gtk_widget_set_app_paintable(area, TRUE);
//    gtk_widget_set_double_buffered(win, FALSE);
    gtk_widget_set_double_buffered(area, FALSE);

    gtk_signal_connect(GTK_OBJECT(win), "destroy",
            GTK_SIGNAL_FUNC(exit), (void *)0);

    GdkImage *img = gdk_image_new(GDK_IMAGE_FASTEST, vis, 640, 480);

    printf("Img-> %dx%d depth:%d bpp:%d bpl:%d\n", img->width, img->height,
            img->depth, img->bpp, img->bpl);

    if (img->bpp != 4) // actually only 32bit support since it's a test
        return -1;

    gtk_widget_show_all(win);

    mygc = gdk_gc_new(area->window);
    mydest = area->window;

    g_thread_create(myloop, img, FALSE, NULL);

    gtk_main();
}

_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to