1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
29 #include <pango/pangocairo.h>
30 #include <gdk-pixbuf/gdk-pixbuf.h>
32 #include "gdkdrawable.h"
33 #include "gdkinternals.h"
34 #include "gdkwindow.h"
35 #include "gdkscreen.h"
36 #include "gdkpixbuf.h"
39 static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
44 gint *composite_x_offset,
45 gint *composite_y_offset);
46 static cairo_region_t * gdk_drawable_real_get_visible_region (GdkDrawable *drawable);
47 static void gdk_drawable_real_draw_drawable (GdkDrawable *drawable,
58 G_DEFINE_ABSTRACT_TYPE (GdkDrawable, gdk_drawable, G_TYPE_OBJECT)
61 gdk_drawable_class_init (GdkDrawableClass *klass)
63 klass->get_composite_drawable = gdk_drawable_real_get_composite_drawable;
64 /* Default implementation for clip and visible region is the same */
65 klass->get_clip_region = gdk_drawable_real_get_visible_region;
66 klass->get_visible_region = gdk_drawable_real_get_visible_region;
67 klass->draw_drawable = gdk_drawable_real_draw_drawable;
71 gdk_drawable_init (GdkDrawable *drawable)
75 /* Manipulation of drawables
79 * gdk_drawable_get_size:
80 * @drawable: a #GdkDrawable
81 * @width: (out) (allow-none): location to store drawable's width, or %NULL
82 * @height: (out) (allow-none): location to store drawable's height, or %NULL
84 * Fills *@width and *@height with the size of @drawable.
85 * @width or @height can be %NULL if you only want the other one.
87 * On the X11 platform, if @drawable is a #GdkWindow, the returned
88 * size is the size reported in the most-recently-processed configure
89 * event, rather than the current size on the X server.
93 gdk_drawable_get_size (GdkDrawable *drawable,
97 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
99 GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height);
103 * gdk_drawable_get_visual:
104 * @drawable: a #GdkDrawable
106 * Gets the #GdkVisual describing the pixel format of @drawable.
108 * Return value: a #GdkVisual
111 gdk_drawable_get_visual (GdkDrawable *drawable)
113 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
115 return GDK_DRAWABLE_GET_CLASS (drawable)->get_visual (drawable);
119 * gdk_drawable_get_depth:
120 * @drawable: a #GdkDrawable
122 * Obtains the bit depth of the drawable, that is, the number of bits
123 * that make up a pixel in the drawable's visual. Examples are 8 bits
124 * per pixel, 24 bits per pixel, etc.
126 * Return value: number of bits per pixel
129 gdk_drawable_get_depth (GdkDrawable *drawable)
131 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), 0);
133 return GDK_DRAWABLE_GET_CLASS (drawable)->get_depth (drawable);
136 * gdk_drawable_get_screen:
137 * @drawable: a #GdkDrawable
139 * Gets the #GdkScreen associated with a #GdkDrawable.
141 * Return value: the #GdkScreen associated with @drawable
146 gdk_drawable_get_screen(GdkDrawable *drawable)
148 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
150 return GDK_DRAWABLE_GET_CLASS (drawable)->get_screen (drawable);
154 * gdk_drawable_get_display:
155 * @drawable: a #GdkDrawable
157 * Gets the #GdkDisplay associated with a #GdkDrawable.
159 * Return value: the #GdkDisplay associated with @drawable
164 gdk_drawable_get_display (GdkDrawable *drawable)
166 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
168 return gdk_screen_get_display (gdk_drawable_get_screen (drawable));
172 * gdk_drawable_set_colormap:
173 * @drawable: a #GdkDrawable
174 * @colormap: a #GdkColormap
176 * Sets the colormap associated with @drawable. Normally this will
177 * happen automatically when the drawable is created; you only need to
178 * use this function if the drawable-creating function did not have a
179 * way to determine the colormap, and you then use drawable operations
180 * that require a colormap. The colormap for all drawables and
181 * graphics contexts you intend to use together should match. i.e.
182 * when using a #GdkGC to draw to a drawable, or copying one drawable
183 * to another, the colormaps should match.
187 gdk_drawable_set_colormap (GdkDrawable *drawable,
190 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
191 g_return_if_fail (cmap == NULL || gdk_drawable_get_depth (drawable)
192 == cmap->visual->depth);
194 GDK_DRAWABLE_GET_CLASS (drawable)->set_colormap (drawable, cmap);
198 * gdk_drawable_get_colormap:
199 * @drawable: a #GdkDrawable
201 * Gets the colormap for @drawable, if one is set; returns
204 * Return value: the colormap, or %NULL
207 gdk_drawable_get_colormap (GdkDrawable *drawable)
209 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
211 return GDK_DRAWABLE_GET_CLASS (drawable)->get_colormap (drawable);
219 * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
221 * @x: the x coordinate of the point.
222 * @y: the y coordinate of the point.
224 * Draws a point, using the foreground color and other attributes of
228 gdk_draw_point (GdkDrawable *drawable,
235 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
236 g_return_if_fail (GDK_IS_GC (gc));
241 GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, &point, 1);
245 * gdk_draw_rectangle:
246 * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
248 * @filled: %TRUE if the rectangle should be filled.
249 * @x: the x coordinate of the left edge of the rectangle.
250 * @y: the y coordinate of the top edge of the rectangle.
251 * @width: the width of the rectangle.
252 * @height: the height of the rectangle.
254 * Draws a rectangular outline or filled rectangle, using the foreground color
255 * and other attributes of the #GdkGC.
257 * A rectangle drawn filled is 1 pixel smaller in both dimensions than a
258 * rectangle outlined. Calling
259 * <literal>gdk_draw_rectangle (window, gc, TRUE, 0, 0, 20, 20)</literal>
260 * results in a filled rectangle 20 pixels wide and 20 pixels high. Calling
261 * <literal>gdk_draw_rectangle (window, gc, FALSE, 0, 0, 20, 20)</literal>
262 * results in an outlined rectangle with corners at (0, 0), (0, 20), (20, 20),
263 * and (20, 0), which makes it 21 pixels wide and 21 pixels high.
266 gdk_draw_rectangle (GdkDrawable *drawable,
274 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
275 g_return_if_fail (GDK_IS_GC (gc));
277 if (width < 0 || height < 0)
282 gdk_drawable_get_size (drawable, &real_width, &real_height);
287 height = real_height;
290 GDK_DRAWABLE_GET_CLASS (drawable)->draw_rectangle (drawable, gc, filled, x, y,
296 * @drawable: a #GdkDrawable
297 * @gc: a #GdkGC sharing the drawable's visual and colormap
298 * @src: the source #GdkDrawable, which may be the same as @drawable
299 * @xsrc: X position in @src of rectangle to draw
300 * @ysrc: Y position in @src of rectangle to draw
301 * @xdest: X position in @drawable where the rectangle should be drawn
302 * @ydest: Y position in @drawable where the rectangle should be drawn
303 * @width: width of rectangle to draw, or -1 for entire @src width
304 * @height: height of rectangle to draw, or -1 for entire @src height
306 * Copies the @width x @height region of @src at coordinates (@xsrc,
307 * @ysrc) to coordinates (@xdest, @ydest) in @drawable.
308 * @width and/or @height may be given as -1, in which case the entire
309 * @src drawable will be copied.
311 * Most fields in @gc are not used for this operation, but notably the
312 * clip mask or clip region will be honored.
314 * The source and destination drawables must have the same visual and
315 * colormap, or errors will result. (On X11, failure to match
316 * visual/colormap results in a BadMatch error from the X server.)
317 * A common cause of this problem is an attempt to draw a bitmap to
318 * a color drawable. The way to draw a bitmap is to set the bitmap as
319 * the stipple on the #GdkGC, set the fill mode to %GDK_STIPPLED, and
320 * then draw the rectangle.
323 gdk_draw_drawable (GdkDrawable *drawable,
333 GdkDrawable *composite;
334 gint composite_x_offset = 0;
335 gint composite_y_offset = 0;
337 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
338 g_return_if_fail (GDK_IS_DRAWABLE (src));
339 g_return_if_fail (GDK_IS_GC (gc));
341 if (width < 0 || height < 0)
346 gdk_drawable_get_size (src, &real_width, &real_height);
351 height = real_height;
356 GDK_DRAWABLE_GET_CLASS (src)->get_composite_drawable (src,
360 &composite_y_offset);
362 /* TODO: For non-native windows this may copy stuff from other overlapping
363 windows. We should clip that and (for windows with bg != None) clear that
364 area in the destination instead. */
366 if (GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src)
367 GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src (drawable, gc,
369 xsrc - composite_x_offset,
370 ysrc - composite_y_offset,
374 else /* backwards compat for old out-of-tree implementations of GdkDrawable (are there any?) */
375 GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc,
377 xsrc - composite_x_offset,
378 ysrc - composite_y_offset,
382 g_object_unref (composite);
387 * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
389 * @points: an array of #GdkPoint structures.
390 * @n_points: the number of points to be drawn.
392 * Draws a number of points, using the foreground color and other
393 * attributes of the #GdkGC.
396 gdk_draw_points (GdkDrawable *drawable,
398 const GdkPoint *points,
401 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
402 g_return_if_fail ((points != NULL) && (n_points > 0));
403 g_return_if_fail (GDK_IS_GC (gc));
404 g_return_if_fail (n_points >= 0);
409 GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc,
410 (GdkPoint *) points, n_points);
414 gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
419 gint *composite_x_offset,
420 gint *composite_y_offset)
422 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
424 *composite_x_offset = 0;
425 *composite_y_offset = 0;
427 return g_object_ref (drawable);
431 * gdk_drawable_get_clip_region:
432 * @drawable: a #GdkDrawable
434 * Computes the region of a drawable that potentially can be written
435 * to by drawing primitives. This region will not take into account
436 * the clip region for the GC, and may also not take into account
437 * other factors such as if the window is obscured by other windows,
438 * but no area outside of this region will be affected by drawing
441 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
445 gdk_drawable_get_clip_region (GdkDrawable *drawable)
447 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
449 return GDK_DRAWABLE_GET_CLASS (drawable)->get_clip_region (drawable);
453 * gdk_drawable_get_visible_region:
454 * @drawable: a #GdkDrawable
456 * Computes the region of a drawable that is potentially visible.
457 * This does not necessarily take into account if the window is
458 * obscured by other windows, but no area outside of this region
461 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
465 gdk_drawable_get_visible_region (GdkDrawable *drawable)
467 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
469 return GDK_DRAWABLE_GET_CLASS (drawable)->get_visible_region (drawable);
472 static cairo_region_t *
473 gdk_drawable_real_get_visible_region (GdkDrawable *drawable)
480 gdk_drawable_get_size (drawable, &rect.width, &rect.height);
482 return cairo_region_create_rectangle (&rect);
486 * _gdk_drawable_ref_cairo_surface:
487 * @drawable: a #GdkDrawable
489 * Obtains a #cairo_surface_t for the given drawable. If a
490 * #cairo_surface_t for the drawable already exists, it will be
491 * referenced, otherwise a new surface will be created.
493 * Return value: a newly referenced #cairo_surface_t that points
494 * to @drawable. Unref with cairo_surface_destroy()
497 _gdk_drawable_ref_cairo_surface (GdkDrawable *drawable)
499 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
501 return GDK_DRAWABLE_GET_CLASS (drawable)->ref_cairo_surface (drawable);
504 /* Implementation of the old vfunc in terms of the new one
505 in case someone calls it directly (which they shouldn't!) */
507 gdk_drawable_real_draw_drawable (GdkDrawable *drawable,
517 GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src (drawable,
529 /************************************************************************/
532 * _gdk_drawable_get_scratch_gc:
533 * @drawable: A #GdkDrawable
534 * @graphics_exposures: Whether the returned #GdkGC should generate graphics exposures
536 * Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has
537 * the standard values for @drawable, except for the graphics_exposures
538 * field which is determined by the @graphics_exposures parameter.
540 * The foreground color of the returned #GdkGC is undefined. The #GdkGC
541 * must not be altered in any way, except to change its foreground color.
543 * Return value: A #GdkGC suitable for drawing on @drawable
548 _gdk_drawable_get_scratch_gc (GdkDrawable *drawable,
549 gboolean graphics_exposures)
554 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
556 screen = gdk_drawable_get_screen (drawable);
558 g_return_val_if_fail (!screen->closed, NULL);
560 depth = gdk_drawable_get_depth (drawable) - 1;
562 if (graphics_exposures)
564 if (!screen->exposure_gcs[depth])
567 GdkGCValuesMask mask;
569 values.graphics_exposures = TRUE;
570 mask = GDK_GC_EXPOSURES;
572 screen->exposure_gcs[depth] =
573 gdk_gc_new_with_values (drawable, &values, mask);
576 return screen->exposure_gcs[depth];
580 if (!screen->normal_gcs[depth])
582 screen->normal_gcs[depth] =
583 gdk_gc_new (drawable);
586 return screen->normal_gcs[depth];
591 * _gdk_drawable_get_subwindow_scratch_gc:
592 * @drawable: A #GdkDrawable
594 * Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has
595 * the standard values for @drawable, except for the graphics_exposures
596 * field which is %TRUE and the subwindow mode which is %GDK_INCLUDE_INFERIORS.
598 * The foreground color of the returned #GdkGC is undefined. The #GdkGC
599 * must not be altered in any way, except to change its foreground color.
601 * Return value: A #GdkGC suitable for drawing on @drawable
606 _gdk_drawable_get_subwindow_scratch_gc (GdkDrawable *drawable)
611 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
613 screen = gdk_drawable_get_screen (drawable);
615 g_return_val_if_fail (!screen->closed, NULL);
617 depth = gdk_drawable_get_depth (drawable) - 1;
619 if (!screen->subwindow_gcs[depth])
622 GdkGCValuesMask mask;
624 values.graphics_exposures = TRUE;
625 values.subwindow_mode = GDK_INCLUDE_INFERIORS;
626 mask = GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW;
628 screen->subwindow_gcs[depth] =
629 gdk_gc_new_with_values (drawable, &values, mask);
632 return screen->subwindow_gcs[depth];
637 * _gdk_drawable_get_source_drawable:
638 * @drawable: a #GdkDrawable
640 * Returns a drawable for the passed @drawable that is guaranteed to be
641 * usable to create a pixmap (e.g.: not an offscreen window).
646 _gdk_drawable_get_source_drawable (GdkDrawable *drawable)
648 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
650 if (GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable)
651 return GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable (drawable);
657 _gdk_drawable_create_cairo_surface (GdkDrawable *drawable,
661 return GDK_DRAWABLE_GET_CLASS (drawable)->create_cairo_surface (drawable,