internal override void ScrollWindow(IntPtr handle, Rectangle area, int XAmount, int YAmount, bool with_children) {
Hwnd hwnd;
IntPtr gc;
XGCValues gc_values;
hwnd = Hwnd.ObjectFromHandle(handle);
Rectangle r = Rectangle.Intersect (hwnd.Invalid, area);
if (!r.IsEmpty) {
/* We have an invalid area in the window we're scrolling.
Adjust our stored invalid rectangle to to match the scrolled amount */
r.X += XAmount;
r.Y += YAmount;
if (r.X < 0) {
r.Width += r.X;
r.X =0;
}
if (r.Y < 0) {
r.Height += r.Y;
r.Y =0;
}
if (area.Contains (hwnd.Invalid))
hwnd.ClearInvalidArea ();
hwnd.AddInvalidArea(r);
}
gc_values = new XGCValues();
if (with_children) {
gc_values.subwindow_mode = GCSubwindowMode.IncludeInferiors;
}
gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
Rectangle visible_rect = GetTotalVisibleArea (hwnd.client_window);
visible_rect.Intersect (area);
Rectangle dest_rect = visible_rect;
dest_rect.Y += YAmount;
dest_rect.X += XAmount;
dest_rect.Intersect (area);
Point src = new Point (dest_rect.X - XAmount, dest_rect.Y - YAmount);
XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src.X, src.Y,
dest_rect.Width, dest_rect.Height, dest_rect.X, dest_rect.Y);
Rectangle dirty_area = GetDirtyArea (area, dest_rect, XAmount, YAmount);
AddExpose (hwnd, true, dirty_area.X, dirty_area.Y, dirty_area.Width, dirty_area.Height);
ProcessGraphicsExpose (hwnd);
XFreeGC(DisplayHandle, gc);
}