]> Pileus Git - ~andy/gtk/blob - gdk/gdkdraw.c
Throughout: assorted docs
[~andy/gtk] / gdk / gdkdraw.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /*
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/. 
25  */
26
27 #include "gdkdrawable.h"
28 #include "gdkinternals.h"
29 #include "gdkwindow.h"
30
31 static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
32                                                               gint         x,
33                                                               gint         y,
34                                                               gint         width,
35                                                               gint         height,
36                                                               gint        *composite_x_offset,
37                                                               gint        *composite_y_offset);
38 static GdkRegion *  gdk_drawable_real_get_visible_region     (GdkDrawable *drawable);
39
40 static void gdk_drawable_class_init (GdkDrawableClass *klass);
41
42 GType
43 gdk_drawable_get_type (void)
44 {
45   static GType object_type = 0;
46
47   if (!object_type)
48     {
49       static const GTypeInfo object_info =
50       {
51         sizeof (GdkDrawableClass),
52         (GBaseInitFunc) NULL,
53         (GBaseFinalizeFunc) NULL,
54         (GClassInitFunc) gdk_drawable_class_init,
55         NULL,           /* class_finalize */
56         NULL,           /* class_data */
57         sizeof (GdkDrawable),
58         0,              /* n_preallocs */
59         (GInstanceInitFunc) NULL,
60       };
61       
62       object_type = g_type_register_static (G_TYPE_OBJECT,
63                                             "GdkDrawable",
64                                             &object_info, 0);
65     }  
66
67   return object_type;
68 }
69
70 static void
71 gdk_drawable_class_init (GdkDrawableClass *klass)
72 {
73   klass->get_composite_drawable = gdk_drawable_real_get_composite_drawable;
74   /* Default implementation for clip and visible region is the same */
75   klass->get_clip_region = gdk_drawable_real_get_visible_region;
76   klass->get_visible_region = gdk_drawable_real_get_visible_region;
77 }
78
79 /* Manipulation of drawables
80  */
81
82 /**
83  * gdk_drawable_set_data:
84  * @drawable: a #GdkDrawable
85  * @key: name to store the data under
86  * @data: arbitrary data
87  * @destroy_func: function to free @data, or %NULL
88  *
89  * This function is equivalent to g_object_set_data(),
90  * the #GObject variant should be used instead.
91  * 
92  **/
93 void          
94 gdk_drawable_set_data (GdkDrawable   *drawable,
95                        const gchar   *key,
96                        gpointer       data,
97                        GDestroyNotify destroy_func)
98 {
99   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
100   
101   g_object_set_qdata_full (G_OBJECT (drawable),
102                            g_quark_from_string (key),
103                            data,
104                            destroy_func);
105 }
106
107 /**
108  * gdk_drawable_get_data:
109  * @drawable: a #GdkDrawable
110  * @key: name the data was stored under
111  * 
112  * Equivalent to g_object_get_data(); the #GObject variant should be
113  * used instead.
114  * 
115  * Return value: the data stored at @key
116  **/
117 gpointer
118 gdk_drawable_get_data (GdkDrawable   *drawable,
119                        const gchar   *key)
120 {
121   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
122   
123   return g_object_get_qdata (G_OBJECT (drawable),
124                              g_quark_try_string (key));
125 }
126
127 /**
128  * gdk_drawable_get_size:
129  * @drawable: a #GdkDrawable
130  * @width: location to store drawable's width, or %NULL
131  * @height: location to store drawable's height, or %NULL
132  *
133  * Fills *@width and *@height with the size of @drawable.
134  * @width or @height can be %NULL if you only want the other one.
135  * 
136  * On the X11 platform, if @drawable is a #GdkWindow, the returned
137  * size is the size reported in the most-recently-processed configure
138  * event, rather than the current size on the X server.
139  * 
140  **/
141 void
142 gdk_drawable_get_size (GdkDrawable *drawable,
143                        gint        *width,
144                        gint        *height)
145 {
146   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
147
148   GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height);  
149 }
150
151 /**
152  * gdk_drawable_get_visual:
153  * @drawable: a #GdkDrawable
154  * 
155  * Gets the #GdkVisual describing the pixel format of @drawable.
156  * 
157  * Return value: a #GdkVisual
158  **/
159 GdkVisual*
160 gdk_drawable_get_visual (GdkDrawable *drawable)
161 {
162   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
163   
164   return GDK_DRAWABLE_GET_CLASS (drawable)->get_visual (drawable);
165 }
166
167 /**
168  * gdk_drawable_get_depth:
169  * @drawable: a #GdkDrawable
170  * 
171  * Obtains the bit depth of the drawable, that is, the number of bits
172  * that make up a pixel in the drawable's visual. Examples are 8 bits
173  * per pixel, 24 bits per pixel, etc.
174  * 
175  * Return value: number of bits per pixel
176  **/
177 gint
178 gdk_drawable_get_depth (GdkDrawable *drawable)
179 {
180   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), 0);
181
182   return GDK_DRAWABLE_GET_CLASS (drawable)->get_depth (drawable);
183 }
184
185 /**
186  * gdk_drawable_set_colormap:
187  * @drawable: a #GdkDrawable
188  * @colormap: a #GdkColormap
189  *
190  * Sets the colormap associated with @drawable. Normally this will
191  * happen automatically when the drawable is created; you only need to
192  * use this function if the drawable-creating function did not have a
193  * way to determine the colormap, and you then use drawable operations
194  * that require a colormap. The colormap for all drawables and
195  * graphics contexts you intend to use together should match. i.e.
196  * when using a #GdkGC to draw to a drawable, or copying one drawable
197  * to another, the colormaps should match.
198  * 
199  **/
200 void
201 gdk_drawable_set_colormap (GdkDrawable *drawable,
202                            GdkColormap *cmap)
203 {
204   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
205   g_return_if_fail (cmap == NULL || gdk_drawable_get_depth (drawable)
206                     == cmap->visual->depth);
207
208   GDK_DRAWABLE_GET_CLASS (drawable)->set_colormap (drawable, cmap);
209 }
210
211 /**
212  * gdk_drawable_get_colormap:
213  * @drawable: a #GdkDrawable
214  * 
215  * Gets the colormap for @drawable, if one is set; returns
216  * %NULL otherwise.
217  * 
218  * Return value: the colormap, or %NULL
219  **/
220 GdkColormap*
221 gdk_drawable_get_colormap (GdkDrawable *drawable)
222 {
223   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
224
225   return GDK_DRAWABLE_GET_CLASS (drawable)->get_colormap (drawable);
226 }
227
228 /**
229  * gdk_drawable_ref:
230  * @drawable: a #GdkDrawable
231  * 
232  * Deprecated equivalent of calling g_object_ref() on @drawable.
233  * (Drawables were not objects in previous versions of GDK.)
234  * 
235  * Return value: the same @drawable passed in
236  **/
237 GdkDrawable*
238 gdk_drawable_ref (GdkDrawable *drawable)
239 {
240   return (GdkDrawable *) g_object_ref (G_OBJECT (drawable));
241 }
242
243 /**
244  * gdk_drawable_unref:
245  * @drawable: a #GdkDrawable
246  * 
247  * Deprecated equivalent of calling g_object_unref() on @drawable.
248  * 
249  **/
250 void
251 gdk_drawable_unref (GdkDrawable *drawable)
252 {
253   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
254
255   g_object_unref (G_OBJECT (drawable));
256 }
257
258 /* Drawing
259  */
260 void
261 gdk_draw_point (GdkDrawable *drawable,
262                 GdkGC       *gc,
263                 gint         x,
264                 gint         y)
265 {
266   GdkPoint point;
267
268   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
269   g_return_if_fail (GDK_IS_GC (gc));
270
271   point.x = x;
272   point.y = y;
273   
274   GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, &point, 1);
275 }
276
277 void
278 gdk_draw_line (GdkDrawable *drawable,
279                GdkGC       *gc,
280                gint         x1,
281                gint         y1,
282                gint         x2,
283                gint         y2)
284 {
285   GdkSegment segment;
286
287   g_return_if_fail (drawable != NULL);
288   g_return_if_fail (gc != NULL);
289   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
290   g_return_if_fail (GDK_IS_GC (gc));
291
292   segment.x1 = x1;
293   segment.y1 = y1;
294   segment.x2 = x2;
295   segment.y2 = y2;
296   GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc, &segment, 1);
297 }
298
299 void
300 gdk_draw_rectangle (GdkDrawable *drawable,
301                     GdkGC       *gc,
302                     gint         filled,
303                     gint         x,
304                     gint         y,
305                     gint         width,
306                     gint         height)
307 {  
308   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
309   g_return_if_fail (GDK_IS_GC (gc));
310
311   if (width < 0 || height < 0)
312     {
313       gint real_width;
314       gint real_height;
315       
316       gdk_drawable_get_size (drawable, &real_width, &real_height);
317
318       if (width < 0)
319         width = real_width;
320       if (height < 0)
321         height = real_height;
322     }
323
324   GDK_DRAWABLE_GET_CLASS (drawable)->draw_rectangle (drawable, gc, filled, x, y,
325                                                      width, height);
326 }
327
328 void
329 gdk_draw_arc (GdkDrawable *drawable,
330               GdkGC       *gc,
331               gint         filled,
332               gint         x,
333               gint         y,
334               gint         width,
335               gint         height,
336               gint         angle1,
337               gint         angle2)
338 {  
339   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
340   g_return_if_fail (GDK_IS_GC (gc));
341
342   if (width < 0 || height < 0)
343     {
344       gint real_width;
345       gint real_height;
346       
347       gdk_drawable_get_size (drawable, &real_width, &real_height);
348
349       if (width < 0)
350         width = real_width;
351       if (height < 0)
352         height = real_height;
353     }
354
355   GDK_DRAWABLE_GET_CLASS (drawable)->draw_arc (drawable, gc, filled,
356                                                x, y, width, height, angle1, angle2);
357 }
358
359 void
360 gdk_draw_polygon (GdkDrawable *drawable,
361                   GdkGC       *gc,
362                   gint         filled,
363                   GdkPoint    *points,
364                   gint         npoints)
365 {
366   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
367   g_return_if_fail (GDK_IS_GC (gc));
368
369   GDK_DRAWABLE_GET_CLASS (drawable)->draw_polygon (drawable, gc, filled,
370                                                    points, npoints);
371 }
372
373 /* gdk_draw_string
374  *
375  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
376  *
377  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
378  */
379 void
380 gdk_draw_string (GdkDrawable *drawable,
381                  GdkFont     *font,
382                  GdkGC       *gc,
383                  gint         x,
384                  gint         y,
385                  const gchar *string)
386 {
387   gdk_draw_text (drawable, font, gc, x, y, string, _gdk_font_strlen (font, string));
388 }
389
390 /* gdk_draw_text
391  *
392  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
393  *
394  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
395  */
396 void
397 gdk_draw_text (GdkDrawable *drawable,
398                GdkFont     *font,
399                GdkGC       *gc,
400                gint         x,
401                gint         y,
402                const gchar *text,
403                gint         text_length)
404 {
405   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
406   g_return_if_fail (font != NULL);
407   g_return_if_fail (GDK_IS_GC (gc));
408   g_return_if_fail (text != NULL);
409
410   GDK_DRAWABLE_GET_CLASS (drawable)->draw_text (drawable, font, gc, x, y, text, text_length);
411 }
412
413 void
414 gdk_draw_text_wc (GdkDrawable    *drawable,
415                   GdkFont        *font,
416                   GdkGC          *gc,
417                   gint            x,
418                   gint            y,
419                   const GdkWChar *text,
420                   gint            text_length)
421 {
422   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
423   g_return_if_fail (font != NULL);
424   g_return_if_fail (GDK_IS_GC (gc));
425   g_return_if_fail (text != NULL);
426
427   GDK_DRAWABLE_GET_CLASS (drawable)->draw_text_wc (drawable, font, gc, x, y, text, text_length);
428 }
429
430 /**
431  * gdk_draw_drawable:
432  * @drawable: a #GdkDrawable
433  * @gc: a #GdkGC sharing the drawable's visual and colormap
434  * @src: another #GdkDrawable
435  * @xsrc: X position in @src of rectangle to draw
436  * @ysrc: Y position in @src of rectangle to draw
437  * @xdest: X position in @drawable where the rectangle should be drawn
438  * @ydest: Y position in @drawable where the rectangle should be drawn
439  * @width: width of rectangle to draw, or -1 for entire @src width
440  * @height: height of rectangle to draw, or -1 for entire @src height
441  *
442  * Copies the @width x @height region of @src at coordinates (@xsrc,
443  * @ysrc) to coordinates (@xdest, @ydest) in @drawable.
444  * @width and/or @height may be given as -1, in which case the entire
445  * @src drawable will be copied.
446  *
447  * Most fields in @gc are not used for this operation, but notably the
448  * clip mask or clip region will be honored.
449  *
450  * The source and destination drawables must have the same visual and
451  * colormap, or errors will result. (On X11, failure to match
452  * visual/colormap results in a BadMatch error from the X server.)
453  * A common cause of this problem is an attempt to draw a bitmap to
454  * a color drawable. The way to draw a bitmap is to set the
455  * bitmap as a clip mask on your #GdkGC, then use gdk_draw_rectangle()
456  * to draw a rectangle clipped to the bitmap.
457  **/
458 void
459 gdk_draw_drawable (GdkDrawable *drawable,
460                    GdkGC       *gc,
461                    GdkDrawable *src,
462                    gint         xsrc,
463                    gint         ysrc,
464                    gint         xdest,
465                    gint         ydest,
466                    gint         width,
467                    gint         height)
468 {
469   GdkDrawable *composite;
470   gint composite_x_offset = 0;
471   gint composite_y_offset = 0;
472
473   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
474   g_return_if_fail (src != NULL);
475   g_return_if_fail (GDK_IS_GC (gc));
476
477   if (width < 0 || height < 0)
478     {
479       gint real_width;
480       gint real_height;
481       
482       gdk_drawable_get_size (src, &real_width, &real_height);
483
484       if (width < 0)
485         width = real_width;
486       if (height < 0)
487         height = real_height;
488     }
489
490
491   composite =
492     GDK_DRAWABLE_GET_CLASS (src)->get_composite_drawable (src,
493                                                           xsrc, ysrc,
494                                                           width, height,
495                                                           &composite_x_offset,
496                                                           &composite_y_offset);
497
498   
499   GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc, composite,
500                                                     xsrc - composite_x_offset,
501                                                     ysrc - composite_y_offset,
502                                                     xdest, ydest,
503                                                     width, height);
504   
505   g_object_unref (G_OBJECT (composite));
506 }
507
508 void
509 gdk_draw_image (GdkDrawable *drawable,
510                 GdkGC       *gc,
511                 GdkImage    *image,
512                 gint         xsrc,
513                 gint         ysrc,
514                 gint         xdest,
515                 gint         ydest,
516                 gint         width,
517                 gint         height)
518 {
519   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
520   g_return_if_fail (image != NULL);
521   g_return_if_fail (GDK_IS_GC (gc));
522
523   if (width == -1)
524     width = image->width;
525   if (height == -1)
526     height = image->height;
527
528   GDK_DRAWABLE_GET_CLASS (drawable)->draw_image (drawable, gc, image, xsrc, ysrc,
529                                                  xdest, ydest, width, height);
530 }
531
532 void
533 gdk_draw_points (GdkDrawable *drawable,
534                  GdkGC       *gc,
535                  GdkPoint    *points,
536                  gint         npoints)
537 {
538   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
539   g_return_if_fail ((points != NULL) && (npoints > 0));
540   g_return_if_fail (GDK_IS_GC (gc));
541   g_return_if_fail (npoints >= 0);
542
543   if (npoints == 0)
544     return;
545
546   GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, points, npoints);
547 }
548
549 void
550 gdk_draw_segments (GdkDrawable *drawable,
551                    GdkGC       *gc,
552                    GdkSegment  *segs,
553                    gint         nsegs)
554 {
555   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
556
557   if (nsegs == 0)
558     return;
559
560   g_return_if_fail (segs != NULL);
561   g_return_if_fail (GDK_IS_GC (gc));
562   g_return_if_fail (nsegs >= 0);
563
564   GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc, segs, nsegs);
565 }
566
567 void
568 gdk_draw_lines (GdkDrawable *drawable,
569                 GdkGC       *gc,
570                 GdkPoint    *points,
571                 gint         npoints)
572 {
573
574   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
575   g_return_if_fail (points != NULL);
576   g_return_if_fail (GDK_IS_GC (gc));
577   g_return_if_fail (npoints >= 0);
578
579   if (npoints == 0)
580     return;
581
582   GDK_DRAWABLE_GET_CLASS (drawable)->draw_lines (drawable, gc, points, npoints);
583 }
584
585 /**
586  * gdk_draw_glyphs:
587  * @drawable: a #GdkDrawable
588  * @gc: a #GdkGC
589  * @font: font to be used
590  * @x: X coordinate of baseline origin
591  * @y: Y coordinate of baseline origin
592  * @glyphs: glyphs to render
593  *
594  * This is a low-level function; 99% of text rendering should be done
595  * using gdk_draw_layout() instead.
596  *
597  * A glyph is a character in a font. This function draws a sequence of
598  * glyphs.  To obtain a sequence of glyphs you have to understand a
599  * lot about internationalized text handling, which you don't want to
600  * understand; thus, use gdk_draw_layout() instead of this function,
601  * gdk_draw_layout() handles the details.
602  * 
603  **/
604 void
605 gdk_draw_glyphs (GdkDrawable      *drawable,
606                  GdkGC            *gc,
607                  PangoFont        *font,
608                  gint              x,
609                  gint              y,
610                  PangoGlyphString *glyphs)
611 {
612   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
613   g_return_if_fail (GDK_IS_GC (gc));
614
615
616   GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs (drawable, gc, font, x, y, glyphs);
617 }
618
619
620 /**
621  * gdk_drawable_get_image:
622  * @drawable: a #GdkDrawable
623  * @x: x coordinate on @drawable
624  * @y: y coordinate on @drawable
625  * @width: width of region to get
626  * @height: height or region to get
627  * 
628  * A #GdkImage stores client-side image data (pixels). In contrast,
629  * #GdkPixmap and #GdkWindow are server-side
630  * objects. gdk_drawable_get_image() obtains the pixels from a
631  * server-side drawable as a client-side #GdkImage.  The format of a
632  * #GdkImage depends on the #GdkVisual of the current display, which
633  * makes manipulating #GdkImage extremely difficult; therefore, in
634  * most cases you should use gdk_pixbuf_get_from_drawable() instead of
635  * this lower-level function. A #GdkPixbuf contains image data in a
636  * canonicalized RGB format, rather than a display-dependent format.
637  * Of course, there's a convenience vs. speed tradeoff here, so you'll
638  * want to think about what makes sense for your application.
639  *
640  * @x, @y, @width, and @height define the region of @drawable to
641  * obtain as an image.
642  *
643  * You would usually copy image data to the client side if you intend
644  * to examine the values of individual pixels, for example to darken
645  * an image or add a red tint. It would be prohibitively slow to
646  * make a round-trip request to the windowing system for each pixel,
647  * so instead you get all of them at once, modify them, then copy
648  * them all back at once.
649  *
650  * If the X server or other windowing system backend is on the local
651  * machine, this function may use shared memory to avoid copying
652  * the image data.
653  *
654  * If the source drawable is a #GdkWindow and partially offscreen
655  * or obscured, then the obscured portions of the returned image
656  * will contain undefined data.
657  * 
658  * Return value: a #GdkImage containing the contents of @drawable
659  **/
660 GdkImage*
661 gdk_drawable_get_image (GdkDrawable *drawable,
662                         gint         x,
663                         gint         y,
664                         gint         width,
665                         gint         height)
666 {
667   GdkDrawable *composite;
668   gint composite_x_offset = 0;
669   gint composite_y_offset = 0;
670   GdkImage *retval;
671   GdkColormap *cmap;
672   
673   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
674   g_return_val_if_fail (x >= 0, NULL);
675   g_return_val_if_fail (y >= 0, NULL);
676
677   /* FIXME? Note race condition since we get the size then
678    * get the image, and the size may have changed.
679    */
680   
681   if (width < 0 || height < 0)
682     gdk_drawable_get_size (drawable,
683                            width < 0 ? &width : NULL,
684                            height < 0 ? &height : NULL);
685   
686   composite =
687     GDK_DRAWABLE_GET_CLASS (drawable)->get_composite_drawable (drawable,
688                                                                x, y,
689                                                                width, height,
690                                                                &composite_x_offset,
691                                                                &composite_y_offset); 
692   
693   retval = GDK_DRAWABLE_GET_CLASS (composite)->get_image (composite,
694                                                           x - composite_x_offset,
695                                                           y - composite_y_offset,
696                                                           width, height);
697
698   g_object_unref (G_OBJECT (composite));
699
700   cmap = gdk_drawable_get_colormap (drawable);
701   
702   if (retval && cmap)
703     gdk_image_set_colormap (retval, cmap);
704   
705   return retval;
706 }
707
708 static GdkDrawable*
709 gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
710                                           gint         x,
711                                           gint         y,
712                                           gint         width,
713                                           gint         height,
714                                           gint        *composite_x_offset,
715                                           gint        *composite_y_offset)
716 {
717   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
718
719   *composite_x_offset = 0;
720   *composite_y_offset = 0;
721   
722   return GDK_DRAWABLE (g_object_ref (G_OBJECT (drawable)));
723 }
724
725 /**
726  * gdk_drawable_get_clip_region:
727  * @drawable: a #GdkDrawable
728  * 
729  * Computes the region of a drawable that potentially can be written
730  * to by drawing primitives. This region will not take into account
731  * the clip region for the GC, and may also not take into account
732  * other factors such as if the window is obscured by other windows,
733  * but no area outside of this region will be affected by drawing
734  * primitives.
735  * 
736  * Return value: a #GdkRegion. This must be freed with gdk_region_destroy()
737  *               when you are done.
738  **/
739 GdkRegion *
740 gdk_drawable_get_clip_region (GdkDrawable *drawable)
741 {
742   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
743
744   return GDK_DRAWABLE_GET_CLASS (drawable)->get_clip_region (drawable);
745 }
746
747 /**
748  * gdk_drawable_get_visible_region:
749  * @drawable: 
750  * 
751  * Computes the region of a drawable that is potentially visible.
752  * This does not necessarily take into account if the window is
753  * obscured by other windows, but no area outside of this region
754  * is visible.
755  * 
756  * Return value: a #GdkRegion. This must be freed with gdk_region_destroy()
757  *               when you are done.
758  **/
759 GdkRegion *
760 gdk_drawable_get_visible_region (GdkDrawable *drawable)
761 {
762   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
763
764   return GDK_DRAWABLE_GET_CLASS (drawable)->get_visible_region (drawable);
765 }
766
767 static GdkRegion *
768 gdk_drawable_real_get_visible_region (GdkDrawable *drawable)
769 {
770   GdkRectangle rect;
771
772   rect.x = 0;
773   rect.y = 0;
774
775   gdk_drawable_get_size (drawable, &rect.width, &rect.height);
776
777   return gdk_region_rectangle (&rect);
778 }