Re-enable the "find" dialog
2000-10-23 Havoc Pennington <hp@redhat.com> * gtk/testtext.c: Re-enable the "find" dialog * gtk/testgtk.c: Add test for gdk_drawable_get_image * gdk/gdkwindow.c (gdk_window_begin_paint_region): Fix bug where the arguments to gdk_draw_drawable were in the wrong order (gdk_window_paint_init_bg): This function was ignoring the init_region, instead of clipping to it, so the entire backing pixmap was cleared on every begin_paint() (gdk_window_begin_paint_region): Hmm, the same list-walking bug was in here again, the loop kept using the same GtkWindowPaint over and over. (gdk_window_begin_paint_region): Fix a bug where we had two x_offset instead of x_offset and y_offset * gdk/gdkdraw.c (gdk_drawable_get_image): get composite drawable before we get the image. (gdk_draw_drawable): get the composite before we draw the drawable. (gdk_drawable_real_get_composite_drawable): default get_composite_drawable implementation that returns the drawable itself * gdk/gdkdrawable.h (struct _GdkDrawableClass ): Add get_composite_drawable virtual function * gdk/gdkwindow.c (gdk_window_begin_paint_region): Fix a cheesy list-walking bug * gdk/x11/gdkdrawable-x11.c (gdk_x11_draw_drawable): Add a hack to make this work if the source drawable is a GdkDrawableImplX11 instead of a public drawable type. This is really broken; the problem is that GdkDrawable needs a virtual method get_xid(), but of course that doesn't work in practice. Enter RTTI. Also, improve mismatched depth message. * gdk/gdkpixmap.c (gdk_pixmap_get_image): Implement get_image for GdkPixmap * gdk/x11/gdkdrawable-x11.c (gdk_drawable_impl_x11_class_init): install _gdk_x11_get_image as our implementation of get_image * gdk/x11/gdkimage-x11.c (gdk_image_get): Rename to _gdk_x11_get_image and export for use in gdkdrawable-x11.c * gdk/gdkimage.c (gdk_image_get): Make this just a wrapper around gdk_drawable_get_image * gdk/gdkdraw.c (gdk_drawable_get_image): call virtual get_image * gdk/gdkdrawable.h (struct _GdkDrawableClass ): Virtualize get_image * gtk/gtktreestore.c (gtk_tree_store_get_node): remove weird trailing semicolon after for loop
This commit is contained in:
committed by
Havoc Pennington
parent
ce821b23f5
commit
86b5c82a97
221
gdk/gdkwindow.c
221
gdk/gdkwindow.c
@ -28,6 +28,8 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdk.h" /* For gdk_rectangle_union() */
|
||||
#include "gdkpixmap.h"
|
||||
#include "gdkdrawable.h"
|
||||
#include "gdkpixmap.h"
|
||||
|
||||
#ifndef USE_BACKING_STORE
|
||||
#ifndef GDK_WINDOWING_WIN32
|
||||
@ -120,6 +122,12 @@ static void gdk_window_draw_image (GdkDrawable *drawable,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
static GdkImage* gdk_window_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
|
||||
static void gdk_window_real_get_size (GdkDrawable *drawable,
|
||||
gint *width,
|
||||
@ -130,7 +138,15 @@ static gint gdk_window_real_get_depth (GdkDrawable *drawable);
|
||||
static void gdk_window_real_set_colormap (GdkDrawable *drawable,
|
||||
GdkColormap *cmap);
|
||||
static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable);
|
||||
|
||||
|
||||
static GdkDrawable* gdk_window_get_composite_drawable (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
gint *composite_x_offset,
|
||||
gint *composite_y_offset);
|
||||
|
||||
static void gdk_window_free_paint_stack (GdkWindow *window);
|
||||
|
||||
static void gdk_window_init (GdkWindowObject *window);
|
||||
@ -204,6 +220,8 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
|
||||
drawable_class->set_colormap = gdk_window_real_set_colormap;
|
||||
drawable_class->get_colormap = gdk_window_real_get_colormap;
|
||||
drawable_class->get_visual = gdk_window_real_get_visual;
|
||||
drawable_class->get_image = gdk_window_get_image;
|
||||
drawable_class->get_composite_drawable = gdk_window_get_composite_drawable;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -650,12 +668,20 @@ gdk_window_paint_init_bg (GdkWindow *window,
|
||||
GdkRegion *init_region)
|
||||
{
|
||||
GdkGC *tmp_gc;
|
||||
|
||||
|
||||
tmp_gc = gdk_window_get_bg_gc (window, paint);
|
||||
|
||||
gdk_region_offset (init_region,
|
||||
- paint->x_offset,
|
||||
- paint->y_offset);
|
||||
gdk_gc_set_clip_region (tmp_gc, init_region);
|
||||
|
||||
gdk_draw_rectangle (paint->pixmap, tmp_gc, TRUE, 0, 0, -1, -1);
|
||||
gdk_gc_unref (tmp_gc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "x11/gdkx.h"
|
||||
void
|
||||
gdk_window_begin_paint_region (GdkWindow *window,
|
||||
GdkRegion *region)
|
||||
@ -697,11 +723,13 @@ gdk_window_begin_paint_region (GdkWindow *window,
|
||||
|
||||
if (new_rect.width > old_rect.width || new_rect.height > old_rect.height)
|
||||
{
|
||||
paint->pixmap = gdk_pixmap_new (window, new_rect.width, new_rect.height, -1);
|
||||
paint->pixmap = gdk_pixmap_new (window,
|
||||
new_rect.width, new_rect.height, -1);
|
||||
tmp_gc = gdk_gc_new (paint->pixmap);
|
||||
gdk_draw_drawable (paint->pixmap, tmp_gc, tmp_paint->pixmap,
|
||||
0, 0, old_rect.width, old_rect.height,
|
||||
old_rect.x - new_rect.x, old_rect.y - new_rect.y);
|
||||
0, 0,
|
||||
old_rect.x - new_rect.x, old_rect.y - new_rect.y,
|
||||
old_rect.width, old_rect.height);
|
||||
gdk_gc_unref (tmp_gc);
|
||||
gdk_drawable_unref (tmp_paint->pixmap);
|
||||
|
||||
@ -711,13 +739,13 @@ gdk_window_begin_paint_region (GdkWindow *window,
|
||||
tmp_list = private->paint_stack;
|
||||
while (tmp_list)
|
||||
{
|
||||
tmp_paint = private->paint_stack->data;
|
||||
tmp_paint = tmp_list->data;
|
||||
gdk_region_subtract (init_region, tmp_paint->region);
|
||||
|
||||
tmp_paint->pixmap = paint->pixmap;
|
||||
tmp_paint->x_offset = paint->x_offset;
|
||||
tmp_paint->y_offset = paint->x_offset;
|
||||
|
||||
tmp_paint->y_offset = paint->y_offset;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
@ -730,7 +758,7 @@ gdk_window_begin_paint_region (GdkWindow *window,
|
||||
tmp_list = private->paint_stack;
|
||||
while (tmp_list)
|
||||
{
|
||||
tmp_paint = private->paint_stack->data;
|
||||
tmp_paint = tmp_list->data;
|
||||
gdk_region_subtract (init_region, tmp_paint->region);
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
@ -746,6 +774,7 @@ gdk_window_begin_paint_region (GdkWindow *window,
|
||||
|
||||
if (!gdk_region_empty (init_region))
|
||||
gdk_window_paint_init_bg (window, paint, init_region);
|
||||
|
||||
gdk_region_destroy (init_region);
|
||||
|
||||
private->paint_stack = g_slist_prepend (private->paint_stack, paint);
|
||||
@ -796,7 +825,7 @@ gdk_window_end_paint (GdkWindow *window)
|
||||
{
|
||||
GdkWindowPaint *tmp_paint = tmp_list->data;
|
||||
gdk_region_subtract (tmp_paint->region, paint->region);
|
||||
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
@ -1048,6 +1077,138 @@ gdk_window_draw_text_wc (GdkDrawable *drawable,
|
||||
RESTORE_GC (gc);
|
||||
}
|
||||
|
||||
static GdkDrawable*
|
||||
gdk_window_get_composite_drawable (GdkDrawable *window,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height,
|
||||
gint *composite_x_offset,
|
||||
gint *composite_y_offset)
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *)window;
|
||||
GdkWindowPaint *paint;
|
||||
GdkRegion *buffered_region;
|
||||
GSList *tmp_list;
|
||||
GdkPixmap *buffer;
|
||||
GdkPixmap *tmp_pixmap;
|
||||
GdkRectangle rect;
|
||||
GdkRegion *rect_region;
|
||||
GdkGC *tmp_gc;
|
||||
gint windowing_x_offset, windowing_y_offset;
|
||||
gint buffer_x_offset, buffer_y_offset;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (window) || private->paint_stack == NULL)
|
||||
{
|
||||
/* No backing store */
|
||||
_gdk_windowing_window_get_offsets (window,
|
||||
composite_x_offset,
|
||||
composite_y_offset);
|
||||
|
||||
return GDK_DRAWABLE (g_object_ref (G_OBJECT (window)));
|
||||
}
|
||||
|
||||
buffered_region = NULL;
|
||||
buffer = NULL;
|
||||
|
||||
/* All GtkWindowPaint structs have the same pixmap and offsets, just
|
||||
* get the first one. (should probably be cleaned up so that the
|
||||
* pixmap is stored in the window)
|
||||
*/
|
||||
paint = private->paint_stack->data;
|
||||
buffer = paint->pixmap;
|
||||
buffer_x_offset = paint->x_offset;
|
||||
buffer_y_offset = paint->y_offset;
|
||||
|
||||
tmp_list = private->paint_stack;
|
||||
while (tmp_list != NULL)
|
||||
{
|
||||
paint = tmp_list->data;
|
||||
|
||||
if (buffered_region == NULL)
|
||||
buffered_region = gdk_region_copy (paint->region);
|
||||
else
|
||||
gdk_region_union (buffered_region, paint->region);
|
||||
|
||||
tmp_list = g_slist_next (tmp_list);
|
||||
}
|
||||
|
||||
/* See if the buffered part is overlapping the part we want
|
||||
* to get
|
||||
*/
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
rect_region = gdk_region_rectangle (&rect);
|
||||
|
||||
gdk_region_intersect (buffered_region, rect_region);
|
||||
|
||||
gdk_region_destroy (rect_region);
|
||||
|
||||
if (gdk_region_empty (buffered_region))
|
||||
{
|
||||
gdk_region_destroy (buffered_region);
|
||||
|
||||
_gdk_windowing_window_get_offsets (window,
|
||||
composite_x_offset,
|
||||
composite_y_offset);
|
||||
|
||||
return GDK_DRAWABLE (g_object_ref (G_OBJECT (window)));
|
||||
}
|
||||
|
||||
tmp_pixmap = gdk_pixmap_new (window,
|
||||
width, height,
|
||||
-1);
|
||||
|
||||
tmp_gc = gdk_gc_new (tmp_pixmap);
|
||||
|
||||
_gdk_windowing_window_get_offsets (window,
|
||||
&windowing_x_offset,
|
||||
&windowing_y_offset);
|
||||
|
||||
/* Copy the current window contents */
|
||||
gdk_draw_drawable (tmp_pixmap,
|
||||
tmp_gc,
|
||||
private->impl,
|
||||
x - windowing_x_offset,
|
||||
y - windowing_y_offset,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
/* Make buffered_region relative to the tmp_pixmap */
|
||||
gdk_region_offset (buffered_region,
|
||||
- x,
|
||||
- y);
|
||||
|
||||
/* Set the clip mask to avoid drawing over non-buffered areas of
|
||||
* tmp_pixmap.
|
||||
*/
|
||||
|
||||
gdk_gc_set_clip_region (tmp_gc, buffered_region);
|
||||
gdk_region_destroy (buffered_region);
|
||||
|
||||
/* Draw backing pixmap onto the tmp_pixmap, offsetting
|
||||
* appropriately.
|
||||
*/
|
||||
gdk_draw_drawable (tmp_pixmap,
|
||||
tmp_gc,
|
||||
buffer,
|
||||
x - buffer_x_offset,
|
||||
y - buffer_y_offset,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
/* Set these to location of tmp_pixmap within the window */
|
||||
*composite_x_offset = x;
|
||||
*composite_y_offset = y;
|
||||
|
||||
g_object_unref (G_OBJECT (tmp_gc));
|
||||
|
||||
return tmp_pixmap;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_draw_drawable (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
@ -1061,21 +1222,25 @@ gdk_window_draw_drawable (GdkDrawable *drawable,
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *)drawable;
|
||||
OFFSET_GC (gc);
|
||||
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (drawable))
|
||||
return;
|
||||
|
||||
|
||||
/* If we have a backing pixmap draw to that */
|
||||
if (private->paint_stack)
|
||||
{
|
||||
GdkWindowPaint *paint = private->paint_stack->data;
|
||||
gdk_draw_drawable (paint->pixmap, gc, src, xsrc, ysrc,
|
||||
gdk_draw_drawable (paint->pixmap, gc,
|
||||
src, xsrc, ysrc,
|
||||
xdest - x_offset, ydest - y_offset, width, height);
|
||||
|
||||
}
|
||||
else
|
||||
gdk_draw_drawable (private->impl, gc, src, xsrc, ysrc,
|
||||
gdk_draw_drawable (private->impl, gc,
|
||||
src, xsrc, ysrc,
|
||||
xdest - x_offset, ydest - y_offset,
|
||||
width, height);
|
||||
|
||||
RESTORE_GC (gc);
|
||||
}
|
||||
|
||||
@ -1403,6 +1568,32 @@ gdk_window_real_get_colormap (GdkDrawable *drawable)
|
||||
|
||||
return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
|
||||
}
|
||||
|
||||
static GdkImage*
|
||||
gdk_window_get_image (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
gint x_offset, y_offset;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (drawable))
|
||||
return NULL;
|
||||
|
||||
/* If we're here, a composite image was not necessary, so
|
||||
* we can ignore the paint stack.
|
||||
*/
|
||||
|
||||
_gdk_windowing_window_get_offsets (drawable, &x_offset, &y_offset);
|
||||
|
||||
return gdk_drawable_get_image (((GdkWindowObject*)drawable)->impl,
|
||||
x - x_offset,
|
||||
y - y_offset,
|
||||
width, height);
|
||||
}
|
||||
|
||||
/* Code for dirty-region queueing
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user