+#include "wx/listimpl.cpp"
+WX_DEFINE_LIST(wxGtkNotebookPagesList);
+
+//-----------------------------------------------------------------------------
+// "switch_page"
+//-----------------------------------------------------------------------------
+
+static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget),
+                                              GtkNotebookPage *WXUNUSED(page),
+                                              gint page,
+                                              wxNotebook *notebook )
+{
+    // are you trying to call SetSelection() from a notebook event handler?
+    // you shouldn't!
+    wxCHECK_RET( !notebook->m_inSwitchPage,
+                 _T("gtk_notebook_page_change_callback reentered") );
+
+    notebook->m_inSwitchPage = TRUE;
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+    int old = notebook->GetSelection();
+
+    wxNotebookEvent eventChanging( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,
+                                   notebook->GetId(), page, old );
+    eventChanging.SetEventObject( notebook );
+
+    if ( (notebook->GetEventHandler()->ProcessEvent(eventChanging)) &&
+         !eventChanging.IsAllowed() )
+    {
+        /* program doesn't allow the page change */
+        gtk_signal_emit_stop_by_name( GTK_OBJECT(notebook->m_widget),
+                                      "switch_page" );
+    }
+    else // change allowed
+    {
+        // make wxNotebook::GetSelection() return the correct (i.e. consistent
+        // with wxNotebookEvent::GetSelection()) value even though the page is
+        // not really changed in GTK+
+        notebook->m_selection = page;
+
+        wxNotebookEvent eventChanged( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+                                      notebook->GetId(), page, old );
+        eventChanged.SetEventObject( notebook );
+        notebook->GetEventHandler()->ProcessEvent( eventChanged );
+    }
+
+    notebook->m_inSwitchPage = FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// "size_allocate"
+//-----------------------------------------------------------------------------
+
+static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
+{
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+    if ((win->m_x == alloc->x) &&
+        (win->m_y == alloc->y) &&
+        (win->m_width == alloc->width) &&
+        (win->m_height == alloc->height))
+    {
+        return;
+    }
+
+    win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height );
+
+    /* GTK 1.2 up to version 1.2.5 is broken so that we have to call allocate
+       here in order to make repositioning after resizing to take effect. */
+    if ((gtk_major_version == 1) &&
+        (gtk_minor_version == 2) &&
+        (gtk_micro_version < 6) &&
+        (win->m_wxwindow) &&
+        (GTK_WIDGET_REALIZED(win->m_wxwindow)))
+    {
+        gtk_widget_size_allocate( win->m_wxwindow, alloc );
+    }
+}
+
+//-----------------------------------------------------------------------------
+// "realize" from m_widget
+//-----------------------------------------------------------------------------
+
+static gint
+gtk_notebook_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win )
+{
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+    /* GTK 1.2 up to version 1.2.5 is broken so that we have to call a queue_resize
+       here in order to make repositioning before showing to take effect. */
+    gtk_widget_queue_resize( win->m_widget );
+
+    return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// "key_press_event"
+//-----------------------------------------------------------------------------
+
+static gint gtk_notebook_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxNotebook *win )
+{
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+    if (!win->m_hasVMT) return FALSE;
+    if (g_blockEventsOnDrag) return FALSE;
+
+    /* win is a control: tab can be propagated up */
+    if ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab))
+    {
+        int sel = win->GetSelection();
+        if (sel == -1)
+            return TRUE;
+        wxGtkNotebookPage *nb_page = win->GetNotebookPage(sel);
+        wxCHECK_MSG( nb_page, FALSE, _T("invalid selection in wxNotebook") );
+
+        wxNavigationKeyEvent event;
+        event.SetEventObject( win );
+        /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
+        event.SetDirection( (gdk_event->keyval == GDK_Tab) );
+        /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
+        event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
+        event.SetCurrentFocus( win );
+
+        wxNotebookPage *client = win->GetPage(sel);
+        if ( !client->GetEventHandler()->ProcessEvent( event ) )
+        {
+             client->SetFocus();
+        }
+
+        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+//-----------------------------------------------------------------------------
+// InsertChild callback for wxNotebook
+//-----------------------------------------------------------------------------
+
+static void wxInsertChildInNotebook( wxNotebook* WXUNUSED(parent), wxWindow* WXUNUSED(child) )
+{
+    /* we don't do anything here but pray */
+}
+