New function which can be used to implement scrolling in non-window

2005-06-21  Matthias Clasen  <mclasen@redhat.com>

	* gdk/gdk.symbols:
	* gdk/gdkwindow.h:
	* gdk/x11/gdkgeometry-x11.c (gdk_window_move_region): New
	function which can be used to implement scrolling in
	non-window widgets.  (#135165, Søren Sandmann)
This commit is contained in:
Matthias Clasen 2005-06-21 04:09:52 +00:00 committed by Matthias Clasen
parent a4768daec1
commit 0f133f4f4b
8 changed files with 179 additions and 11 deletions

View File

@ -1,3 +1,11 @@
2005-06-21 Matthias Clasen <mclasen@redhat.com>
* gdk/gdk.symbols:
* gdk/gdkwindow.h:
* gdk/x11/gdkgeometry-x11.c (gdk_window_move_region): New
function which can be used to implement scrolling in
non-window widgets. (#135165, Søren Sandmann)
2005-06-20 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkiconcache.c: Handle MAP_FAILED. (#308449, Georg

View File

@ -1,3 +1,11 @@
2005-06-21 Matthias Clasen <mclasen@redhat.com>
* gdk/gdk.symbols:
* gdk/gdkwindow.h:
* gdk/x11/gdkgeometry-x11.c (gdk_window_move_region): New
function which can be used to implement scrolling in
non-window widgets. (#135165, Søren Sandmann)
2005-06-20 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkiconcache.c: Handle MAP_FAILED. (#308449, Georg

View File

@ -1,3 +1,11 @@
2005-06-21 Matthias Clasen <mclasen@redhat.com>
* gdk/gdk.symbols:
* gdk/gdkwindow.h:
* gdk/x11/gdkgeometry-x11.c (gdk_window_move_region): New
function which can be used to implement scrolling in
non-window widgets. (#135165, Søren Sandmann)
2005-06-20 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkiconcache.c: Handle MAP_FAILED. (#308449, Georg

View File

@ -1,3 +1,7 @@
2005-06-21 Matthias Clasen <mclasen@redhat.com>
* gdk/gdk-sections.txt: Add gdk_window_move_region
2005-06-20 Matthias Clasen <mclasen@redhat.com>
* === Released 2.7.0 ===

View File

@ -643,6 +643,7 @@ gdk_window_move
gdk_window_resize
gdk_window_move_resize
gdk_window_scroll
gdk_window_move_region
gdk_window_reparent
gdk_window_clear
gdk_window_clear_area

View File

@ -680,6 +680,7 @@ gdk_window_register_dnd
#if IN_HEADER(__GDK_WINDOW_H__)
#if IN_FILE(__GDK_GEOMETRY_X11_C__)
gdk_window_scroll
gdk_window_move_region
#endif
#endif

View File

@ -331,6 +331,10 @@ void gdk_window_remove_filter (GdkWindow *window,
void gdk_window_scroll (GdkWindow *window,
gint dx,
gint dy);
void gdk_window_move_region (GdkWindow *window,
GdkRegion *region,
gint dx,
gint dy);
/*
* This allows for making shaped (partially transparent) windows

View File

@ -155,6 +155,7 @@ struct _GdkWindowQueueItem
GdkWindowQueueType type;
union {
struct {
GdkRegion *area;
gint dx;
gint dy;
} translate;
@ -183,6 +184,7 @@ static void gdk_window_premove (GdkWindow *window,
static void gdk_window_postmove (GdkWindow *window,
GdkWindowParentPos *parent_pos);
static void gdk_window_queue_translation (GdkWindow *window,
GdkRegion *area,
gint dx,
gint dy);
static void gdk_window_clip_changed (GdkWindow *window,
@ -231,7 +233,7 @@ gdk_window_copy_area_scroll (GdkWindow *window,
gc = _gdk_drawable_get_scratch_gc (window, TRUE);
gdk_window_queue_translation (window, dx, dy);
gdk_window_queue_translation (window, NULL, dx, dy);
XCopyArea (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
@ -327,7 +329,7 @@ gdk_window_guffaw_scroll (GdkWindow *window,
_gdk_x11_window_tmp_unset_bg (window, FALSE);;
if (dx > 0 || dy > 0)
gdk_window_queue_translation (window, MAX (dx, 0), MAX (dy, 0));
gdk_window_queue_translation (window, NULL, MAX (dx, 0), MAX (dy, 0));
gdk_window_set_static_gravities (window, TRUE);
@ -353,7 +355,7 @@ gdk_window_guffaw_scroll (GdkWindow *window,
new_position.x - d_xoffset, new_position.y - d_yoffset);
if (dx < 0 || dy < 0)
gdk_window_queue_translation (window, MIN (dx, 0), MIN (dy, 0));
gdk_window_queue_translation (window, NULL, MIN (dx, 0), MIN (dy, 0));
XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
@ -461,6 +463,115 @@ gdk_window_scroll (GdkWindow *window,
gdk_window_guffaw_scroll (window, dx, dy);
}
/**
* gdk_window_move_region:
* @window: a #GdkWindow
* @region: The #GdkRegion to move
* @dx: Amount to move in the X direction
* @dy: Amount to move in the Y direction
*
* Move the part of @window indicated by @region by @dy pixels in the Y
* direction and @dx pixels in the X direction. The portions of @region
* that not covered by the new position of @region are invalidated.
*
* Child windows are not moved.
*
* Since: 2.8
**/
void
gdk_window_move_region (GdkWindow *window,
GdkRegion *region,
gint dx,
gint dy)
{
GdkWindowImplX11 *impl;
GdkWindowObject *private;
GdkRegion *window_clip;
GdkRegion *src_region;
GdkRegion *brought_in;
GdkRegion *dest_region;
GdkRegion *moving_invalid_region;
GdkRectangle dest_extents;
GdkGC *gc;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (region != NULL);
if (GDK_WINDOW_DESTROYED (window))
return;
private = GDK_WINDOW_OBJECT (window);
impl = GDK_WINDOW_IMPL_X11 (private->impl);
if (dx == 0 && dy == 0)
return;
window_clip = gdk_region_rectangle (&impl->position_info.clip_rect);
/* compute source regions */
src_region = gdk_region_copy (region);
brought_in = gdk_region_copy (region);
gdk_region_intersect (src_region, window_clip);
gdk_region_subtract (brought_in, src_region);
gdk_region_offset (brought_in, dx, dy);
/* compute destination regions */
dest_region = gdk_region_copy (src_region);
gdk_region_offset (dest_region, dx, dy);
gdk_region_intersect (dest_region, window_clip);
gdk_region_get_clipbox (dest_region, &dest_extents);
gdk_region_destroy (window_clip);
/* calculating moving part of current invalid area */
moving_invalid_region = NULL;
if (private->update_area)
{
moving_invalid_region = gdk_region_copy (private->update_area);
gdk_region_intersect (moving_invalid_region, src_region);
gdk_region_offset (moving_invalid_region, dx, dy);
}
/* invalidate all of the src region */
gdk_window_invalidate_region (window, src_region, FALSE);
/* un-invalidate destination region */
if (private->update_area)
gdk_region_subtract (private->update_area, dest_region);
/* invalidate moving parts of existing update area */
if (moving_invalid_region)
{
gdk_window_invalidate_region (window, moving_invalid_region, FALSE);
gdk_region_destroy (moving_invalid_region);
}
/* invalidate area brought in from off-screen */
gdk_window_invalidate_region (window, brought_in, FALSE);
gdk_region_destroy (brought_in);
/* Actually do the moving */
gdk_window_queue_translation (window, src_region, dx, dy);
gc = _gdk_drawable_get_scratch_gc (window, TRUE);
gdk_gc_set_clip_region (gc, dest_region);
XCopyArea (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
GDK_WINDOW_XID (window),
GDK_GC_XGC (gc),
dest_extents.x - dx, dest_extents.y - dy,
dest_extents.width, dest_extents.height,
dest_extents.x, dest_extents.y);
/* Unset clip region of cached GC */
gdk_gc_set_clip_region (gc, NULL);
gdk_region_destroy (src_region);
gdk_region_destroy (dest_region);
}
void
_gdk_window_move_resize_child (GdkWindow *window,
gint x,
@ -520,7 +631,7 @@ _gdk_window_move_resize_child (GdkWindow *window,
gdk_window_set_static_gravities (window, TRUE);
if (d_xoffset < 0 || d_yoffset < 0)
gdk_window_queue_translation (window, MIN (d_xoffset, 0), MIN (d_yoffset, 0));
gdk_window_queue_translation (window, NULL, MIN (d_xoffset, 0), MIN (d_yoffset, 0));
compute_intermediate_position (&impl->position_info, &new_info, d_xoffset, d_yoffset,
&new_position);
@ -541,7 +652,7 @@ _gdk_window_move_resize_child (GdkWindow *window,
new_position.x + dx, new_position.y + dy);
if (d_xoffset > 0 || d_yoffset > 0)
gdk_window_queue_translation (window, MAX (d_xoffset, 0), MAX (d_yoffset, 0));
gdk_window_queue_translation (window, NULL, MAX (d_xoffset, 0), MAX (d_yoffset, 0));
XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
@ -797,7 +908,7 @@ gdk_window_premove (GdkWindow *window,
GdkRectangle new_position;
if (d_xoffset < 0 || d_yoffset < 0)
gdk_window_queue_translation (window, MIN (d_xoffset, 0), MIN (d_yoffset, 0));
gdk_window_queue_translation (window, NULL, MIN (d_xoffset, 0), MIN (d_yoffset, 0));
compute_intermediate_position (&impl->position_info, &new_info, d_xoffset, d_yoffset,
&new_position);
@ -843,7 +954,7 @@ gdk_window_postmove (GdkWindow *window,
if (d_xoffset != 0 || d_yoffset != 0)
{
if (d_xoffset > 0 || d_yoffset > 0)
gdk_window_queue_translation (window, MAX (d_xoffset, 0), MAX (d_yoffset, 0));
gdk_window_queue_translation (window, NULL, MAX (d_xoffset, 0), MAX (d_yoffset, 0));
XMoveResizeWindow (GDK_DRAWABLE_XDISPLAY (window),
GDK_DRAWABLE_XID (window),
@ -917,6 +1028,11 @@ queue_item_free (GdkWindowQueueItem *item)
if (item->type == GDK_WINDOW_QUEUE_ANTIEXPOSE)
gdk_region_destroy (item->u.antiexpose.area);
else
{
if (item->u.translate.area)
gdk_region_destroy (item->u.translate.area);
}
g_free (item);
}
@ -990,11 +1106,13 @@ gdk_window_queue (GdkWindow *window,
static void
gdk_window_queue_translation (GdkWindow *window,
GdkRegion *area,
gint dx,
gint dy)
{
GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1);
item->type = GDK_WINDOW_QUEUE_TRANSLATE;
item->u.translate.area = area ? gdk_region_copy (area) : NULL;
item->u.translate.dx = dx;
item->u.translate.dy = dy;
@ -1039,9 +1157,25 @@ _gdk_window_process_expose (GdkWindow *window,
if (item->window == window)
{
if (item->type == GDK_WINDOW_QUEUE_TRANSLATE)
gdk_region_offset (invalidate_region, item->u.translate.dx, item->u.translate.dy);
{
if (item->u.translate.area)
{
GdkRegion *intersection;
intersection = gdk_region_copy (invalidate_region);
gdk_region_intersect (intersection, item->u.translate.area);
gdk_region_subtract (invalidate_region, intersection);
gdk_region_offset (intersection, item->u.translate.dx, item->u.translate.dy);
gdk_region_union (invalidate_region, intersection);
gdk_region_destroy (intersection);
}
else
gdk_region_offset (invalidate_region, item->u.translate.dx, item->u.translate.dy);
}
else /* anti-expose */
gdk_region_subtract (invalidate_region, item->u.antiexpose.area);
{
gdk_region_subtract (invalidate_region, item->u.antiexpose.area);
}
}
}
else