Commit 01110305 authored by Alexander Larsson's avatar Alexander Larsson

Merge branch 'client-side-windows'

parents 3c97f037 038398d4
......@@ -94,6 +94,7 @@ for the possible window states
was added in 2.8.
@GDK_DAMAGE: the content of the window has been changed. This event type
was added in 2.14.
@GDK_EVENT_LAST:
<!-- ##### ENUM GdkEventMask ##### -->
<para>
......
......@@ -200,6 +200,7 @@ Describes the kind of window.
@GDK_WINDOW_DIALOG: useless/deprecated compatibility type
@GDK_WINDOW_TEMP: override redirect temporary window (used to implement #GtkMenu)
@GDK_WINDOW_FOREIGN: foreign window (see gdk_window_foreign_new())
@GDK_WINDOW_OFFSCREEN:
<!-- ##### ENUM GdkWindowClass ##### -->
<para>
......
......@@ -120,6 +120,7 @@ gdk_c_sources = \
gdkintl.h \
gdkkeys.c \
gdkkeyuni.c \
gdkoffscreenwindow.c \
gdkpango.c \
gdkpixbuf-drawable.c \
gdkpixbuf-render.c \
......@@ -151,10 +152,10 @@ gdk_built_sources = \
gdkincludedir = $(includedir)/gtk-2.0/gdk
gdkinclude_HEADERS = $(gdk_public_h_sources) $(gdk_built_public_sources)
# gdkmarshalers.c is not here because it is currently an empty file
common_sources = \
$(gdk_c_sources) \
gdkenumtypes.c \
gdkmarshalers.c \
gdkmarshalers.h
libgdk_directfb_2_0_la_SOURCES = $(common_sources)
......
......@@ -69,9 +69,6 @@ gdk_get_use_xshm
gdk_set_use_xshm
#endif
gdk_keyboard_grab
gdk_keyboard_grab_info_libgtk_only
gdk_pointer_grab
gdk_pointer_grab_info_libgtk_only
#endif
#endif
......@@ -85,6 +82,9 @@ gdk_pointer_is_grabbed
gdk_pointer_ungrab
gdk_event_send_client_message
gdk_event_send_clientmessage_toall
gdk_keyboard_grab_info_libgtk_only
gdk_pointer_grab_info_libgtk_only
gdk_display_pointer_is_grabbed
#endif
#endif
......@@ -254,12 +254,6 @@ gdk_visual_type_get_type G_GNUC_CONST
#endif
#endif
#if IN_HEADER(__GDK_PIXMAP_H__)
#if IN_FILE(__GDK_PIXMAP_X11_C__)
gdk_bitmap_create_from_data
#endif
#endif
#if IN_HEADER(__GDK_FONT_H__)
#if IN_FILE(__GDK_FONT_C__)
#ifndef GDK_DISABLE_DEPRECATED
......@@ -466,7 +460,6 @@ gdk_display_get_default_screen
gdk_display_get_name
gdk_display_get_n_screens
gdk_display_get_screen
gdk_display_pointer_is_grabbed
gdk_display_pointer_ungrab
gdk_display_keyboard_ungrab
gdk_display_open
......@@ -667,10 +660,16 @@ gdk_window_set_back_pixmap
gdk_window_set_cursor
gdk_window_get_geometry
gdk_window_get_origin
gdk_window_get_root_coords
gdk_window_get_deskrelative_origin
gdk_window_shape_combine_mask
gdk_window_shape_combine_region
gdk_window_set_child_shapes
gdk_window_merge_child_shapes
gdk_window_input_shape_combine_mask
gdk_window_input_shape_combine_region
gdk_window_set_child_input_shapes
gdk_window_merge_child_input_shapes
gdk_window_set_static_gravities
gdk_window_reparent
gdk_window_add_filter
......@@ -716,6 +715,18 @@ gdk_window_set_user_data
gdk_window_thaw_toplevel_updates_libgtk_only
gdk_window_thaw_updates
gdk_window_set_composited
gdk_pointer_grab
gdk_window_beep
gdk_window_geometry_changed
gdk_window_ensure_native
#endif
#endif
#if IN_HEADER(__GDK_WINDOW_H__)
#if IN_FILE(__GDK_OFFSCREEN_WINDOW_C__)
gdk_offscreen_window_get_pixmap
gdk_offscreen_window_set_embedder
gdk_offscreen_window_get_embedder
#endif
#endif
......@@ -733,7 +744,6 @@ gdk_window_lookup
gdk_window_lookup_for_display
#ifndef GDK_DISABLE_DEPRECATED
gdk_window_set_hints
gdk_window_get_deskrelative_origin
#endif
gdk_window_get_type_hint
gdk_window_set_type_hint
......@@ -748,15 +758,12 @@ gdk_window_set_startup_id
gdk_window_set_transient_for
gdk_window_get_root_origin
gdk_window_get_frame_extents
gdk_window_input_shape_combine_mask
gdk_window_input_shape_combine_region
gdk_window_set_override_redirect
gdk_window_set_accept_focus
gdk_window_set_focus_on_map
gdk_window_set_icon_list
gdk_window_set_icon
gdk_window_set_icon_name
gdk_window_beep
gdk_window_set_opacity
gdk_window_iconify
gdk_window_deiconify
......@@ -773,8 +780,6 @@ gdk_window_set_group
gdk_window_get_decorations
gdk_window_set_decorations
gdk_window_set_functions
gdk_window_set_child_input_shapes
gdk_window_merge_child_input_shapes
gdk_window_begin_move_drag
gdk_window_begin_resize_drag
gdk_window_enable_synchronized_configure
......@@ -925,23 +930,24 @@ gdk_pixbuf_render_to_drawable_alpha
#if IN_HEADER(__GDK_PIXMAP_H__)
#if IN_FILE(__GDK_PIXMAP_C__)
gdk_bitmap_create_from_data
gdk_pixmap_colormap_create_from_xpm
gdk_pixmap_create_from_data
gdk_pixmap_create_from_xpm
gdk_pixmap_colormap_create_from_xpm_d
gdk_pixmap_create_from_xpm_d
gdk_pixmap_get_type G_GNUC_CONST
gdk_pixmap_new
#endif
#endif
#if IN_HEADER(__GDK_PIXMAP_H__)
#if IN_FILE(__GDK_PIXMAP_X11_C__)
gdk_pixmap_create_from_data
gdk_pixmap_foreign_new
gdk_pixmap_foreign_new_for_display
gdk_pixmap_foreign_new_for_screen
gdk_pixmap_lookup
gdk_pixmap_lookup_for_display
gdk_pixmap_new
#endif
#endif
......
......@@ -50,6 +50,10 @@ gdk_cairo_create (GdkDrawable *drawable)
surface = _gdk_drawable_ref_cairo_surface (drawable);
cr = cairo_create (surface);
if (GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip)
GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip (drawable, cr);
cairo_surface_destroy (surface);
return cr;
......
This diff is collapsed.
......@@ -43,6 +43,33 @@ typedef struct _GdkDisplayPointerHooks GdkDisplayPointerHooks;
#define GDK_IS_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DISPLAY))
#define GDK_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DISPLAY, GdkDisplayClass))
/* Tracks information about the keyboard grab on this display */
typedef struct
{
GdkWindow *window;
GdkWindow *native_window;
gulong serial;
gboolean owner_events;
guint32 time;
} GdkKeyboardGrabInfo;
/* Tracks information about which window and position the pointer last was in.
* This is useful when we need to synthesize events later.
* Note that we track toplevel_under_pointer using enter/leave events,
* so in the case of a grab, either with owner_events==FALSE or with the
* pointer in no clients window the x/y coordinates may actually be outside
* the window.
*/
typedef struct
{
GdkWindow *toplevel_under_pointer; /* The toplevel window with mouse inside, tracked via native events */
GdkWindow *window_under_pointer; /* The window that last got sent a normal enter event */
gdouble toplevel_x, toplevel_y;
guint32 state;
guint32 button;
gulong motion_hint_serial; /* 0 == didn't deliver hinted motion event */
} GdkPointerWindowInfo;
struct _GdkDisplay
{
GObject parent_instance;
......@@ -64,10 +91,18 @@ struct _GdkDisplay
const GdkDisplayPointerHooks *pointer_hooks; /* Current hooks for querying pointer */
guint closed : 1; /* Whether this display has been closed */
guint ignore_core_events : 1; /* Don't send core motion and button event */
guint double_click_distance; /* Maximum distance between clicks in pixels */
gint button_x[2]; /* The last 2 button click positions. */
gint button_y[2];
GList *pointer_grabs;
GdkKeyboardGrabInfo keyboard_grab;
GdkPointerWindowInfo pointer_info;
/* Last reported event time from server */
guint32 last_event_time;
};
struct _GdkDisplayClass
......
......@@ -150,7 +150,8 @@ gdk_drawable_get_size (GdkDrawable *drawable,
{
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height);
if (GDK_DRAWABLE_GET_CLASS (drawable)->get_size != NULL)
GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height);
}
/**
......@@ -623,7 +624,7 @@ gdk_draw_drawable (GdkDrawable *drawable,
gint width,
gint height)
{
GdkDrawable *composite;
GdkDrawable *composite, *composite_impl;
gint composite_x_offset = 0;
gint composite_y_offset = 0;
......@@ -652,13 +653,29 @@ gdk_draw_drawable (GdkDrawable *drawable,
&composite_x_offset,
&composite_y_offset);
GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc, composite,
/* The draw_drawable call below is will recurse into gdk_draw_drawable again,
* specifying the right impl for the destination. This means the composite
* we got here will be fed to get_composite_drawable again, which is a problem
* for window as that causes double the composite offset. Avoid this by passing
* in the impl directly.
*/
if (GDK_IS_WINDOW (composite))
composite_impl = GDK_WINDOW_OBJECT (src)->impl;
else
composite_impl = composite;
/* TODO: For non-native windows this may copy stuff from other overlapping
windows. We should clip that and (for windows with bg != None) clear that
area in the destination instead. */
GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc,
composite_impl,
xsrc - composite_x_offset,
ysrc - composite_y_offset,
xdest, ydest,
width, height);
width, height,
src);
g_object_unref (composite);
}
......@@ -871,7 +888,7 @@ real_draw_glyphs (GdkDrawable *drawable,
cairo_t *cr;
cr = gdk_cairo_create (drawable);
_gdk_gc_update_context (gc, cr, NULL, NULL, TRUE);
_gdk_gc_update_context (gc, cr, NULL, NULL, TRUE, drawable);
if (matrix)
{
......@@ -995,7 +1012,7 @@ gdk_draw_trapezoids (GdkDrawable *drawable,
g_return_if_fail (n_trapezoids == 0 || trapezoids != NULL);
cr = gdk_cairo_create (drawable);
_gdk_gc_update_context (gc, cr, NULL, NULL, TRUE);
_gdk_gc_update_context (gc, cr, NULL, NULL, TRUE, drawable);
for (i = 0; i < n_trapezoids; i++)
{
......@@ -1185,7 +1202,7 @@ gdk_drawable_real_get_image (GdkDrawable *drawable,
return gdk_drawable_copy_to_image (drawable, NULL, x, y, 0, 0, width, height);
}
static GdkDrawable*
static GdkDrawable *
gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
gint x,
gint y,
......@@ -1771,5 +1788,81 @@ _gdk_drawable_get_scratch_gc (GdkDrawable *drawable,
}
}
/**
* _gdk_drawable_get_subwindow_scratch_gc:
* @drawable: A #GdkDrawable
*
* Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has
* the standard values for @drawable, except for the graphics_exposures
* field which is %TRUE and the subwindow mode which is %GDK_INCLUDE_INFERIORS.
*
* The foreground color of the returned #GdkGC is undefined. The #GdkGC
* must not be altered in any way, except to change its foreground color.
*
* Return value: A #GdkGC suitable for drawing on @drawable
*
* Since: 2.18
**/
GdkGC *
_gdk_drawable_get_subwindow_scratch_gc (GdkDrawable *drawable)
{
GdkScreen *screen;
gint depth;
g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
screen = gdk_drawable_get_screen (drawable);
g_return_val_if_fail (!screen->closed, NULL);
depth = gdk_drawable_get_depth (drawable) - 1;
if (!screen->subwindow_gcs[depth])
{
GdkGCValues values;
GdkGCValuesMask mask;
values.graphics_exposures = TRUE;
values.subwindow_mode = GDK_INCLUDE_INFERIORS;
mask = GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW;
screen->subwindow_gcs[depth] =
gdk_gc_new_with_values (drawable, &values, mask);
}
return screen->subwindow_gcs[depth];
}
/**
* _gdk_drawable_get_source_drawable:
* @drawable: a #GdkDrawable
*
* Returns a drawable for the passed @drawable that is guaranteed to be
* usable to create a pixmap (e.g.: not an offscreen window).
*
* Since: 2.16
*/
GdkDrawable *
_gdk_drawable_get_source_drawable (GdkDrawable *drawable)
{
g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
if (GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable)
return GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable (drawable);
return drawable;
}
cairo_surface_t *
_gdk_drawable_create_cairo_surface (GdkDrawable *drawable,
int width,
int height)
{
return GDK_DRAWABLE_GET_CLASS (drawable)->create_cairo_surface (drawable,
width, height);
}
#define __GDK_DRAW_C__
#include "gdkaliasdef.c"
......@@ -105,7 +105,8 @@ struct _GdkDrawableClass
gint xdest,
gint ydest,
gint width,
gint height);
gint height,
GdkDrawable *original_src);
void (*draw_points) (GdkDrawable *drawable,
GdkGC *gc,
GdkPoint *points,
......@@ -200,10 +201,16 @@ struct _GdkDrawableClass
cairo_surface_t *(*ref_cairo_surface) (GdkDrawable *drawable);
GdkDrawable *(*get_source_drawable) (GdkDrawable *drawable);
void (*set_cairo_clip) (GdkDrawable *drawable,
cairo_t *cr);
cairo_surface_t * (*create_cairo_surface) (GdkDrawable *drawable,
int width,
int height);
/* Padding for future expansion */
void (*_gdk_reserved4) (void);
void (*_gdk_reserved5) (void);
void (*_gdk_reserved6) (void);
void (*_gdk_reserved7) (void);
void (*_gdk_reserved9) (void);
void (*_gdk_reserved10) (void);
......
......@@ -120,6 +120,63 @@ _gdk_event_queue_append (GdkDisplay *display,
return display->queued_tail;
}
/**
* _gdk_event_queue_insert_after:
* @display: a #GdkDisplay
* @sibling: Append after this event.
* @event: Event to append.
*
* Appends an event after the specified event, or if it isn't in
* the queue, onto the tail of the event queue.
*
* Returns: the newly appended list node.
*
* Since: 2.16
*/
GList*
_gdk_event_queue_insert_after (GdkDisplay *display,
GdkEvent *sibling,
GdkEvent *event)
{
GList *prev = g_list_find (display->queued_events, sibling);
if (prev && prev->next)
{
display->queued_events = g_list_insert_before (display->queued_events, prev->next, event);
return prev->next;
}
else
return _gdk_event_queue_append (display, event);
}
/**
* _gdk_event_queue_insert_after:
* @display: a #GdkDisplay
* @sibling: Append after this event.
* @event: Event to append.
*
* Appends an event before the specified event, or if it isn't in
* the queue, onto the tail of the event queue.
*
* Returns: the newly appended list node.
*
* Since: 2.16
*/
GList*
_gdk_event_queue_insert_before (GdkDisplay *display,
GdkEvent *sibling,
GdkEvent *event)
{
GList *next = g_list_find (display->queued_events, sibling);
if (next)
{
display->queued_events = g_list_insert_before (display->queued_events, next, event);
return next->prev;
}
else
return _gdk_event_queue_append (display, event);
}
/**
* _gdk_event_queue_remove_link:
* @display: a #GdkDisplay
......@@ -575,6 +632,7 @@ gdk_event_get_time (const GdkEvent *event)
case GDK_SETTING:
case GDK_OWNER_CHANGE:
case GDK_GRAB_BROKEN:
case GDK_EVENT_LAST:
/* return current time */
break;
}
......@@ -653,6 +711,7 @@ gdk_event_get_state (const GdkEvent *event,
case GDK_SETTING:
case GDK_OWNER_CHANGE:
case GDK_GRAB_BROKEN:
case GDK_EVENT_LAST:
/* no state field */
break;
}
......@@ -884,9 +943,17 @@ gdk_event_get_axis (const GdkEvent *event,
void
gdk_event_request_motions (const GdkEventMotion *event)
{
GdkDisplay *display;
g_return_if_fail (event != NULL);
if (event->type == GDK_MOTION_NOTIFY && event->is_hint)
gdk_device_get_state (event->device, event->window, NULL, NULL);
{
gdk_device_get_state (event->device, event->window, NULL, NULL);
display = gdk_drawable_get_display (event->window);
_gdk_display_enable_motion_hints (display);
}
}
/**
......@@ -1101,13 +1168,16 @@ gdk_synthesize_click (GdkDisplay *display,
gint nclicks)
{
GdkEvent temp_event;
GdkEvent *event_copy;
GList *link;
g_return_if_fail (event != NULL);
temp_event = *event;
temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
gdk_display_put_event (display, &temp_event);
event_copy = gdk_event_copy (&temp_event);
link = _gdk_event_queue_append (display, event_copy);
}
void
......
......@@ -151,7 +151,8 @@ typedef enum
GDK_SETTING = 33,
GDK_OWNER_CHANGE = 34,
GDK_GRAB_BROKEN = 35,
GDK_DAMAGE = 36
GDK_DAMAGE = 36,
GDK_EVENT_LAST /* helper variable for decls */
} GdkEventType;
/* Event masks. (Used to select what types of events a window
......
......@@ -43,12 +43,24 @@ struct _GdkGCPrivate
{
GdkRegion *clip_region;
GdkFill fill;
guint32 region_tag_applied;
int region_tag_offset_x;
int region_tag_offset_y;
GdkRegion *old_clip_region;
GdkPixmap *old_clip_mask;
GdkBitmap *stipple;
GdkPixmap *tile;
GdkPixmap *clip_mask;
guint32 fg_pixel;
guint32 bg_pixel;
guint subwindow_mode : 1;
guint fill : 2;
guint exposures : 2;
};
#define GDK_GC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_GC, GdkGCPrivate))
......@@ -150,6 +162,8 @@ _gdk_gc_init (GdkGC *gc,
gc->clip_x_origin = values->clip_x_origin;
if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
gc->clip_y_origin = values->clip_y_origin;
if ((values_mask & GDK_GC_CLIP_MASK) && values->clip_mask)
priv->clip_mask = g_object_ref (values->clip_mask);
if (values_mask & GDK_GC_TS_X_ORIGIN)
gc->ts_x_origin = values->ts_x_origin;
if (values_mask & GDK_GC_TS_Y_ORIGIN)
......@@ -172,6 +186,12 @@ _gdk_gc_init (GdkGC *gc,
priv->fg_pixel = values->foreground.pixel;
if (values_mask & GDK_GC_BACKGROUND)
priv->bg_pixel = values->background.pixel;
if (values_mask & GDK_GC_SUBWINDOW)
priv->subwindow_mode = values->subwindow_mode;
if (values_mask & GDK_GC_EXPOSURES)
priv->exposures = values->graphics_exposures;
else
priv->exposures = TRUE;
gc->colormap = gdk_drawable_get_colormap (drawable);
if (gc->colormap)
......@@ -183,9 +203,15 @@ gdk_gc_finalize (GObject *object)
{
GdkGC *gc = GDK_GC (object);
GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
if (priv->clip_region)
gdk_region_destroy (priv->clip_region);
if (priv->old_clip_region)
gdk_region_destroy (priv->old_clip_region);
if (priv->clip_mask)
g_object_unref (priv->clip_mask);
if (priv->old_clip_mask)
g_object_unref (priv->old_clip_mask);
if (gc->colormap)
g_object_unref (gc->colormap);
if (priv->tile)
......@@ -269,6 +295,12 @@ gdk_gc_set_values (GdkGC *gc,
priv = GDK_GC_GET_PRIVATE (gc);
if ((values_mask & GDK_GC_CLIP_X_ORIGIN) ||
(values_mask & GDK_GC_CLIP_Y_ORIGIN) ||
(values_mask & GDK_GC_CLIP_MASK) ||
(values_mask & GDK_GC_SUBWINDOW))
_gdk_gc_remove_drawable_clip (gc);
if (values_mask & GDK_GC_CLIP_X_ORIGIN)
gc->clip_x_origin = values->clip_x_origin;
if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
......@@ -279,6 +311,14 @@ gdk_gc_set_values (GdkGC *gc,
gc->ts_y_origin = values->ts_y_origin;
if (values_mask & GDK_GC_CLIP_MASK)
{
if (priv->clip_mask)
{
g_object_unref (priv->clip_mask);
priv->clip_mask = NULL;
}
if (values->clip_mask)
priv->clip_mask = g_object_ref (values->clip_mask);
if (priv->clip_region)
{
gdk_region_destroy (priv->clip_region);
......@@ -313,6 +353,10 @@ gdk_gc_set_values (GdkGC *gc,
priv->fg_pixel = values->foreground.pixel;
if (values_mask & GDK_GC_BACKGROUND)
priv->bg_pixel = values->background.pixel;
if (values_mask & GDK_GC_SUBWINDOW)
priv->subwindow_mode = values->subwindow_mode;
if (values_mask & GDK_GC_EXPOSURES)
priv->exposures = values->graphics_exposures;
GDK_GC_GET_CLASS (gc)->set_values (gc, values, values_mask);
}
......@@ -542,18 +586,120 @@ gdk_gc_set_clip_mask (GdkGC *gc,
gdk_gc_set_values (gc, &values, GDK_GC_CLIP_MASK);
}
/* Takes ownership of passed in region */
static void
_gdk_gc_set_clip_region_internal (GdkGC *gc,
GdkRegion *region)
_gdk_gc_set_clip_region_real (GdkGC *gc,
GdkRegion *region,
gboolean reset_origin)
{
GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
if (priv->clip_mask)
{
g_object_unref (priv->clip_mask);
priv->clip_mask = NULL;
}
if (priv->clip_region)
gdk_region_destroy (priv->clip_region);
priv->clip_region = region;
_gdk_windowing_gc_set_clip_region (gc, region);
_gdk_windowing_gc_set_clip_region (gc, region, reset_origin);
}
/* Doesn't copy region, allows not to reset origin */
void
_gdk_gc_set_clip_region_internal (GdkGC *gc,
GdkRegion *region,
gboolean reset_origin)
{
_gdk_gc_remove_drawable_clip (gc);
_gdk_gc_set_clip_region_real (gc, region, reset_origin);
}
void
_gdk_gc_add_drawable_clip (GdkGC *gc,
guint32 region_tag,
GdkRegion *region,
int offset_x,
int offset_y)
{
GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
if (priv->region_tag_applied == region_tag &&
offset_x == priv->region_tag_offset_x &&
offset_y == priv->region_tag_offset_y)
return; /* Already appied this drawable region */
if (priv->region_tag_applied)
_gdk_gc_remove_drawable_clip (gc);
region = gdk_region_copy (region);
if (offset_x != 0 || offset_y != 0)
gdk_region_offset (region, offset_x, offset_y);
if (priv->clip_mask)
{
int w, h;
GdkPixmap *new_mask;
GdkGC *tmp_gc;
GdkColor black = {0, 0, 0, 0};
priv->old_clip_mask = g_object_ref (priv->clip_mask);
gdk_drawable_get_size (priv->old_clip_mask, &w, &h);
new_mask = gdk_pixmap_new (priv->old_clip_mask, w, h, -1);
tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)new_mask, FALSE);
gdk_gc_set_foreground (tmp_gc, &black);
gdk_draw_rectangle (new_mask, tmp_gc, TRUE, 0, 0, -1, -1);
_gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); /* Takes ownership of region */
gdk_draw_drawable (new_mask,
tmp_gc,
priv->old_clip_mask,
0, 0,
0, 0,
-1, -1);
gdk_gc_set_clip_region (tmp_gc, NULL);