--- gtkgl/gtkglarea.h	2014-04-27 13:12:41 +0000
+++ gtkgl/gtkglarea.h	2014-04-28 05:42:31 +0000
@@ -38,6 +38,20 @@
 typedef struct _GtkGLArea       GtkGLArea;
 typedef struct _GtkGLAreaClass  GtkGLAreaClass;
 
+#if defined __GTK3__
+
+#define GTK_GL_WIDGET_CLASS GTK_WIDGET_CLASS
+#define GtkGLWidget GtkWidget
+#define GtkGLWidgetClass GtkWidgetClass
+
+#elif defined __GTK2__
+
+#define GTK_GL_WIDGET_CLASS GTK_OBJECT_CLASS
+#define GtkGLWidget GtkObject
+#define GtkGLWidgetClass GtkObjectClass
+
+#endif
+
 
 struct _GtkGLArea
 {
--- gtkgl/gtkglarea.c	2014-04-27 07:58:32 +0000
+++ gtkgl/gtkglarea.c	2014-04-28 05:26:22 +0000
@@ -23,18 +23,18 @@
 #include "gdkgl.h"
 #include "gtkglarea.h"
 
-static void gtk_gl_area_destroy       (GtkObject      *object); /* change to finalize? */
+static void gtk_gl_area_destroy       (GtkGLWidget *widget); /* change to finalize? */
 
 G_DEFINE_TYPE (GtkGLArea, gtk_gl_area, GTK_TYPE_DRAWING_AREA);
 
 static void
 gtk_gl_area_class_init (GtkGLAreaClass *klass)
 {
-  GtkObjectClass *object_class;
+  GtkGLWidgetClass *widget_class;
 
-  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkGLWidgetClass*) klass;
 
-  object_class->destroy = gtk_gl_area_destroy;
+  widget_class->destroy = gtk_gl_area_destroy;
 }
 
 
@@ -105,7 +105,7 @@
   if (glcontext == NULL)
     return NULL;
 
-#if defined GDK_WINDOWING_X11
+#if defined (GDK_WINDOWING_X11) && defined (__GTK2__)
   /* use colormap and visual suitable for OpenGL rendering */
   gtk_widget_push_colormap(gdk_colormap_new(visual,TRUE));
 #endif
@@ -113,7 +113,7 @@
   gl_area = g_object_new(GTK_TYPE_GL_AREA, NULL);
   gl_area->glcontext = glcontext;
 
-#if defined GDK_WINDOWING_X11
+#if defined (GDK_WINDOWING_X11) && defined (__GTK2__)
   /* pop back defaults */
   gtk_widget_pop_colormap();
 #endif
@@ -123,20 +123,20 @@
 
 
 static void
-gtk_gl_area_destroy(GtkObject *object)
+gtk_gl_area_destroy(GtkGLWidget *widget)
 {
   GtkGLArea *gl_area;
 
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (GTK_IS_GL_AREA(object));
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_GL_AREA(widget));
 
-  gl_area = GTK_GL_AREA(object);
+  gl_area = GTK_GL_AREA(widget);
 
   if (gl_area->glcontext)
     g_object_unref(gl_area->glcontext);
   gl_area->glcontext = NULL;
 
-  GTK_OBJECT_CLASS (gtk_gl_area_parent_class)->destroy;
+  GTK_GL_WIDGET_CLASS (gtk_gl_area_parent_class)->destroy;
 }
 
 
--- gtkgl/gdkgl.h	2014-04-27 14:24:26 +0000
+++ gtkgl/gdkgl.h	2014-04-28 07:35:00 +0000
@@ -78,6 +78,23 @@
 
 typedef struct _GdkGLContext GdkGLContext;
 
+#if defined __GTK3__
+
+#define GDK_GL_IS_DRAWABLE GDK_IS_WINDOW
+#define GDK_GL_IS_PIXMAP_SOURCE GDK_IS_PIXBUF
+#define GdkGLDrawable GdkWindow
+#define GdkGLPixmapSource GdkPixbuf
+
+#elif defined __GTK2__
+
+#define gdk_x11_window_get_xid GDK_WINDOW_XWINDOW
+#define GDK_GL_IS_DRAWABLE GDK_IS_DRAWABLE
+#define GDK_GL_IS_PIXMAP_SOURCE GDK_IS_PIXMAP
+#define GdkGLDrawable GdkDrawable
+#define GdkGLPixmapSource GdkPixmap
+
+#endif
+
 
 gint          gdk_gl_query(void);
 gchar        *gdk_gl_get_info(void);
@@ -90,8 +107,8 @@
 GdkGLContext *gdk_gl_context_share_new(GdkVisual *visual, GdkGLContext *sharelist, gint direct);
 GdkGLContext *gdk_gl_context_attrlist_share_new(int *attrlist, GdkGLContext *sharelist, gint direct);
 
-gint          gdk_gl_make_current(GdkDrawable *drawable, GdkGLContext *context);
-void          gdk_gl_swap_buffers(GdkDrawable *drawable);
+gint          gdk_gl_make_current(GdkGLDrawable *drawable, GdkGLContext *context);
+void          gdk_gl_swap_buffers(GdkGLDrawable *drawable);
 
 
 void          gdk_gl_wait_gdk(void);
@@ -110,13 +127,17 @@
 typedef struct _GdkGLPixmap GdkGLPixmap;
 
 GType        gdk_gl_pixmap_get_type(void);
-GdkGLPixmap *gdk_gl_pixmap_new(GdkVisual *visual, GdkPixmap *pixmap);
+GdkGLPixmap *gdk_gl_pixmap_new(GdkVisual *visual, GdkGLPixmapSource *pixmap);
 
 gint         gdk_gl_pixmap_make_current(GdkGLPixmap *glpixmap, GdkGLContext *context);
 
 
 /* fonts */
+#if defined __GTK3__
+void gdk_gl_use_pango_font(PangoFontDescription *fontdesc, int first, int count, int list_base);
+#elif defined __GTK2__
 void gdk_gl_use_gdk_font(GdkFont *font, int first, int count, int list_base);
+#endif
 
 
 #ifndef GTKGL_DISABLE_DEPRECATED
--- gtkgl/gdkgl.c	2014-04-27 14:24:34 +0000
+++ gtkgl/gdkgl.c	2014-04-28 07:37:46 +0000
@@ -30,6 +30,10 @@
 #elif defined GDK_WINDOWING_X11
 #   include <gdk/gdkx.h>
 #   include <GL/glx.h>
+#   ifdef __GTK3__
+#      include <cairo.h>
+#      include <cairo-xlib.h>
+#   endif
 #   define PLATFORM "GDK_WINDOWING_X11"
 #elif defined GDK_WINDOWING_FB
 #   define PLATFORM "GDK_WINDOWING_FB"
@@ -66,16 +70,16 @@
  *  The GdkGLPixmap class
  */
 struct _GdkGLPixmap {
-  GObject   parent;
+  GObject           parent;
 #if defined GDK_WINDOWING_WIN32
-  gboolean  initialised;
-  HDC       hdc;
-  HBITMAP   hbitmap;
-  GdkPixmap *pixmap;
-#elif defined GDK_WINDOWING_X11
-  Display   *xdisplay;
-  GLXPixmap glxpixmap;
-  GdkPixmap *front_left;
+  gboolean          initialised;
+  HDC               hdc;
+  HBITMAP           hbitmap;
+  GdkGLPixmapSource *pixmap;
+#elif defined GDK_WINDOWING_X11
+  Display           *xdisplay;
+  GLXPixmap         glxpixmap;
+  GdkGLPixmapSource *front_left;
 #endif
 };
 
