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