+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
+
+ if (m_wxwindow && m_wxwindow->window)
+ {
+ gdk_window_lower( m_wxwindow->window );
+ }
+ else if (m_widget->window)
+ {
+ gdk_window_lower( m_widget->window );
+ }
+}
+
+bool wxWindowGTK::SetCursor( const wxCursor &cursor )
+{
+ if ( !wxWindowBase::SetCursor(cursor.Ok() ? cursor : *wxSTANDARD_CURSOR) )
+ return false;
+
+ GTKUpdateCursor();
+
+ return true;
+}
+
+void wxWindowGTK::GTKUpdateCursor()
+{
+ wxCursor cursor(g_globalCursor.Ok() ? g_globalCursor : GetCursor());
+ if ( cursor.Ok() )
+ {
+ wxArrayGdkWindows windowsThis;
+ GdkWindow * const winThis = GTKGetWindow(windowsThis);
+ if ( winThis )
+ {
+ gdk_window_set_cursor(winThis, cursor.GetCursor());
+ }
+ else
+ {
+ const size_t count = windowsThis.size();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ GdkWindow *win = windowsThis[n];
+ if ( !win )
+ {
+ wxFAIL_MSG(_T("NULL window returned by GTKGetWindow()?"));
+ continue;
+ }
+
+ gdk_window_set_cursor(win, cursor.GetCursor());
+ }
+ }
+ }
+}
+
+void wxWindowGTK::WarpPointer( int x, int y )
+{
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
+
+ // We provide this function ourselves as it is
+ // missing in GDK (top of this file).
+
+ GdkWindow *window = (GdkWindow*) NULL;
+ if (m_wxwindow)
+ window = GTK_PIZZA(m_wxwindow)->bin_window;
+ else
+ window = GetConnectWidget()->window;
+
+ if (window)
+ gdk_window_warp_pointer( window, x, y );
+}
+
+wxWindowGTK::ScrollDir wxWindowGTK::ScrollDirFromRange(GtkRange *range) const
+{
+ // find the scrollbar which generated the event
+ for ( int dir = 0; dir < ScrollDir_Max; dir++ )
+ {
+ if ( range == m_scrollBar[dir] )
+ return (ScrollDir)dir;
+ }
+
+ wxFAIL_MSG( _T("event from unknown scrollbar received") );
+
+ return ScrollDir_Max;
+}
+
+bool wxWindowGTK::DoScrollByUnits(ScrollDir dir, ScrollUnit unit, int units)
+{
+ bool changed = false;
+ GtkRange* range = m_scrollBar[dir];
+ if ( range && units )
+ {
+ GtkAdjustment* adj = range->adjustment;
+ gdouble inc = unit == ScrollUnit_Line ? adj->step_increment
+ : adj->page_increment;
+
+ const int posOld = int(adj->value + 0.5);
+ gtk_range_set_value(range, posOld + units*inc);
+
+ changed = int(adj->value + 0.5) != posOld;
+ }
+
+ return changed;
+}
+
+bool wxWindowGTK::ScrollLines(int lines)
+{
+ return DoScrollByUnits(ScrollDir_Vert, ScrollUnit_Line, lines);
+}
+
+bool wxWindowGTK::ScrollPages(int pages)
+{
+ return DoScrollByUnits(ScrollDir_Vert, ScrollUnit_Page, pages);
+}
+
+void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect )
+{
+ if (!m_widget)
+ return;
+ if (!m_widget->window)
+ return;
+
+ if (m_wxwindow)
+ {
+ if (!GTK_PIZZA(m_wxwindow)->bin_window) return;
+
+ GdkRectangle gdk_rect,
+ *p;
+ if (rect)
+ {
+ gdk_rect.x = rect->x;
+ gdk_rect.y = rect->y;
+ gdk_rect.width = rect->width;
+ gdk_rect.height = rect->height;
+ if (GetLayoutDirection() == wxLayout_RightToLeft)
+ gdk_rect.x = GetClientSize().x - gdk_rect.x - gdk_rect.width;
+
+ p = &gdk_rect;
+ }
+ else // invalidate everything
+ {
+ p = NULL;
+ }
+
+ gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, p, TRUE );
+ }
+}
+
+void wxWindowGTK::Update()
+{
+ GtkUpdate();
+
+ // 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();
+}