>A displaying application

A displaying application

Once more, the code for this example can be found there.

Now that we know how to render our data in a pixel buffer, we want to display it on screen in a window. To do this, we use the gdkrgb library which transfers pixel buffers to the X server in Drawables. The code below is very similar to our previous example: we just initialize GTK+ and gdkrgb and instead of saving the pixel buffer to a file, we create a widget to display it and run the GTK+ main loop:

int main (int argc, char *argv[])
  ArtSVP *path;
  char *buffer;

  /* gtk/gdkrgb initialization */
  gtk_init (&argc, &argv);
  gdk_rgb_init ();

  path = make_path ();

  buffer = render_path (path);

  build_widget (buffer);

  /* gtk main loop */
  gtk_main ();

  return 0;

The only new function is build_widget which is shown below. This function just creates a drawing area and connects a drawing callback to the expose signal.

static void 
build_widget (unsigned char *buffer)
  GtkWidget *window = NULL, *drawing_area = NULL;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size (GTK_WINDOW(window), WIDTH, HEIGHT);
  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
		      GTK_SIGNAL_FUNC (destroy_cb), NULL);
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
		      GTK_SIGNAL_FUNC (destroy_cb), NULL);
  drawing_area = gtk_drawing_area_new ();
  gtk_container_add (GTK_CONTAINER (window),
		     GTK_WIDGET (drawing_area));

  gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
		      GTK_SIGNAL_FUNC (expose_cb), buffer);
  gtk_signal_connect (GTK_OBJECT (drawing_area), "configure_event",
		      GTK_SIGNAL_FUNC (expose_cb), buffer);

  gtk_widget_show_all (window);

The expose callback is very simple: it just calls gdkrgb's entry point to render the pixel buffer onto the drawing area we instantiated a little before.

static int 
expose_cb (GtkWidget *widget, GdkEventExpose *evt, gpointer data)
  art_u8 *buf = (art_u8 *)data;

  gdk_draw_rgb_image (widget->window, widget->style->black_gc, 
		      0, 0, WIDTH, HEIGHT, 
  return FALSE;