@@ -353,16 +357,20 @@
 }
 
 
-gint gdk_gl_make_current(GdkDrawable *drawable, GdkGLContext *context)
+gint gdk_gl_make_current(GdkGLDrawable *drawable, GdkGLContext *context)
 {
-  g_return_val_if_fail (GDK_IS_DRAWABLE(drawable), FALSE);
+  g_return_val_if_fail (GDK_GL_IS_DRAWABLE(drawable), FALSE);
   g_return_val_if_fail (GDK_IS_GL_CONTEXT(context), FALSE);
 
 #if defined GDK_WINDOWING_WIN32
   if (!context->initialised)
   {
     int pf;
-    HWND hwnd = (HWND) gdk_win32_drawable_get_handle (drawable);
+#if defined __GTK3__
+    HWND hwnd = (HWND) gdk_win32_window_get_handle (GDK_WINDOW (drawable));
+#elif defined __GTK2__
+    HWND hwnd = (HWND) gdk_win32_drawable_get_handle (GDK_DRAWABLE (drawable));
+#endif
 
     context->hdc = GetDC (hwnd);
 
@@ -394,7 +402,7 @@
 
   return TRUE;
 #elif defined GDK_WINDOWING_X11
-  return (glXMakeCurrent(context->xdisplay, GDK_WINDOW_XWINDOW(drawable),
+  return (glXMakeCurrent(context->xdisplay, gdk_x11_window_get_xid(drawable),
 			 context->glxcontext) == True) ? TRUE : FALSE;
 
 #if 0
@@ -405,7 +413,7 @@
     }
   else
     {
-      return (glXMakeCurrent(context->xdisplay, GDK_WINDOW_XWINDOW(drawable), context->glxcontext) == True) ? TRUE : FALSE;
+      return (glXMakeCurrent(context->xdisplay, gdk_x11_window_get_xid(drawable), context->glxcontext) == True) ? TRUE : FALSE;
     }
 #endif
 #else
@@ -413,17 +421,21 @@
 #endif
 }
 
-void gdk_gl_swap_buffers(GdkDrawable *drawable)
+void gdk_gl_swap_buffers(GdkGLDrawable *drawable)
 {
 #if defined GDK_WINDOWING_WIN32
   HDC   hdc;
   HWND  hwnd;
 #endif
 
-  g_return_if_fail (GDK_IS_DRAWABLE(drawable));
+  g_return_if_fail (GDK_GL_IS_DRAWABLE(drawable));
 
 #if defined GDK_WINDOWING_WIN32
-  hwnd = (HWND) gdk_win32_drawable_get_handle (drawable);
+#  if defined __GTK3__
+  hwnd = (HWND) gdk_win32_window_get_handle (GDK_WINDOW (drawable));
+#  elif defined __GTK2__
+  hwnd = (HWND) gdk_win32_drawable_get_handle (GDK_DRAWABLE (drawable));
+#  endif
   hdc  = GetDC (hwnd);
   if (hdc  == NULL)
   {
@@ -501,7 +513,11 @@
 #if defined GDK_WINDOWING_WIN32
   glFinish ();
   SelectObject (pixmap->hdc, pixmap->hbitmap);
+#  if defined __GTK3__
+  g_object_unref (pixmap->pixmap);
+#  elif defined __GTK2__
   gdk_pixmap_unref (pixmap->pixmap);
+#  endif
 #elif defined GDK_WINDOWING_X11
   if (pixmap->glxpixmap != None) {
     glXDestroyGLXPixmap(pixmap->xdisplay, pixmap->glxpixmap);
@@ -509,7 +525,11 @@
   }
   pixmap->glxpixmap = None;
   if (pixmap->front_left) {
+#  if defined __GTK3__
+    g_object_unref(pixmap->front_left);
+#  elif defined __GTK2__
     gdk_pixmap_unref(pixmap->front_left);
+#endif
     glXWaitX();
   }
   pixmap->front_left = NULL;
@@ -530,7 +550,7 @@
 }
 
 GdkGLPixmap *
-gdk_gl_pixmap_new(GdkVisual *visual, GdkPixmap *pixmap)
+gdk_gl_pixmap_new(GdkVisual *visual, GdkGLPixmapSource *pixmap)
 {
   GdkGLPixmap *glpixmap;
 #ifndef GDK_WINDOWING_WIN32
@@ -548,7 +568,7 @@
 #endif
 
   g_return_val_if_fail(GDK_IS_VISUAL(visual), NULL);
-  g_return_val_if_fail(GDK_IS_PIXMAP(pixmap), NULL);
+  g_return_val_if_fail(GDK_GL_IS_PIXMAP_SOURCE(pixmap), NULL);
 
   glpixmap = g_object_new(GDK_TYPE_GL_PIXMAP, NULL);
   if (!glpixmap)
@@ -558,10 +578,30 @@
   glpixmap->initialised = FALSE;
   glpixmap->hdc = NULL;
   glpixmap->hbitmap = NULL;
+#  if defined __GTK3__
+  glpixmap->pixmap = g_object_ref (pixmap);
+#  elif defined __GTK2__
   glpixmap->pixmap = gdk_pixmap_ref (pixmap);
+#  endif
 #elif defined GDK_WINDOWING_X11
+
+#  if defined __GTK2__
   dpy = gdk_x11_get_default_xdisplay();
   xpixmap = (Pixmap)GDK_DRAWABLE_XID(pixmap);
+#  elif defined __GTK3__
+  dpy = gdk_x11_get_default_xdisplay();
+  xpixmap = XCreatePixmap (dpy, RootWindow(dpy, 0), gdk_pixbuf_get_width(pixmap), gdk_pixbuf_get_width(pixmap), 1);
+
+  cairo_t *cr;
+  cairo_surface_t *cs;
+
+  cs = cairo_xlib_surface_create_for_bitmap (dpy, xpixmap, DefaultScreenOfDisplay(dpy), gdk_pixbuf_get_width(pixmap), gdk_pixbuf_get_height(pixmap));
+  cr = cairo_create (cs);
+
+  gdk_cairo_set_source_pixbuf (cr, pixmap, 0, 0);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+#  endif
 
   g_return_val_if_fail(XGetGeometry(dpy, xpixmap, &root_return,
 				    &x_ret, &y_ret, &w_ret, &h_ret,
@@ -579,7 +619,11 @@
 
   glpixmap->xdisplay   = dpy;
   glpixmap->glxpixmap  = glxpixmap;
+#  if defined __GTK3__
+  glpixmap->front_left = g_object_ref(pixmap);
+#  elif defined __GTK2__
   glpixmap->front_left = gdk_pixmap_ref(pixmap);
+#  endif
 #endif
 
   return glpixmap;
@@ -650,6 +694,35 @@
  *  Font support
  */
 
+
+#if defined __GTK3__
+
+#  if defined GDK_WINDOWING_WIN32
+  __declspec(dllimport) HFONT _pango_win32_font_get_hfont (PangoFont *font);
+#  endif
+
+void gdk_gl_use_pango_font(PangoFontDescription *fontdesc, int first, int count, int list_base)
+{
+#if defined GDK_WINDOWING_WIN32
+  HDC dc = CreateCompatibleDC (NULL);
+  PangoContext *fontcontext = pango_context_new ();
+  PangoFontMap *fontmap = pango_cairo_font_map_get_default ();
+  PangoFont *font = pango_font_map_load_font (fontmap, fontcontext, fontdesc);
+  HFONT old_font = _pango_win32_font_get_hfont (font);
+  g_object_unref(fontcontext);
+
+  wglUseFontBitmaps (dc, first, count, list_base);
+
+  SelectObject (dc, old_font);
+  DeleteDC (dc);
+#elif defined GDK_WINDOWING_X11
+  g_return_if_fail(fontdesc != NULL);
+  g_warning ("gdk_gl_use_pango_font not implemented on " PLATFORM);
+#endif
+}
+
+#elif defined __GTK2__
+
 void gdk_gl_use_gdk_font(GdkFont *font, int first, int count, int list_base)
 {
 #if defined GDK_WINDOWING_WIN32
@@ -668,6 +741,7 @@
 #endif
 }
 
+#endif
 
 /*
  *  Helper functions
--- examples/simple.c	2014-04-07 15:48:56 +0000
+++ examples/simple.c	2014-04-28 05:11:51 +0000
@@ -23,6 +23,10 @@
 
 gint init(GtkWidget *widget)
 {
+  g_print ("GTK+ version : %d.%d.%d\n", GTK_MAJOR_VERSION,
+                                        GTK_MINOR_VERSION,
+                                        GTK_MICRO_VERSION);
+
   /* OpenGL functions can be called only if make_current returns true */
   if (gtk_gl_area_make_current(GTK_GL_AREA(widget)))
     {
@@ -40,15 +44,26 @@
 
 
 /* When widget is exposed it's contents are redrawn. */
+#if defined __GTK3__
+gboolean draw(GtkWidget *widget, cairo_t *cr)
+#elif defined __GTK2__
 gint draw(GtkWidget *widget, GdkEventExpose *event)
+#endif
 {
+# ifdef __GTK2__
   /* Draw only last expose. */
   if (event->count > 0)
     return TRUE;
+# endif
 
   /* OpenGL functions can be called only if make_current returns true */
   if (gtk_gl_area_make_current(GTK_GL_AREA(widget)))
     {
+#    ifdef __GTK3__
+      GtkAllocation allocation;
+      gtk_widget_get_allocation (widget, &allocation);
+      glViewport(0, 0, allocation.width, allocation.height);
+#    endif
 
       /* Draw simple triangle */
       glClearColor(0,0,0,1);
@@ -68,6 +83,7 @@
   return TRUE;
 }
 
+#ifdef __GTK2__
 /* When glarea widget size changes, viewport size is set to match the new size */
 gint reshape(GtkWidget *widget, GdkEventConfigure *event)
 {
@@ -80,6 +96,16 @@
     }
   return TRUE;
 }
+#endif
+
+#ifdef __GTK3__
+gboolean delete(GtkWidget *widget, GdkEvent *event)
+{
+  gtk_widget_destroy (widget);
+
+  return FALSE;
+}
+#endif
 
 
 int main(int argc, char **argv)
@@ -118,9 +144,18 @@
   gtk_container_set_border_width(GTK_CONTAINER(window), 10);
 
   /* Quit form main if got delete event */
+#if defined __GTK3__
+  g_signal_connect(G_OBJECT(window), "delete-event",
+                   G_CALLBACK(delete), NULL);
+  g_signal_connect(G_OBJECT(window), "destroy",
+                   G_CALLBACK(gtk_main_quit), NULL);
+#elif defined __GTK2__
   g_signal_connect(G_OBJECT(window), "delete-event",
                    G_CALLBACK(gtk_main_quit), NULL);
+#endif
+
 
+#ifdef __GTK2__
 
   /* You should always delete gtk_gl_area widgets before exit or else
      GLX contexts are left undeleted, this may cause problems (=core dump)
@@ -132,6 +167,7 @@
   */
   gtk_quit_add_destroy(1, GTK_OBJECT(window));
 
+#endif
 
   /* Create new OpenGL widget. */
   glarea = GTK_WIDGET(gtk_gl_area_new(attrlist));
@@ -142,11 +178,20 @@
 
   /* Connect signal handlers */
   /* Redraw image when exposed. */
+#if defined __GTK3__
+  g_signal_connect(G_OBJECT(glarea), "draw",
+                   G_CALLBACK(draw), NULL);
+#elif defined __GTK2__
   g_signal_connect(G_OBJECT(glarea), "expose-event",
                    G_CALLBACK(draw), NULL);
+#endif
+
+#if defined __GTK2__
   /* When window is resized viewport needs to be resized also. */
   g_signal_connect(G_OBJECT(glarea), "configure-event",
                    G_CALLBACK(reshape), NULL);
+#endif
+
   /* Do initialization when widget has been realized. */
   g_signal_connect(G_OBJECT(glarea), "realize",
                    G_CALLBACK(init), NULL);
--- examples/zktor.c	2014-04-07 15:48:56 +0000
+++ examples/zktor.c	2014-04-28 05:44:37 +0000
@@ -737,7 +737,9 @@
 {
   /* OpenGL functions can be called only if makecurrent returns true */
   if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) {
-#if !defined(WIN32)
+#if defined __GTK3__
+    PangoFontDescription *fontdesc;
+#elif defined __GTK2__
     GdkFont *font;
 #endif
 
@@ -746,8 +748,15 @@
     gtk_widget_get_allocation (widget, &allocation);
     glViewport(0, 0, allocation.width, allocation.height);
 
-#if !defined(WIN32)
     /* generate font display lists */
+#if defined __GTK3__
+    fontdesc = pango_font_description_from_string("Sans 10");
+    if (fontdesc) {
+      fontbase = glGenLists( 128 );
+      gdk_gl_use_pango_font(fontdesc, 0, 128, fontbase);
+      pango_font_description_free(fontdesc);
+    }
+#elif defined __GTK2__
     font = gdk_font_load("-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*");
     if (font) {
       fontbase = glGenLists( 128 );
@@ -761,14 +770,28 @@
 
 
 /* When widget is exposed it's contents are redrawn. */
+#if defined __GTK3__
+gboolean draw(GtkWidget *widget, cairo_t *cr)
+#elif defined __GTK2__
 gint draw(GtkWidget *widget, GdkEventExpose *event)
+#endif
 {
+# ifdef __GTK2__
   /* Draw only last expose. */
   if (event->count > 0)
     return TRUE;
+# endif
 
   if (gtk_gl_area_make_current(GTK_GL_AREA(widget)))
-    game_render();
+    {
+#    ifdef __GTK3__
+      GtkAllocation allocation;
+      gtk_widget_get_allocation (widget, &allocation);
+      glViewport(0, 0, allocation.width, allocation.height);
+#    endif
+
+      game_render();
+    }
 
   /* Swap backbuffer to front */
   gtk_gl_area_swap_buffers(GTK_GL_AREA(widget));
@@ -776,6 +799,7 @@
   return TRUE;
 }
 
+#ifdef __GTK2__
 /* When glarea widget size changes, viewport size is set to match the new size */
 gint reshape(GtkWidget *widget, GdkEventConfigure *event)
 {
@@ -788,38 +812,38 @@
     }
   return TRUE;
 }
-
+#endif
 
 gint key_press_event(GtkWidget *widget, GdkEventKey *event)
 {
   switch (event->keyval) {
-  case GDK_Left:
+  case GDK_KEY_Left:
     control_spin = 1;
     break;
-  case GDK_Right:
+  case GDK_KEY_Right:
     control_spin = -1;
     break;
-  case GDK_Up:
-  case GDK_space:
+  case GDK_KEY_Up:
+  case GDK_KEY_space:
     control_fire = 1;
     break;
-  case GDK_Down:
+  case GDK_KEY_Down:
     control_speed = 1;
     break;
-  case GDK_r:
+  case GDK_KEY_r:
     game_init();
     break;
-  case GDK_q:
+  case GDK_KEY_q:
     gtk_main_quit();
     break;
 
 #ifdef FULLSCREEN_MESA_3DFX
-  case GDK_f:
+  case GDK_KEY_f:
     switch_fullscreen(widget);
     break;
 #endif
 
-  case GDK_d:
+  case GDK_KEY_d:
     draw_fast = (!draw_fast);
     break;
   }
@@ -832,17 +856,17 @@
 gint key_release_event(GtkWidget *widget, GdkEventKey *event)
 {
   switch (event->keyval) {
-  case GDK_Left:
+  case GDK_KEY_Left:
     if (control_spin == 1) control_spin = 0;
     break;
-  case GDK_Right:
+  case GDK_KEY_Right:
     if (control_spin == -1) control_spin = 0;
     break;
-  case GDK_Up:
-  case GDK_space:
+  case GDK_KEY_Up:
+  case GDK_KEY_space:
     control_fire = 0;
     break;
-  case GDK_Down:
+  case GDK_KEY_Down:
     control_speed = 0;
     break;
   }
@@ -858,6 +882,15 @@
   return TRUE;
 }
 
+#ifdef __GTK3__
+gboolean delete(GtkWidget *widget, GdkEvent *event)
+{
+  gtk_widget_destroy (widget);
+
+  return FALSE;
+}
+#endif
+
 
 int main(int argc, char **argv)
 {
@@ -897,9 +930,18 @@
   gtk_window_set_title(GTK_WINDOW(window), "Zktor");
 
   /* Quit form main if got delete event */
+#if defined __GTK3__
   g_signal_connect(G_OBJECT(window), "delete-event",
+                   G_CALLBACK(delete), NULL);
+  g_signal_connect(G_OBJECT(window), "destroy",
                    G_CALLBACK(gtk_main_quit), NULL);
+#elif defined __GTK2__
+  g_signal_connect(G_OBJECT(window), "delete-event",
+                   G_CALLBACK(gtk_main_quit), NULL);
+#endif
+
 
+#ifdef __GTK2__
 
   /* You should always delete gtk_gl_area widgets before exit or else
      GLX contexts are left undeleted, this may cause problems (=core dump)
@@ -911,8 +953,13 @@
   */
   gtk_quit_add_destroy(1, GTK_OBJECT(window));
 
+#endif
 
+#if defined __GTK3__
+  vbox = GTK_WIDGET(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0));
+#elif defined __GTK2__
   vbox = GTK_WIDGET(gtk_vbox_new(FALSE, 0));
+#endif
   gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
 
 
@@ -934,11 +981,20 @@
 
   /* Connect signal handlers */
   /* Redraw image when exposed. */
+#if defined __GTK3__
+  g_signal_connect(G_OBJECT(glarea), "draw",
+                   G_CALLBACK(draw), NULL);
+#elif defined __GTK2__
   g_signal_connect(G_OBJECT(glarea), "expose-event",
                    G_CALLBACK(draw), NULL);
+#endif
+
+#if defined __GTK2__
   /* When window is resized viewport needs to be resized also. */
   g_signal_connect(G_OBJECT(glarea), "configure-event",
                    G_CALLBACK(reshape), NULL);
+#endif
+
   /* Do initialization when widget has been realized. */
   g_signal_connect(G_OBJECT(glarea), "realize",
                    G_CALLBACK(init), NULL);
--- examples/viewlw.c	2014-04-27 21:51:48 +0000
+++ examples/viewlw.c	2014-04-27 22:31:10 +0000
@@ -101,17 +101,23 @@
     glFrustum(-fW, fW, -fH, fH, zNear, zFar);
 }
 
-gint glarea_expose(GtkWidget *widget, GdkEventExpose *event)
+#if defined __GTK3__
+gint glarea_draw(GtkWidget *widget, cairo_t *cr)
+#elif defined __GTK2__
+gint glarea_draw(GtkWidget *widget, GdkEventExpose *event)
+#endif
 {
   GLfloat m[4][4];
 
   GtkGLArea *glarea = GTK_GL_AREA(widget);
-  mesh_info *info = (mesh_info*)gtk_object_get_data(GTK_OBJECT(widget), "mesh_info");
+  mesh_info *info = (mesh_info*)g_object_get_data(G_OBJECT(widget), "mesh_info");
 
+# ifdef __GTK2__
   /* draw only last expose */
   if (event->count > 0) {
     return TRUE;
   }
+# endif
 
   /* OpenGL calls can be done only if make_current returns true */
   if (gtk_gl_area_make_current(glarea)) {
@@ -121,6 +127,12 @@
       info->do_init = FALSE;
     }
 
+#  ifdef __GTK3__
+    GtkAllocation allocation;
+    gtk_widget_get_allocation (widget, &allocation);
+    glViewport(0, 0, allocation.width, allocation.height);
+#  endif
+
     /* view */
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
@@ -145,6 +157,7 @@
   return TRUE;
 }
 
+#ifdef __GTK2__
 gint glarea_configure(GtkWidget *widget, GdkEventConfigure *event)
 {
   /* OpenGL calls can be done only if make_current returns true */
@@ -155,11 +168,12 @@
   }
   return TRUE;
 }
+#endif
 
 gint glarea_destroy(GtkWidget *widget)
 {
   /* delete mesh info */
-  mesh_info *info = (mesh_info*)gtk_object_get_data(GTK_OBJECT(widget),"mesh_info");
+  mesh_info *info = (mesh_info*)g_object_get_data(G_OBJECT(widget),"mesh_info");
   if (info) {
     lw_object_free(info->lwobject);
     g_free(info);
@@ -169,7 +183,7 @@
 
 gint glarea_button_press(GtkWidget *widget, GdkEventButton *event)
 {
-  mesh_info *info = (mesh_info*)gtk_object_get_data(GTK_OBJECT(widget), "mesh_info");
+  mesh_info *info = (mesh_info*)g_object_get_data(G_OBJECT(widget), "mesh_info");
   if (event->button == 1) {
     /* beginning of drag, reset mouse position */
     info->beginx = event->x;
@@ -182,10 +196,15 @@
 gint glarea_motion_notify(GtkWidget *widget, GdkEventMotion *event)
 {
   int x, y;
+#if defined __GTK3__
+  cairo_t *area;
+  cairo_surface_t *surface;
+#elif defined __GTK2__
   GdkRectangle area;
+#endif
   GdkModifierType state;
   GtkAllocation allocation;
-  mesh_info *info = (mesh_info*)gtk_object_get_data(GTK_OBJECT(widget), "mesh_info");
+  mesh_info *info = (mesh_info*)g_object_get_data(G_OBJECT(widget), "mesh_info");
 
   if (event->is_hint) {
     /* fix this! */
@@ -198,36 +217,62 @@
     state = event->state;
   }
 
+  gtk_widget_get_allocation (widget, &allocation);
+#if defined __GTK3__
+  surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
+                                               CAIRO_CONTENT_COLOR,
+                                               allocation.width, allocation.height);
+#elif defined __GTK2__
   area.x = 0;
   area.y = 0;
-  gtk_widget_get_allocation (widget, &allocation);
   area.width  = allocation.width;
   area.height = allocation.height;
+#endif
 
   if (state & GDK_BUTTON1_MASK) {
     /* drag in progress, simulate trackball */
     float spin_quat[4];
     trackball(spin_quat,
-	      (2.0*info->beginx -       area.width) / area.width,
-	      (     area.height - 2.0*info->beginy) / area.height,
-	      (           2.0*x -       area.width) / area.width,
-	      (     area.height -            2.0*y) / area.height);
+	     ( 2.0*info->beginx - allocation.width) / allocation.width,
+	     (allocation.height - 2.0*info->beginy) / allocation.height,
+	     (            2.0*x - allocation.width) / allocation.width,
+	     (allocation.height -            2.0*y) / allocation.height);
     add_quats(spin_quat, info->quat, info->quat);
     /* orientation has changed, redraw mesh */
+# if defined __GTK3__
+    area = cairo_create (surface);
+    cairo_set_source_rgb (area, 1, 1, 1);
+    gtk_widget_draw (widget, area);
+    cairo_paint (area);
+    cairo_destroy (area);
+# elif defined __GTK2__
     gtk_widget_queue_draw_area (widget, area.x, area.y, area.width, area.height);
+# endif
   }
 
   if (state & GDK_BUTTON2_MASK) {
     /* zooming drag */
-    info->zoom += ((y - info->beginy) / area.height) * 40;
+    info->zoom += ((y - info->beginy) / allocation.height) * 40;
     if (info->zoom < 5) info->zoom = 5;
     if (info->zoom > 120) info->zoom = 120;
     /* zoom has changed, redraw mesh */
+# if defined __GTK3__
+    area = cairo_create (surface);
+    cairo_set_source_rgb (area, 1, 1, 1);
+    gtk_widget_draw (widget, area);
+    cairo_paint (area);
+    cairo_destroy (area);
+#elif defined __GTK2__
     gtk_widget_queue_draw_area (widget, area.x, area.y, area.width, area.height);
+#  endif
   }
   info->beginx = x;
   info->beginy = y;
 
+#ifdef __GTK3__
+  cairo_surface_destroy (surface);
+#endif
+
   return TRUE;
 }
 
@@ -284,6 +329,8 @@
 gint window_count = 0; /* number of windows on screen */
 gint window_destroy(GtkWidget *widget)
 {
+  gtk_widget_destroy(widget);
+
   /* if this was last window quit */
   if (--window_count == 0)
     gtk_main_quit();
@@ -332,14 +379,21 @@
 			GDK_BUTTON_RELEASE_MASK|
 			GDK_POINTER_MOTION_MASK|
 			GDK_POINTER_MOTION_HINT_MASK);
+#if defined __GTK3__
+  g_signal_connect (G_OBJECT(glarea), "draw",
+                    G_CALLBACK(glarea_draw), NULL);
+#elif defined __GTK2__
   g_signal_connect (G_OBJECT(glarea), "expose-event",
-                    G_CALLBACK(glarea_expose), NULL);
+                    G_CALLBACK(glarea_draw), NULL);
+#endif
   g_signal_connect (G_OBJECT(glarea), "motion-notify-event",
                     G_CALLBACK(glarea_motion_notify), NULL);
   g_signal_connect (G_OBJECT(glarea), "button-press-event",
                     G_CALLBACK(glarea_button_press), NULL);
+#if defined __GTK2__
   g_signal_connect (G_OBJECT(glarea), "configure-event",
                     G_CALLBACK(glarea_configure), NULL);
+#endif
   g_signal_connect (G_OBJECT(glarea), "destroy",
                     G_CALLBACK(glarea_destroy), NULL);
 
@@ -353,7 +407,7 @@
   info->beginy = 0;
   info->zoom   = 45;
   trackball(info->quat , 0.0, 0.0, 0.0, 0.0);
-  gtk_object_set_data(GTK_OBJECT(glarea), "mesh_info", info);
+  g_object_set_data(G_OBJECT(glarea), "mesh_info", info);
 
 
   /* create new top level window */
--- examples/gtkglarea_demo.c	2014-04-27 23:44:22 +0000
+++ examples/gtkglarea_demo.c	2014-04-28 05:39:14 +0000
@@ -50,7 +50,11 @@
 gint       glarea_button_release (GtkWidget*, GdkEventButton*);
 gint       glarea_button_press   (GtkWidget*, GdkEventButton*);
 gint       glarea_motion_notify  (GtkWidget*, GdkEventMotion*);
+#if defined __GTK3__
+gint       glarea_draw           (GtkWidget*, cairo_t*);
+#elif defined __GTK2__
 gint       glarea_draw           (GtkWidget*, GdkEventExpose*);
+#endif
 gint       glarea_reshape        (GtkWidget*, GdkEventConfigure*);
 gint       glarea_init           (GtkWidget*);
 gint       glarea_destroy        (GtkWidget*);
@@ -150,18 +154,27 @@
   g_signal_connect (G_OBJECT(glarea), "motion-notify-event",
                     G_CALLBACK(glarea_motion_notify), NULL);
 
+#if defined __GTK3__
+  /* draw - The window contents need to be redrawn.           */
+
+  g_signal_connect (G_OBJECT(glarea), "draw",
+                    G_CALLBACK(glarea_draw), NULL);
+#elif defined __GTK2__
   /* expose_event - The window was exposed and the contents   */
   /*                need to be redrawn.                       */
 
   g_signal_connect (G_OBJECT(glarea), "expose-event",
                     G_CALLBACK(glarea_draw), NULL);
+#endif
 
+#if defined __GTK2__
   /* configure_event - The window has been resized. You will  */
   /*                   probably want to call your reshape     */
   /*                   function here.                         */
 
   g_signal_connect (G_OBJECT(glarea), "configure-event",
                     G_CALLBACK(glarea_reshape), NULL);
+#endif
 
   /* realize - The window has been created, this is where you */
   /*           can hook up your initialization routines.      */
@@ -271,7 +284,11 @@
   GdkModifierType state;
 
   if (event->is_hint) {
+#if defined __GTK3__
+    gdk_window_get_device_position(event->window, event->device, &x, &y, &state);
+#elif defined __GTK2__
     gdk_window_get_pointer(event->window, &x, &y, &state);
+#endif
   } else {
     x = event->x;
     y = event->y;
@@ -298,28 +315,42 @@
 
 /*****************************************************************************/
 /*                                                                           */
-/* Function: glarea_draw (GtkWidget*, GdkEventExpose*)                       */
+/* Function: glarea_draw (GtkWidget*, cairo_t*)                              */
 /*                                                                           */
 /* This is the function that should render your scene to the GtkGLArea. It   */
 /* can be used as a callback to the 'Expose' event.                          */
 /*                                                                           */
 /*****************************************************************************/
 
-gint glarea_draw (GtkWidget* widget, GdkEventExpose* event) {
-
+#if defined __GTK3__
+gint glarea_draw (GtkWidget* widget, cairo_t* cr)
+#elif defined __GTK2__
+gint glarea_draw (GtkWidget* widget, GdkEventExpose* event)
+#endif
+{
+# ifdef __GTK2__
   /* Draw only on the last expose event. */
 
   if (event->count > 0) {
     return(TRUE);
   }
+#endif
 
-  g_print ("Expose Event\n");
+  g_print ("Draw Event\n");
 
   /* gtk_gl_area_make_current MUST be called before rendering */
   /* into the GtkGLArea.                                      */
 
   if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) {
 
+# ifdef __GTK3__
+    /* Resize the viewport according to the window */
+
+    GtkAllocation allocation;
+    gtk_widget_get_allocation (widget, &allocation);
+    glViewport(0, 0, allocation.width, allocation.height);
+#endif
+
     /* Clear the drawing color buffer and depth buffers */
     /* before drawing.                                  */
 
@@ -342,6 +373,7 @@
 
 }
 
+#ifdef __GTK2__
 /*****************************************************************************/
 /*                                                                           */
 /* Function: glarea_reshape (GtkWidget*, GdkEventConfigure*)                 */
@@ -382,6 +414,7 @@
   return (TRUE);
 
 }
+#endif
 
 /*****************************************************************************/
 /*                                                                           */
@@ -429,6 +462,27 @@
 
 }
 
+#ifdef __GTK3__
+/*****************************************************************************/
+/*                                                                           */
+/* Function: glarea_delete (GtkWidget*)                                      */
+/*                                                                           */
+/* This function is a callback for the main GtkGLArea. It deletes should     */
+/* delete any data structures stored in the GtkGLArea.                       */
+/*                                                                           */
+/*****************************************************************************/
+
+gint glarea_delete (GtkWidget* widget) {
+
+  g_print ("GTK GL Area Delete Event\n");
+
+  gtk_widget_destroy (widget);
+
+  return TRUE;
+
+}
+#endif
+
 /*****************************************************************************/
 /*                                                                           */
 /* Function: main (int, char**)                                              */
@@ -449,7 +503,11 @@
 
   /* Main widget container */
 
+#if defined __GTK3__
+  box_main = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
+#elif defined __GTK2__
   box_main = gtk_vbox_new (FALSE, 10);
+#endif
 
   /* GTK GL Area */
 
@@ -468,6 +526,13 @@
 
   gtk_window_set_title (GTK_WINDOW(window), "GtkGLArea Demo");
 
+#if defined __GTK3__
+ g_signal_connect (G_OBJECT(window), "delete-event",
+                    G_CALLBACK(glarea_delete), NULL);
+
+  g_signal_connect (G_OBJECT (window), "destroy",
+                    G_CALLBACK(gtk_main_quit), NULL);
+#elif defined __GTK2__
   /* destroy this window when exiting from gtk_main() */
 
   gtk_quit_add_destroy (1, GTK_OBJECT(window));
@@ -477,6 +542,7 @@
 
   g_signal_connect (G_OBJECT (window), "destroy",
                     G_CALLBACK(gtk_main_quit), NULL);
+#endif
 
   gtk_container_set_border_width (GTK_CONTAINER(window), 10);
 
@@ -486,7 +552,7 @@
   /* it, it's contents are already there. Otherwise they    */
   /* might see each widget come up.                         */
 
-  gtk_box_pack_start (GTK_BOX(box_main), glarea,      FALSE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX(box_main), glarea,      TRUE, TRUE, 0);
   gtk_box_pack_start (GTK_BOX(box_main), button_quit, FALSE, TRUE, 0);
   gtk_container_add (GTK_CONTAINER(window), box_main);
 
--- examples/gdkfont.c	2014-04-27 22:54:26 +0000
+++ examples/gdkfont.c	2014-04-27 23:42:36 +0000
@@ -33,27 +33,43 @@
 gint init(GtkWidget *widget)
 {
   if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) {
+#if defined __GTK3__
+    PangoFontDescription *font;
+#elif defined __GTK2__
     GdkFont *font;
+#endif
 
     /* set viewport */
-    glViewport(0,0, widget->allocation.width, widget->allocation.height);
+    GtkAllocation allocation;
+    gtk_widget_get_allocation (widget, &allocation);
+    glViewport(0,0, allocation.width, allocation.height);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
-    glOrtho(0,widget->allocation.width, 0,widget->allocation.height, -1.0, 1.0);
+    glOrtho(0,allocation.width, 0,allocation.height, -1.0, 1.0);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
 
     /* generate font display lists */
     fontbase = glGenLists( 128 );
+#if defined __GTK3__
+    font = pango_font_description_from_string(fontname);
+#elif defined __GTK2__
     font = gdk_font_load(fontname);
+#endif
     if (!font) {
       g_print("Can't load font '%s'\n", fontname);
-      gtk_exit(1);
+      return -1;
     }
 
+#if defined __GTK3__
+    gdk_gl_use_pango_font(font, 0, 128, fontbase);
+    fontheight = pango_font_description_get_size(font);
+    pango_font_description_free(font);
+#elif defined __GTK2__
     gdk_gl_use_gdk_font(font, 0, 128, fontbase);
     fontheight = font->ascent+font->descent;
     gdk_font_unref(font);
+#endif
 
   }
   return TRUE;
@@ -63,14 +79,22 @@
 /* When widget is exposed it's contents are redrawn. */
 gint draw(GtkWidget *widget, GdkEventExpose *event)
 {
+#ifdef __GTK2__
   /* Draw only last expose. */
   if (event->count > 0) {
     return TRUE;
   }
+#endif
 
   if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) {
     int i,j;
 
+    GtkAllocation allocation;
+    gtk_widget_get_allocation (widget, &allocation);
+#  ifdef __GTK3__
+    glViewport(0, 0, allocation.width, allocation.height);
+#  endif
+
     /* clear screen */
     glClearColor(0,0,1,1);
     glClear(GL_COLOR_BUFFER_BIT);
@@ -78,7 +102,7 @@
     /* Draw some text */
     glColor3f(1,1,1);
     for (i=1; i<5; i++) {
-      glRasterPos2f(10, widget->allocation.height-i*fontheight);
+      glRasterPos2f(10, allocation.height-i*fontheight);
       for (j=' '; j<='Z'; j++) {
 	glCallList(fontbase+j);
       }
@@ -96,6 +120,7 @@
   return TRUE;
 }
 
+#ifdef __GTK2__
 /* When glarea widget size changes, viewport size is set to match the new size */
 gint reshape(GtkWidget *widget, GdkEventConfigure *event)
 {
@@ -111,6 +136,16 @@
   }
   return TRUE;
 }
+#endif
+
+#ifdef __GTK3__
+gboolean delete(GtkWidget *widget, GdkEvent *event)
+{
+  gtk_widget_destroy (widget);
+
+  return FALSE;
+}
+#endif
 
 
 int main(int argc, char **argv)
@@ -120,7 +155,11 @@
   gtk_init(&argc, &argv);
 
   if (argc == 1) {
+#if defined __GTK3__
+    fontname = "Sans 10";
+#elif defined __GTK2__
     fontname = "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*";
+#endif
   } else if (argc == 2) {
     fontname = argv[1];
   } else if (argc > 2) {
@@ -141,11 +180,20 @@
   gtk_container_set_border_width(GTK_CONTAINER(window), 10);
 
   /* Quit form main if got delete event */
-  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
-		     GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
+#if defined __GTK3__
+  g_signal_connect(G_OBJECT(window), "delete-event",
+                   G_CALLBACK(delete), NULL);
+  g_signal_connect(G_OBJECT(window), "destroy",
+                   G_CALLBACK(gtk_main_quit), NULL);
+#elif defined __GTK2__
+  g_signal_connect(G_OBJECT(window), "delete_event",
+		   G_CALLBACK(gtk_main_quit), NULL);
+#endif
 
+#ifdef __GTK2__
   /* Delete  widget before exit */
   gtk_quit_add_destroy(1, GTK_OBJECT(window));
+#endif
 
   /* Create new OpenGL widget. */
   glarea = GTK_WIDGET(gtk_gl_area_new_vargs(NULL,
@@ -161,14 +209,21 @@
 			GDK_BUTTON_PRESS_MASK);
 
   /* Connect signal handlers */
-  gtk_signal_connect(GTK_OBJECT(glarea), "expose_event",
-		     GTK_SIGNAL_FUNC(draw), NULL);
-  gtk_signal_connect(GTK_OBJECT(glarea), "configure_event",
-		     GTK_SIGNAL_FUNC(reshape), NULL);
-  gtk_signal_connect(GTK_OBJECT(glarea), "realize",
-		     GTK_SIGNAL_FUNC(init), NULL);
+#if defined __GTK3__
+  g_signal_connect(G_OBJECT(glarea), "draw",
+		   G_CALLBACK(draw), NULL);
+#elif defined __GTK2__
+  g_signal_connect(G_OBJECT(glarea), "expose_event",
+		   G_CALLBACK(draw), NULL);
+#endif
+#ifdef __GTK2__
+  g_signal_connect(G_OBJECT(glarea), "configure_event",
+		   G_CALLBACK(reshape), NULL);
+#endif
+  g_signal_connect(G_OBJECT(glarea), "realize",
+		   G_CALLBACK(init), NULL);
 
-  gtk_widget_set_usize(GTK_WIDGET(glarea), 450,100);
+  gtk_widget_set_size_request(GTK_WIDGET(glarea), 450,100);
 
   /* put glarea into window and show it all */
   gtk_container_add(GTK_CONTAINER(window),GTK_WIDGET(glarea));
--- examples/glpixmap.c	2014-04-27 22:34:59 +0000
+++ examples/glpixmap.c	2014-04-27 22:53:05 +0000
@@ -41,7 +41,7 @@
 {
   GtkWidget *window,*pixmapwidget;
   GdkVisual *visual;
-  GdkPixmap *pixmap;
+  GdkGLPixmapSource *pixmap;
   GdkGLPixmap *glpixmap;
   GdkGLContext *context;
 
@@ -59,21 +59,27 @@
     g_print("Can't get visual\n");
     return 0;
   }
+#ifdef __GTK2__
   gtk_widget_set_default_colormap(gdk_colormap_new(visual, TRUE));
   gtk_widget_set_default_visual(visual);
+#endif
 
   /* top level window. */
   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title(GTK_WINDOW(window), "glpixmap");
   gtk_container_set_border_width(GTK_CONTAINER(window), 10);
-  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
-		     GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
-  gtk_widget_set_usize(window, 100,100);
+  g_signal_connect(G_OBJECT(window), "delete-event",
+		     G_CALLBACK(gtk_main_quit), NULL);
+  gtk_widget_set_size_request(window, 100,100);
   gtk_widget_show(window);
 
   /* pixmap */
   context  = gdk_gl_context_new(visual);
+#if defined __GTK3__
+  pixmap = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 80,80);
+#elif defined __GTK2__
   pixmap = gdk_pixmap_new(NULL, 80,80, gdk_visual_get_depth (visual));
+#endif
   glpixmap = gdk_gl_pixmap_new(visual, pixmap);
   if (gdk_gl_pixmap_make_current(glpixmap, context)) {
     glMatrixMode(GL_PROJECTION);
@@ -96,8 +102,13 @@
 
 
   /* pixmapwidget */
+#if defined __GTK3__
+  pixmapwidget = gtk_image_new_from_pixbuf( pixmap );
+  g_object_unref(pixmap);
+#elif defined __GTK2__
   pixmapwidget = gtk_pixmap_new( pixmap, NULL );
   gdk_pixmap_unref(pixmap);
+#endif
 
   gtk_container_add(GTK_CONTAINER(window), pixmapwidget);
   gtk_widget_show(pixmapwidget);
--- examples/shaders.c	2014-04-28 07:03:09 +0000
+++ examples/shaders.c	2014-04-28 07:15:08 +0000              *
@@ -40,7 +40,11 @@
 void       create_shader         (void);
 void       create_texture_2D     (void);
 GtkWidget* create_glarea         (void);
+#if defined __GTK3__
+gint       glarea_draw           (GtkWidget*, cairo_t*);
+#elif defined __GTK2__
 gint       glarea_draw           (GtkWidget*, GdkEventExpose*);
+#endif
 gint       glarea_draw_scene     (void);
 gint       glarea_reshape        (GtkWidget*, GdkEventConfigure*);
 gint       glarea_init           (GtkWidget*);
@@ -244,11 +248,18 @@
 
   gtk_widget_set_events(GTK_WIDGET(glarea), GDK_EXPOSURE_MASK);
 
+#if defined __GTK3__
+  g_signal_connect (G_OBJECT(glarea), "draw",
+                    G_CALLBACK(glarea_draw), NULL);
+#elif defined __GTK2__
   g_signal_connect (G_OBJECT(glarea), "expose-event",
                     G_CALLBACK(glarea_draw), NULL);
+#endif
 
+#if defined __GTK2__
   g_signal_connect (G_OBJECT(glarea), "configure-event",
                     G_CALLBACK(glarea_reshape), NULL);
+#endif
 
   g_signal_connect (G_OBJECT(glarea), "realize",
                     G_CALLBACK(glarea_init), NULL);
@@ -285,21 +296,33 @@
 
 /*****************************************************************************/
 /*                                                                           */
-/* Function: glarea_draw (GtkWidget*, GdkEventExpose*)                       */
+/* Function: glarea_draw (GtkWidget*, cairot_t*)                             */
 /*                                                                           */
 /* This is the function that should render your scene to the GtkGLArea. It   */
 /* can be used as a callback to the 'Expose' event.                          */
 /*                                                                           */
 /*****************************************************************************/
 
-gint glarea_draw (GtkWidget* widget, GdkEventExpose* event) {
-
+#if defined __GTK3__
+gint glarea_draw (GtkWidget* widget, cairo_t* cr)
+#elif defined __GTK2__
+gint glarea_draw (GtkWidget* widget, GdkEventExpose* event)
+#endif
+{
+# ifdef __GTK2__
   if (event->count > 0) {
     return(TRUE);
   }
+#endif
 
   if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) {
 
+#    ifdef __GTK3__
+      GtkAllocation allocation;
+      gtk_widget_get_allocation (widget, &allocation);
+      glViewport(0, 0, allocation.width, allocation.height);
+#    endif
+
     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glarea_draw_scene();
     gtk_gl_area_swap_buffers (GTK_GL_AREA(widget));
@@ -310,6 +333,7 @@
 
 }
 
+#ifdef __GTK2__
 /*****************************************************************************/
 /*                                                                           */
 /* Function: glarea_reshape (GtkWidget*, GdkEventConfigure*)                 */
@@ -340,6 +364,7 @@
   return (TRUE);
 
 }
+#endif
 
 /*****************************************************************************/
 /*                                                                           */
@@ -382,6 +407,23 @@
 
 /*****************************************************************************/
 /*                                                                           */
+/* Function: glarea_delete (GtkWidget*)                                     */
+/*                                                                           */
+/* This function is a callback for the main GtkGLArea. It deletes should     */
+/* delete any data structures stored in the GtkGLArea.                       */
+/*                                                                           */
+/*****************************************************************************/
+
+gint glarea_delete (GtkWidget* widget) {
+
+  gtk_widget_destroy (widget);
+
+  return TRUE;
+
+}
+
+/*****************************************************************************/
+/*                                                                           */
 /* Function: glarea_destroy (GtkWidget*)                                     */
 /*                                                                           */
 /* This function is a callback for the main GtkGLArea. It deletes should     */
@@ -421,7 +463,11 @@
 
   /* Main widget container */
 
+#if defined __GTK3__
+  box_main = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
+#elif defined __GTK2__
   box_main = gtk_vbox_new (FALSE, 10);
+#endif
 
   /* GTK GL Area */
 
@@ -446,12 +492,19 @@
 
   gtk_window_set_title (GTK_WINDOW(window), "GtkGLArea Shader Demo");
 
+#ifdef __GTK2__
   /* destroy this window when exiting from gtk_main() */
 
   gtk_quit_add_destroy (1, GTK_OBJECT(window));
+#endif
 
+#if defined __GTK3__
+  g_signal_connect (G_OBJECT(window), "delete-event",
+                    G_CALLBACK(glarea_delete), NULL);
+#elif defined __GTK2__
   g_signal_connect (G_OBJECT(window), "delete-event",
                     G_CALLBACK(gtk_main_quit), NULL);
+#endif
 
   g_signal_connect (G_OBJECT (window), "destroy",
                     G_CALLBACK(gtk_main_quit), NULL);
--- AUTHORS	2014-04-07 15:32:04 +0000
+++ AUTHORS	2014-04-28 07:18:07 +0000
@@ -18,4 +18,9 @@
  Chris Abernethy <chris65536@home.com> (gtkglarea_demo.c)
  Ryan Corder <ryanc@greengrey.org> (Arch support)
  Iwan Gabovitch <qubodup@gmail.com> (Arch support)
+ Manuel Bachmann <tarnyko@tarnyko.net> (GTK+3 support)
+
+Contributors licensing
+----------------------
+ Manuel Bachmann : all contributions placed under the WTFPL license ;-)
 
--- gtkgl/gtkgl.def	2014-04-07 15:48:56 +0000
+++ /dev/null	2014-04-28 09:05:41 +0000
@@ -1,21 +0,0 @@
-EXPORTS
-	gdk_gl_choose_visual
-	gdk_gl_context_attrlist_share_new
-	gdk_gl_context_new
-	gdk_gl_context_share_new
-	gdk_gl_get_config
-	gdk_gl_get_info
-	gdk_gl_make_current
-	gdk_gl_pixmap_make_current
-	gdk_gl_pixmap_new
-	gdk_gl_query
-	gdk_gl_swap_buffers
-	gdk_gl_use_gdk_font
-	gdk_gl_wait_gdk
-	gdk_gl_wait_gl
-	gtk_gl_area_get_type
-	gtk_gl_area_make_current
-	gtk_gl_area_new
-	gtk_gl_area_new_vargs
-	gtk_gl_area_share_new
-	gtk_gl_area_swap_buffers
--- /dev/null	2014-04-28 09:06:16 +0000
+++ gtkgl/gtkgl2.def	2014-04-07 15:48:56 +0000
@@ -0,0 +1,21 @@
+EXPORTS
+	gdk_gl_choose_visual
+	gdk_gl_context_attrlist_share_new
+	gdk_gl_context_new
+	gdk_gl_context_share_new
+	gdk_gl_get_config
+	gdk_gl_get_info
+	gdk_gl_make_current
+	gdk_gl_pixmap_make_current
+	gdk_gl_pixmap_new
+	gdk_gl_query
+	gdk_gl_swap_buffers
+	gdk_gl_use_gdk_font
+	gdk_gl_wait_gdk
+	gdk_gl_wait_gl
+	gtk_gl_area_get_type
+	gtk_gl_area_make_current
+	gtk_gl_area_new
+	gtk_gl_area_new_vargs
+	gtk_gl_area_share_new
+	gtk_gl_area_swap_buffers
--- /dev/null	2014-04-28 09:06:20 +0000
+++ gtkgl/gtkgl3.def	2014-04-27 20:19:48 +0000
@@ -0,0 +1,21 @@
+EXPORTS
+	gdk_gl_choose_visual
+	gdk_gl_context_attrlist_share_new
+	gdk_gl_context_new
+	gdk_gl_context_share_new
+	gdk_gl_get_config
+	gdk_gl_get_info
+	gdk_gl_make_current
+	gdk_gl_pixmap_make_current
+	gdk_gl_pixmap_new
+	gdk_gl_query
+	gdk_gl_swap_buffers
+	gdk_gl_use_pango_font
+	gdk_gl_wait_gdk
+	gdk_gl_wait_gl
+	gtk_gl_area_get_type
+	gtk_gl_area_make_current
+	gtk_gl_area_new
+	gtk_gl_area_new_vargs
+	gtk_gl_area_share_new
+	gtk_gl_area_swap_buffers
--- configure.ac	2014-04-22 20:43:33 +0000
+++ configure.ac	2014-04-28 09:00:23 +0000
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT([gtkgl],
-        [2.1.0],
+        [2.1.1],
         [https://bugzilla.gnome.org/enter_bug.cgi?product=gtkglarea],
         [gtkglarea],
         [http://mono-project.com/GtkGLArea])
@@ -71,8 +71,19 @@
 dnl
 dnl  Check for GTK libraries
 dnl
+AC_ARG_WITH(gtk,  [  --with-gtk=2/3          Use GTK+2 (default) or GTK+3])
+GMODULE_REQUIRED_VERSION=2.0.0
+if test "x$with_gtk" = "x3" ; then
+GTK_REQUIRED_VERSION=3.0.0
+PKG_CHECK_MODULES(GTK, gtk+-3.0 >= $GTK_REQUIRED_VERSION gmodule-2.0 >= $GMODULE_REQUIRED_VERSION)
+CPPFLAGS="$CPPFLAGS -D__GTK3__"
+cp gtkgl/gtkgl3.def gtkgl/gtkgl.def
+else
 GTK_REQUIRED_VERSION=2.22
-PKG_CHECK_MODULES(GTK, gtk+-2.0 >= $GTK_REQUIRED_VERSION gmodule-2.0 >= $GTK_REQUIRED_VERSION)
+PKG_CHECK_MODULES(GTK, gtk+-2.0 >= $GTK_REQUIRED_VERSION gmodule-2.0 >= $GMODULE_REQUIRED_VERSION)
+CPPFLAGS="$CPPFLAGS -D__GTK2__"
+cp gtkgl/gtkgl2.def gtkgl/gtkgl.def
+fi
 
 dnl
 dnl  Check for GL/MesaGL libraries
