Wednesday, February 28, 2007

A detailed exploration of gears.c

As soon as I saw gears.c, I decided to make it my first experiment of the library. Here is a snapshot of the program.

So, let's focus on its source.
int
main (int argc, char *argv[])
{
GdkGLConfig *glconfig;
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *drawing_area;
GtkWidget *button;

gtk_init (&argc, &argv);
gtk_gl_init (&argc, &argv);
glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB    |
                                      GDK_GL_MODE_DEPTH  |
                                      GDK_GL_MODE_DOUBLE);
if (glconfig == NULL) {
  g_print ("*** Cannot find the double-buffered visual.\n");
  g_print ("*** Trying single-buffered visual.\n");

  glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB   |
                                        GDK_GL_MODE_DEPTH);
  if (glconfig == NULL) {
    g_print ("*** No appropriate OpenGL-capable visual found.\n");
    exit (1);
  }
}

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "gears");
gtk_container_set_reallocate_redraws (GTK_CONTAINER (window), TRUE);

g_signal_connect (G_OBJECT (window), "delete_event",
                  G_CALLBACK (gtk_main_quit), NULL);

vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);

drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request (drawing_area, 300, 300);

gtk_widget_set_gl_capability (drawing_area,
                              glconfig,
                              NULL,
                              TRUE,
                              GDK_GL_RGBA_TYPE);

gtk_widget_add_events (drawing_area,
                       GDK_VISIBILITY_NOTIFY_MASK);

g_signal_connect_after (G_OBJECT (drawing_area), "realize",
                        G_CALLBACK (init), NULL);
g_signal_connect (G_OBJECT (drawing_area), "configure_event",
                  G_CALLBACK (reshape), NULL);
g_signal_connect (G_OBJECT (drawing_area), "expose_event",
                  G_CALLBACK (draw), NULL);
g_signal_connect (G_OBJECT (drawing_area), "map_event",
                  G_CALLBACK (map), NULL);
g_signal_connect (G_OBJECT (drawing_area), "unmap_event",
                  G_CALLBACK (unmap), NULL);
g_signal_connect (G_OBJECT (drawing_area), "visibility_notify_event",
                  G_CALLBACK (visible), NULL);

g_signal_connect_swapped (G_OBJECT (window), "key_press_event",
                          G_CALLBACK (key), drawing_area);

gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);

gtk_widget_show (drawing_area);
button = gtk_button_new_with_label ("Quit");

g_signal_connect (G_OBJECT (button), "clicked",
                  G_CALLBACK (gtk_main_quit), NULL);

gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
gtk_widget_show (window);

gtk_main ();
return 0;
}
Here we will explain the whole thing step by step. There are two init functions in the beginning, which extracts those options they care so that the rest are what the application really cares about.

2 comments:

Anonymous said...

I am more interested in your explorations of
gtkglextmm as that would combine with your interest in using C++.
I am interested in using it for a medical image display program
ct scans mri and plain x ray images using dicom3 format.

Araruna said...

Where is the continuation of the post???