surface->impl_surface = NULL;
}
- if (surface->shape)
- cairo_region_destroy (surface->shape);
-
if (surface->input_shape)
cairo_region_destroy (surface->input_shape);
child_region = cairo_region_create_rectangle (&r);
- if (sibling->shape)
- {
- /* Adjust shape region to parent surface coords */
- cairo_region_translate (sibling->shape, sibling->x, sibling->y);
- cairo_region_intersect (child_region, sibling->shape);
- cairo_region_translate (sibling->shape, -sibling->x, -sibling->y);
- }
-
cairo_region_subtract (region, child_region);
cairo_region_destroy (child_region);
}
child_region = cairo_region_create_rectangle (&r);
- if (child->shape)
- {
- /* Adjust shape region to parent surface coords */
- cairo_region_translate (child->shape, child->x, child->y);
- cairo_region_intersect (child_region, child->shape);
- cairo_region_translate (child->shape, -child->x, -child->y);
- }
-
if (for_input)
{
if (child->input_shape)
*y = parent_y - surface->y;
}
-/**
- * gdk_surface_shape_combine_region:
- * @surface: a #GdkSurface
- * @shape_region: (allow-none): region of surface to be non-transparent
- * @offset_x: X position of @shape_region in @surface coordinates
- * @offset_y: Y position of @shape_region in @surface coordinates
- *
- * Makes pixels in @surface outside @shape_region be transparent,
- * so that the surface may be nonrectangular.
- *
- * If @shape_region is %NULL, the shape will be unset, so the whole
- * surface will be opaque again. @offset_x and @offset_y are ignored
- * if @shape_region is %NULL.
- *
- * On the X11 platform, this uses an X server extension which is
- * widely available on most common platforms, but not available on
- * very old X servers, and occasionally the implementation will be
- * buggy. On servers without the shape extension, this function
- * will do nothing.
- *
- * This function works on both toplevel and child surfaces.
- */
-void
-gdk_surface_shape_combine_region (GdkSurface *surface,
- const cairo_region_t *shape_region,
- gint offset_x,
- gint offset_y)
-{
- cairo_region_t *old_region, *new_region, *diff;
-
- g_return_if_fail (GDK_IS_SURFACE (surface));
-
- if (GDK_SURFACE_DESTROYED (surface))
- return;
-
- if (!surface->shape && shape_region == NULL)
- return;
-
- surface->shaped = (shape_region != NULL);
-
- if (surface->shape)
- cairo_region_destroy (surface->shape);
-
- old_region = NULL;
- if (GDK_SURFACE_IS_MAPPED (surface))
- old_region = cairo_region_copy (surface->clip_region);
-
- if (shape_region)
- {
- surface->shape = cairo_region_copy (shape_region);
- cairo_region_translate (surface->shape, offset_x, offset_y);
- }
- else
- surface->shape = NULL;
-
- recompute_visible_regions (surface, FALSE);
-
- if (old_region)
- {
- new_region = cairo_region_copy (surface->clip_region);
-
- /* New area in the surface, needs invalidation */
- diff = cairo_region_copy (new_region);
- cairo_region_subtract (diff, old_region);
-
- gdk_surface_invalidate_region_full (surface, diff, TRUE);
-
- cairo_region_destroy (diff);
-
- if (!gdk_surface_is_toplevel (surface))
- {
- /* New area in the non-root parent surface, needs invalidation */
- diff = cairo_region_copy (old_region);
- cairo_region_subtract (diff, new_region);
-
- /* Adjust region to parent surface coords */
- cairo_region_translate (diff, surface->x, surface->y);
-
- gdk_surface_invalidate_region_full (surface->parent, diff, TRUE);
-
- cairo_region_destroy (diff);
- }
-
- cairo_region_destroy (new_region);
- cairo_region_destroy (old_region);
- }
-}
-
-static void
-do_child_shapes (GdkSurface *surface,
- gboolean merge)
-{
- GdkRectangle r;
- cairo_region_t *region;
-
- r.x = 0;
- r.y = 0;
- r.width = surface->width;
- r.height = surface->height;
-
- region = cairo_region_create_rectangle (&r);
- remove_child_area (surface, FALSE, region);
-
- if (merge && surface->shape)
- cairo_region_subtract (region, surface->shape);
-
- cairo_region_xor_rectangle (region, &r);
-
- gdk_surface_shape_combine_region (surface, region, 0, 0);
-
- cairo_region_destroy (region);
-}
-
-/**
- * gdk_surface_set_child_shapes:
- * @surface: a #GdkSurface
- *
- * Sets the shape mask of @surface to the union of shape masks
- * for all children of @surface, ignoring the shape mask of @surface
- * itself. Contrast with gdk_surface_merge_child_shapes() which includes
- * the shape mask of @surface in the masks to be merged.
- **/
-void
-gdk_surface_set_child_shapes (GdkSurface *surface)
-{
- g_return_if_fail (GDK_IS_SURFACE (surface));
-
- do_child_shapes (surface, FALSE);
-}
-
-/**
- * gdk_surface_merge_child_shapes:
- * @surface: a #GdkSurface
- *
- * Merges the shape masks for any child surfaces into the
- * shape mask for @surface. i.e. the union of all masks
- * for @surface and its children will become the new mask
- * for @surface. See gdk_surface_shape_combine_region().
- *
- * This function is distinct from gdk_surface_set_child_shapes()
- * because it includes @surface’s shape mask in the set of shapes to
- * be merged.
- */
-void
-gdk_surface_merge_child_shapes (GdkSurface *surface)
-{
- g_return_if_fail (GDK_IS_SURFACE (surface));
-
- do_child_shapes (surface, TRUE);
-}
-
/**
* gdk_surface_input_shape_combine_region:
* @surface: a #GdkSurface
region = cairo_region_create_rectangle (&r);
remove_child_area (surface, TRUE, region);
- if (merge && surface->shape)
- cairo_region_subtract (region, surface->shape);
if (merge && surface->input_shape)
cairo_region_subtract (region, surface->input_shape);
return surface->input_only;
}
-/**
- * gdk_surface_is_shaped:
- * @surface: a toplevel #GdkSurface
- *
- * Determines whether or not the surface is shaped.
- *
- * Returns: %TRUE if @surface is shaped
- */
-gboolean
-gdk_surface_is_shaped (GdkSurface *surface)
-{
- g_return_val_if_fail (GDK_IS_SURFACE (surface), FALSE);
-
- return surface->shaped;
-}
-
/* Gets the toplevel for a surface as used for events,
i.e. including offscreen parents going up to the native
toplevel */
return
x >= 0 && x < surface->width &&
y >= 0 && y < surface->height &&
- (surface->shape == NULL ||
- cairo_region_contains_point (surface->shape,
- x, y)) &&
(surface->input_shape == NULL ||
cairo_region_contains_point (surface->input_shape,
x, y));
if (surface->input_only)
g_print (" input-only");
- if (surface->shaped)
- g_print (" shaped");
-
if (!gdk_surface_is_visible ((GdkSurface *)surface))
g_print (" hidden");
static GQuark quark_accel_path = 0;
static GQuark quark_accel_closures = 0;
static GQuark quark_parent_surface = 0;
-static GQuark quark_shape_info = 0;
static GQuark quark_input_shape_info = 0;
static GQuark quark_pango_context = 0;
static GQuark quark_mnemonic_labels = 0;
quark_accel_path = g_quark_from_static_string ("gtk-accel-path");
quark_accel_closures = g_quark_from_static_string ("gtk-accel-closures");
quark_parent_surface = g_quark_from_static_string ("gtk-parent-surface");
- quark_shape_info = g_quark_from_static_string ("gtk-shape-info");
quark_input_shape_info = g_quark_from_static_string ("gtk-input-shape-info");
quark_pango_context = g_quark_from_static_string ("gtk-pango-context");
quark_mnemonic_labels = g_quark_from_static_string ("gtk-mnemonic-labels");
gtk_widget_realize (GtkWidget *widget)
{
GtkWidgetPrivate *priv;
- cairo_region_t *region;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (widget->priv->anchored ||
gtk_widget_real_set_has_tooltip (widget, gtk_widget_get_has_tooltip (widget), TRUE);
- if (priv->has_shape_mask)
- {
- region = g_object_get_qdata (G_OBJECT (widget), quark_shape_info);
- gdk_surface_shape_combine_region (priv->surface, region, 0, 0);
- }
-
gtk_widget_update_input_shape (widget);
if (priv->multidevice)
g_object_ref (widget);
gtk_widget_push_verify_invariants (widget);
- if (widget->priv->has_shape_mask)
- gtk_widget_shape_combine_region (widget, NULL);
-
if (g_object_get_qdata (G_OBJECT (widget), quark_input_shape_info))
gtk_widget_input_shape_combine_region (widget, NULL);
}
}
-/**
- * gtk_widget_shape_combine_region:
- * @widget: a #GtkWidget
- * @region: (allow-none): shape to be added, or %NULL to remove an existing shape
- *
- * Sets a shape for this widget’s GDK surface. This allows for
- * transparent windows etc., see gdk_surface_shape_combine_region()
- * for more information.
- **/
-void
-gtk_widget_shape_combine_region (GtkWidget *widget,
- cairo_region_t *region)
-{
- GtkWidgetPrivate *priv;
-
- g_return_if_fail (GTK_IS_WIDGET (widget));
- /* set_shape doesn't work on widgets without GDK surface */
- g_return_if_fail (_gtk_widget_get_has_surface (widget));
-
- priv = widget->priv;
-
- if (region == NULL)
- {
- priv->has_shape_mask = FALSE;
-
- if (priv->surface)
- gdk_surface_shape_combine_region (priv->surface, NULL, 0, 0);
-
- g_object_set_qdata (G_OBJECT (widget), quark_shape_info, NULL);
- }
- else
- {
- priv->has_shape_mask = TRUE;
-
- g_object_set_qdata_full (G_OBJECT (widget), quark_shape_info,
- cairo_region_copy (region),
- (GDestroyNotify) cairo_region_destroy);
-
- /* set shape if widget has a GDK surface already.
- * otherwise the shape is scheduled to be set by gtk_widget_realize().
- */
- if (priv->surface)
- gdk_surface_shape_combine_region (priv->surface, region, 0, 0);
- }
-}
-
static void
gtk_widget_update_input_shape (GtkWidget *widget)
{