+ // when we call Update() we really want to update the window immediately on
+ // screen, even if it means flushing the entire queue and hence slowing down
+ // everything -- but it should still be done, it's just that Update() should
+ // be called very rarely
+ gdk_flush();
+}
+
+void wxWindowGTK::GtkUpdate()
+{
+ if (!m_updateRegion.IsEmpty())
+ GtkSendPaintEvents();
+
+ // for consistency with other platforms (and also because it's convenient
+ // to be able to update an entire TLW by calling Update() only once), we
+ // should also update all our children here
+ for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ node->GetData()->GtkUpdate();
+ }
+}
+
+void wxWindowGTK::GtkSendPaintEvents()
+{
+ if (!m_wxwindow)
+ {
+ m_clearRegion.Clear();
+ m_updateRegion.Clear();
+ return;
+ }
+
+ // Clip to paint region in wxClientDC
+ m_clipPaintRegion = true;
+
+ // widget to draw on
+ GtkPizza *pizza = GTK_PIZZA (m_wxwindow);
+
+ if (GetThemeEnabled() && (GetBackgroundStyle() == wxBG_STYLE_SYSTEM))
+ {
+ // find ancestor from which to steal background
+ wxWindow *parent = wxGetTopLevelParent((wxWindow *)this);
+ if (!parent)
+ parent = (wxWindow*)this;
+
+ if (GTK_WIDGET_MAPPED(parent->m_widget))
+ {
+ wxRegionIterator upd( m_updateRegion );
+ while (upd)
+ {
+ GdkRectangle rect;
+ rect.x = upd.GetX();
+ rect.y = upd.GetY();
+ rect.width = upd.GetWidth();
+ rect.height = upd.GetHeight();
+
+ gtk_paint_flat_box( parent->m_widget->style,
+ pizza->bin_window,
+ (GtkStateType)GTK_WIDGET_STATE(m_wxwindow),
+ GTK_SHADOW_NONE,
+ &rect,
+ parent->m_widget,
+ (char *)"base",
+ 0, 0, -1, -1 );
+
+ ++upd;
+ }
+ }
+ }
+ else // Always send an erase event under GTK 1.2
+ {
+ wxWindowDC dc( (wxWindow*)this );
+ dc.SetDeviceClippingRegion( m_clearRegion.IsEmpty() ? m_updateRegion
+ : m_clearRegion );
+
+ wxEraseEvent erase_event( GetId(), &dc );
+ erase_event.SetEventObject( this );
+
+ if (!HandleWindowEvent(erase_event) && GetBackgroundStyle() != wxBG_STYLE_CUSTOM)
+ {
+ if (!g_eraseGC)
+ {
+ g_eraseGC = gdk_gc_new( pizza->bin_window );
+ gdk_gc_set_fill( g_eraseGC, GDK_SOLID );
+ }
+ gdk_gc_set_foreground( g_eraseGC, GetBackgroundColour().GetColor() );
+
+ wxRegionIterator upd( m_clearRegion );
+ while (upd)
+ {
+ gdk_draw_rectangle( pizza->bin_window, g_eraseGC, 1,
+ upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
+ upd ++;
+ }
+ }
+ m_clearRegion.Clear();
+ }
+
+ wxNcPaintEvent nc_paint_event( GetId() );
+ nc_paint_event.SetEventObject( this );
+ HandleWindowEvent( nc_paint_event );
+
+ wxPaintEvent paint_event( GetId() );
+ paint_event.SetEventObject( this );
+ HandleWindowEvent( paint_event );
+
+ m_clipPaintRegion = false;
+
+#if !defined(__WXUNIVERSAL__)
+ // The following code will result in all window-less widgets
+ // being redrawn because the wxWidgets class is allowed to
+ // paint over the window-less widgets.
+
+ GList *children = pizza->children;
+ while (children)
+ {
+ GtkPizzaChild *child = (GtkPizzaChild*) children->data;
+ children = children->next;
+
+ if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+ GTK_WIDGET_DRAWABLE (child->widget))
+ {
+ // Get intersection of widget area and update region
+ wxRegion region( m_updateRegion );
+
+ GdkEventExpose gdk_event;
+ gdk_event.type = GDK_EXPOSE;
+ gdk_event.window = pizza->bin_window;
+ gdk_event.count = 0;
+ gdk_event.send_event = TRUE;
+
+ wxRegionIterator upd( m_updateRegion );
+ while (upd)
+ {
+ GdkRectangle rect;
+ rect.x = upd.GetX();
+ rect.y = upd.GetY();
+ rect.width = upd.GetWidth();
+ rect.height = upd.GetHeight();
+
+ if (gtk_widget_intersect (child->widget, &rect, &gdk_event.area))
+ {
+ gtk_widget_event (child->widget, (GdkEvent*) &gdk_event);
+ }
+
+ upd ++;
+ }
+ }
+ }
+#endif // native GTK 1
+
+ m_updateRegion.Clear();
+}
+
+void wxWindowGTK::ClearBackground()
+{
+ wxCHECK_RET( m_widget != NULL, wxT("invalid window") );