Re: Flickering with Socket and Plug




Hi Rene,

I looked at this a little more and can get the flicker. Testing on Ubuntu16.04 with GTK3.18 it works without flicker and on Ubuntu16.04 with a jhbuild of GTK3.22 it does flicker. I tweaked your code a little so that I could test it a little easier.

Eric


/*
    gcc -Wall socket_plug1.c -o socket_plug1 `pkg-config --cflags --libs gtk+-3.0`
    Tested on Ubuntu16.04 and GTK3.18 and GTK3.22
    Flickers with 3.22
*/
 
#include <cairo.h>
#include <gtk/gtkx.h>

//cairo_surface_t * image = NULL;
GdkPixbuf *image=NULL;
static GTimer *timer=NULL;
static guint timer_id=0;

gboolean timeout(gpointer data)
{
  gtk_widget_queue_draw(GTK_WIDGET(data));
  return TRUE;
}

gboolean draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data)
{
  g_timer_start(timer);
  gint width=gtk_widget_get_allocated_width(widget);
  gint height=gtk_widget_get_allocated_height(widget);
  gint rect_x=width/10;
  gint rect_y=height/10;
  gint i=0;
  gint j=0;
  gint move_x=0;
  gint move_y=0;
  static gint overlap=0;

  //Set some limits to draw with.
  if(rect_x>20&&rect_y>20)
    {
      GdkPixbuf *pixbuf=gdk_pixbuf_scale_simple(image, rect_x, rect_y, GDK_INTERP_BILINEAR);
      for(i=0;i<10;i++)
        {
          for(j=0;j<10;j++)
            {
              gdk_cairo_set_source_pixbuf(cr, pixbuf, move_x, move_y);
              cairo_paint(cr);
              move_x+=rect_x-overlap;
            }
          move_x=0;
          move_y+=rect_y;
        }
      g_object_unref(pixbuf);

      if(overlap==20) overlap=0;
      else overlap++;
    }
  else
    {
      //Just draw white if below the limit.
      cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
      cairo_paint(cr);
    }
    
  g_print("Timer %f\n", g_timer_elapsed(timer, NULL));  
  return FALSE;
}
static void quit_program(GtkWidget *widget, gpointer data)
  {
    g_source_remove(timer_id);
    gtk_main_quit();
  }
//-------------------------------------------------------------------------
int main(int argc, char** argv)
{
  gtk_init (&argc, &argv);

  //image = cairo_image_surface_create_from_png("1200px-GTK+_logo.svg.png");
  GError *error=NULL;
  image = gdk_pixbuf_new_from_file("1200px-GTK+_logo.svg.png", &error);
  if(error!=NULL) g_print("%s\n", error->message);

  GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
  g_signal_connect(window, "destroy", G_CALLBACK(quit_program), NULL);

  timer=g_timer_new();

  GtkWidget* socket = gtk_socket_new();
  gtk_widget_set_hexpand(socket, TRUE);
  gtk_widget_set_vexpand(socket, TRUE);
  gtk_container_add(GTK_CONTAINER(window), socket);

  Window socket_id = gtk_socket_get_id(GTK_SOCKET(socket));
  GtkWidget* plug = gtk_plug_new(socket_id);
  gtk_widget_set_hexpand(plug, TRUE);
  gtk_widget_set_vexpand(plug, TRUE);

  GtkWidget* drawing_area = gtk_drawing_area_new ();
  gtk_widget_set_hexpand(drawing_area, TRUE);
  gtk_widget_set_vexpand(drawing_area, TRUE);
  gtk_container_add(GTK_CONTAINER(plug), drawing_area);
  g_signal_connect (G_OBJECT (drawing_area), "draw", G_CALLBACK (draw_callback), NULL);

  timer_id=g_timeout_add(16, timeout, drawing_area);
  gtk_widget_show_all(plug);
  gtk_widget_show_all (window);
 
  gtk_main ();
  return 0;
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]