]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkdrawable-x11.c
Add two virtualized functions gdk_drawable_get_clip_region - to get the
[~andy/gtk] / gdk / x11 / gdkdrawable-x11.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 "gdkprivate-x11.h"
28 #include "gdkregion-generic.h"
29
30 #include <pango/pangox.h>
31 #include <config.h>
32
33 #if HAVE_XFT
34 #include <pango/pangoxft.h>
35 #endif
36
37 #include <stdlib.h>
38
39 #if defined (HAVE_IPC_H) && defined (HAVE_SHM_H) && defined (HAVE_XSHM_H)
40 #define USE_SHM
41 #endif
42
43 #ifdef USE_SHM
44 #include <X11/extensions/XShm.h>
45 #endif /* USE_SHM */
46
47 #include "gdkprivate-x11.h"
48 #include "gdkdrawable-x11.h"
49 #include "gdkpixmap-x11.h"
50
51 static void gdk_x11_draw_rectangle (GdkDrawable    *drawable,
52                                     GdkGC          *gc,
53                                     gint            filled,
54                                     gint            x,
55                                     gint            y,
56                                     gint            width,
57                                     gint            height);
58 static void gdk_x11_draw_arc       (GdkDrawable    *drawable,
59                                     GdkGC          *gc,
60                                     gint            filled,
61                                     gint            x,
62                                     gint            y,
63                                     gint            width,
64                                     gint            height,
65                                     gint            angle1,
66                                     gint            angle2);
67 static void gdk_x11_draw_polygon   (GdkDrawable    *drawable,
68                                     GdkGC          *gc,
69                                     gint            filled,
70                                     GdkPoint       *points,
71                                     gint            npoints);
72 static void gdk_x11_draw_text      (GdkDrawable    *drawable,
73                                     GdkFont        *font,
74                                     GdkGC          *gc,
75                                     gint            x,
76                                     gint            y,
77                                     const gchar    *text,
78                                     gint            text_length);
79 static void gdk_x11_draw_text_wc   (GdkDrawable    *drawable,
80                                     GdkFont        *font,
81                                     GdkGC          *gc,
82                                     gint            x,
83                                     gint            y,
84                                     const GdkWChar *text,
85                                     gint            text_length);
86 static void gdk_x11_draw_drawable  (GdkDrawable    *drawable,
87                                     GdkGC          *gc,
88                                     GdkPixmap      *src,
89                                     gint            xsrc,
90                                     gint            ysrc,
91                                     gint            xdest,
92                                     gint            ydest,
93                                     gint            width,
94                                     gint            height);
95 static void gdk_x11_draw_points    (GdkDrawable    *drawable,
96                                     GdkGC          *gc,
97                                     GdkPoint       *points,
98                                     gint            npoints);
99 static void gdk_x11_draw_segments  (GdkDrawable    *drawable,
100                                     GdkGC          *gc,
101                                     GdkSegment     *segs,
102                                     gint            nsegs);
103 static void gdk_x11_draw_lines     (GdkDrawable    *drawable,
104                                     GdkGC          *gc,
105                                     GdkPoint       *points,
106                                     gint            npoints);
107 static void gdk_x11_draw_glyphs    (GdkDrawable      *drawable,
108                                     GdkGC            *gc,
109                                     PangoFont        *font,
110                                     gint              x,
111                                     gint              y,
112                                     PangoGlyphString *glyphs);
113 static void gdk_x11_draw_image     (GdkDrawable     *drawable,
114                                     GdkGC           *gc,
115                                     GdkImage        *image,
116                                     gint             xsrc,
117                                     gint             ysrc,
118                                     gint             xdest,
119                                     gint             ydest,
120                                     gint             width,
121                                     gint             height);
122
123 static void gdk_x11_set_colormap   (GdkDrawable    *drawable,
124                                     GdkColormap    *colormap);
125
126 static GdkColormap* gdk_x11_get_colormap   (GdkDrawable    *drawable);
127
128 static gint         gdk_x11_get_depth      (GdkDrawable    *drawable);
129
130 static GdkVisual*   gdk_x11_get_visual     (GdkDrawable    *drawable);
131
132 static void gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass);
133
134 static gpointer parent_class = NULL;
135
136 GType
137 gdk_drawable_impl_x11_get_type (void)
138 {
139   static GType object_type = 0;
140
141   if (!object_type)
142     {
143       static const GTypeInfo object_info =
144       {
145         sizeof (GdkDrawableImplX11Class),
146         (GBaseInitFunc) NULL,
147         (GBaseFinalizeFunc) NULL,
148         (GClassInitFunc) gdk_drawable_impl_x11_class_init,
149         NULL,           /* class_finalize */
150         NULL,           /* class_data */
151         sizeof (GdkDrawableImplX11),
152         0,              /* n_preallocs */
153         (GInstanceInitFunc) NULL,
154       };
155       
156       object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
157                                             "GdkDrawableImplX11",
158                                             &object_info, 0);
159     }
160   
161   return object_type;
162 }
163
164 static void
165 gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
166 {
167   GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
168
169   parent_class = g_type_class_peek_parent (klass);
170
171   drawable_class->create_gc = _gdk_x11_gc_new;
172   drawable_class->draw_rectangle = gdk_x11_draw_rectangle;
173   drawable_class->draw_arc = gdk_x11_draw_arc;
174   drawable_class->draw_polygon = gdk_x11_draw_polygon;
175   drawable_class->draw_text = gdk_x11_draw_text;
176   drawable_class->draw_text_wc = gdk_x11_draw_text_wc;
177   drawable_class->draw_drawable = gdk_x11_draw_drawable;
178   drawable_class->draw_points = gdk_x11_draw_points;
179   drawable_class->draw_segments = gdk_x11_draw_segments;
180   drawable_class->draw_lines = gdk_x11_draw_lines;
181   drawable_class->draw_glyphs = gdk_x11_draw_glyphs;
182   drawable_class->draw_image = gdk_x11_draw_image;
183   
184   drawable_class->set_colormap = gdk_x11_set_colormap;
185   drawable_class->get_colormap = gdk_x11_get_colormap;
186
187   drawable_class->get_depth = gdk_x11_get_depth;
188   drawable_class->get_visual = gdk_x11_get_visual;
189   
190   drawable_class->get_image = _gdk_x11_get_image;
191 }
192
193 /*****************************************************
194  * X11 specific implementations of generic functions *
195  *****************************************************/
196
197 static GdkColormap*
198 gdk_x11_get_colormap (GdkDrawable *drawable)
199 {
200   GdkDrawableImplX11 *impl;
201
202   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
203
204   return impl->colormap;
205 }
206
207 static void
208 gdk_x11_set_colormap (GdkDrawable *drawable,
209                       GdkColormap *colormap)
210 {
211   GdkDrawableImplX11 *impl;
212   
213   g_return_if_fail (colormap != NULL);  
214
215   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
216
217   if (impl->colormap == colormap)
218     return;
219   
220   if (impl->colormap)
221     gdk_colormap_unref (impl->colormap);
222   impl->colormap = colormap;
223   if (impl->colormap)
224     gdk_colormap_ref (impl->colormap);
225 }
226
227 /* Drawing
228  */
229
230 static void
231 gdk_x11_draw_rectangle (GdkDrawable *drawable,
232                         GdkGC       *gc,
233                         gint         filled,
234                         gint         x,
235                         gint         y,
236                         gint         width,
237                         gint         height)
238 {
239   GdkDrawableImplX11 *impl;
240
241   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
242   
243   if (filled)
244     XFillRectangle (impl->xdisplay, impl->xid,
245                     GDK_GC_GET_XGC (gc), x, y, width, height);
246   else
247     XDrawRectangle (impl->xdisplay, impl->xid,
248                     GDK_GC_GET_XGC (gc), x, y, width, height);
249 }
250
251 static void
252 gdk_x11_draw_arc (GdkDrawable *drawable,
253                   GdkGC       *gc,
254                   gint         filled,
255                   gint         x,
256                   gint         y,
257                   gint         width,
258                   gint         height,
259                   gint         angle1,
260                   gint         angle2)
261 {
262   GdkDrawableImplX11 *impl;
263
264   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
265
266   
267   if (filled)
268     XFillArc (impl->xdisplay, impl->xid,
269               GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
270   else
271     XDrawArc (impl->xdisplay, impl->xid,
272               GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
273 }
274
275 static void
276 gdk_x11_draw_polygon (GdkDrawable *drawable,
277                       GdkGC       *gc,
278                       gint         filled,
279                       GdkPoint    *points,
280                       gint         npoints)
281 {
282   XPoint *tmp_points;
283   gint tmp_npoints, i;
284   GdkDrawableImplX11 *impl;
285
286   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
287
288   
289   if (!filled &&
290       (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y))
291     {
292       tmp_npoints = npoints + 1;
293       tmp_points = g_new (XPoint, tmp_npoints);
294       tmp_points[npoints].x = points[0].x;
295       tmp_points[npoints].y = points[0].y;
296     }
297   else
298     {
299       tmp_npoints = npoints;
300       tmp_points = g_new (XPoint, tmp_npoints);
301     }
302
303   for (i=0; i<npoints; i++)
304     {
305       tmp_points[i].x = points[i].x;
306       tmp_points[i].y = points[i].y;
307     }
308   
309   if (filled)
310     XFillPolygon (impl->xdisplay, impl->xid,
311                   GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, Complex, CoordModeOrigin);
312   else
313     XDrawLines (impl->xdisplay, impl->xid,
314                 GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, CoordModeOrigin);
315
316   g_free (tmp_points);
317 }
318
319 /* gdk_x11_draw_text
320  *
321  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
322  *
323  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
324  */
325 static void
326 gdk_x11_draw_text (GdkDrawable *drawable,
327                    GdkFont     *font,
328                    GdkGC       *gc,
329                    gint         x,
330                    gint         y,
331                    const gchar *text,
332                    gint         text_length)
333 {
334   GdkDrawableImplX11 *impl;
335
336   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
337   
338   if (font->type == GDK_FONT_FONT)
339     {
340       XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
341       XSetFont(impl->xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
342       if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
343         {
344           XDrawString (impl->xdisplay, impl->xid,
345                        GDK_GC_GET_XGC (gc), x, y, text, text_length);
346         }
347       else
348         {
349           XDrawString16 (impl->xdisplay, impl->xid,
350                          GDK_GC_GET_XGC (gc), x, y, (XChar2b *) text, text_length / 2);
351         }
352     }
353   else if (font->type == GDK_FONT_FONTSET)
354     {
355       XFontSet fontset = (XFontSet) GDK_FONT_XFONT (font);
356       XmbDrawString (impl->xdisplay, impl->xid,
357                      fontset, GDK_GC_GET_XGC (gc), x, y, text, text_length);
358     }
359   else
360     g_error("undefined font type\n");
361 }
362
363 static void
364 gdk_x11_draw_text_wc (GdkDrawable    *drawable,
365                       GdkFont        *font,
366                       GdkGC          *gc,
367                       gint            x,
368                       gint            y,
369                       const GdkWChar *text,
370                       gint            text_length)
371 {
372   GdkDrawableImplX11 *impl;
373
374   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
375   
376   if (font->type == GDK_FONT_FONT)
377     {
378       XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
379       gchar *text_8bit;
380       gint i;
381       XSetFont(impl->xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
382       text_8bit = g_new (gchar, text_length);
383       for (i=0; i<text_length; i++) text_8bit[i] = text[i];
384       XDrawString (impl->xdisplay, impl->xid,
385                    GDK_GC_GET_XGC (gc), x, y, text_8bit, text_length);
386       g_free (text_8bit);
387     }
388   else if (font->type == GDK_FONT_FONTSET)
389     {
390       if (sizeof(GdkWChar) == sizeof(wchar_t))
391         {
392           XwcDrawString (impl->xdisplay, impl->xid,
393                          (XFontSet) GDK_FONT_XFONT (font),
394                          GDK_GC_GET_XGC (gc), x, y, (wchar_t *)text, text_length);
395         }
396       else
397         {
398           wchar_t *text_wchar;
399           gint i;
400           text_wchar = g_new (wchar_t, text_length);
401           for (i=0; i<text_length; i++) text_wchar[i] = text[i];
402           XwcDrawString (impl->xdisplay, impl->xid,
403                          (XFontSet) GDK_FONT_XFONT (font),
404                          GDK_GC_GET_XGC (gc), x, y, text_wchar, text_length);
405           g_free (text_wchar);
406         }
407     }
408   else
409     g_error("undefined font type\n");
410 }
411
412 static void
413 gdk_x11_draw_drawable (GdkDrawable *drawable,
414                        GdkGC       *gc,
415                        GdkPixmap   *src,
416                        gint         xsrc,
417                        gint         ysrc,
418                        gint         xdest,
419                        gint         ydest,
420                        gint         width,
421                        gint         height)
422 {
423   int src_depth = gdk_drawable_get_depth (src);
424   int dest_depth = gdk_drawable_get_depth (drawable);
425   GdkDrawableImplX11 *impl;
426   GdkDrawableImplX11 *src_impl;
427   
428   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
429
430   if (GDK_IS_DRAWABLE_IMPL_X11 (src))
431     src_impl = GDK_DRAWABLE_IMPL_X11 (src);
432   else
433     src_impl = NULL;
434   
435   if (src_depth == 1)
436     {
437       XCopyArea (impl->xdisplay,
438                  src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src),
439                  impl->xid,
440                  GDK_GC_GET_XGC (gc),
441                  xsrc, ysrc,
442                  width, height,
443                  xdest, ydest);
444     }
445   else if (dest_depth != 0 && src_depth == dest_depth)
446     {
447       XCopyArea (impl->xdisplay,
448                  src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src),
449                  impl->xid,
450                  GDK_GC_GET_XGC (gc),
451                  xsrc, ysrc,
452                  width, height,
453                  xdest, ydest);
454     }
455   else
456     g_warning ("Attempt to draw a drawable with depth %d to a drawable with depth %d",
457                src_depth, dest_depth);
458 }
459
460 static void
461 gdk_x11_draw_points (GdkDrawable *drawable,
462                      GdkGC       *gc,
463                      GdkPoint    *points,
464                      gint         npoints)
465 {
466   GdkDrawableImplX11 *impl;
467
468   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
469
470   
471   /* We special-case npoints == 1, because X will merge multiple
472    * consecutive XDrawPoint requests into a PolyPoint request
473    */
474   if (npoints == 1)
475     {
476       XDrawPoint (impl->xdisplay,
477                   impl->xid,
478                   GDK_GC_GET_XGC (gc),
479                   points[0].x, points[0].y);
480     }
481   else
482     {
483       gint i;
484       XPoint *tmp_points = g_new (XPoint, npoints);
485
486       for (i=0; i<npoints; i++)
487         {
488           tmp_points[i].x = points[i].x;
489           tmp_points[i].y = points[i].y;
490         }
491       
492       XDrawPoints (impl->xdisplay,
493                    impl->xid,
494                    GDK_GC_GET_XGC (gc),
495                    tmp_points,
496                    npoints,
497                    CoordModeOrigin);
498
499       g_free (tmp_points);
500     }
501 }
502
503 static void
504 gdk_x11_draw_segments (GdkDrawable *drawable,
505                        GdkGC       *gc,
506                        GdkSegment  *segs,
507                        gint         nsegs)
508 {
509   GdkDrawableImplX11 *impl;
510
511   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
512
513   
514   /* We special-case nsegs == 1, because X will merge multiple
515    * consecutive XDrawLine requests into a PolySegment request
516    */
517   if (nsegs == 1)
518     {
519       XDrawLine (impl->xdisplay, impl->xid,
520                  GDK_GC_GET_XGC (gc), segs[0].x1, segs[0].y1,
521                  segs[0].x2, segs[0].y2);
522     }
523   else
524     {
525       gint i;
526       XSegment *tmp_segs = g_new (XSegment, nsegs);
527
528       for (i=0; i<nsegs; i++)
529         {
530           tmp_segs[i].x1 = segs[i].x1;
531           tmp_segs[i].x2 = segs[i].x2;
532           tmp_segs[i].y1 = segs[i].y1;
533           tmp_segs[i].y2 = segs[i].y2;
534         }
535       
536       XDrawSegments (impl->xdisplay,
537                      impl->xid,
538                      GDK_GC_GET_XGC (gc),
539                      tmp_segs, nsegs);
540
541       g_free (tmp_segs);
542     }
543 }
544
545 static void
546 gdk_x11_draw_lines (GdkDrawable *drawable,
547                     GdkGC       *gc,
548                     GdkPoint    *points,
549                     gint         npoints)
550 {
551   gint i;
552   XPoint *tmp_points = g_new (XPoint, npoints);
553   GdkDrawableImplX11 *impl;
554
555   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
556
557   
558   for (i=0; i<npoints; i++)
559     {
560       tmp_points[i].x = points[i].x;
561       tmp_points[i].y = points[i].y;
562     }
563       
564   XDrawLines (impl->xdisplay,
565               impl->xid,
566               GDK_GC_GET_XGC (gc),
567               tmp_points, npoints,
568               CoordModeOrigin);
569
570   g_free (tmp_points);
571 }
572
573 #if HAVE_XFT
574 static void
575 update_xft_draw_clip (GdkGC *gc)
576 {
577   GdkGCX11 *private = GDK_GC_X11 (gc);
578   int i;
579   
580   if (private->xft_draw)
581     {
582       if (private->clip_region)
583         {
584           GdkRegionBox *boxes = private->clip_region->rects;
585           Region region = XCreateRegion ();
586           
587           for (i=0; i<private->clip_region->numRects; i++)
588             {
589               XRectangle rect;
590               
591               rect.x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
592               rect.y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
593               rect.width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rect.x;
594               rect.height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rect.y;
595               XUnionRectWithRegion (&rect, region, region);
596             }
597           
598           XftDrawSetClip (private->xft_draw, region);
599           XDestroyRegion (region);
600         }
601       else
602         XftDrawSetClip (private->xft_draw, NULL);
603     }
604 }
605 #endif  
606
607 static void
608 gdk_x11_draw_glyphs (GdkDrawable      *drawable,
609                      GdkGC            *gc,
610                      PangoFont        *font,
611                      gint              x,
612                      gint              y,
613                      PangoGlyphString *glyphs)
614 {
615   GdkDrawableImplX11 *impl;
616
617   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
618
619 #if HAVE_XFT
620   if (PANGO_XFT_IS_FONT (font))
621     {
622       GdkGCX11 *gc_x11 = GDK_GC_X11 (gc);
623       XftColor xft_color;
624       GdkColormap *cmap;
625       GdkColor color;
626       
627       cmap = gdk_gc_get_colormap (gc);
628
629       _gdk_x11_gc_flush (gc);
630       
631       if (!gc_x11->xft_draw)
632         {
633           gc_x11->xft_draw = XftDrawCreate (impl->xdisplay,
634                                             impl->xid,
635                                             GDK_VISUAL_XVISUAL (gdk_colormap_get_visual (cmap)),
636                                             GDK_COLORMAP_XCOLORMAP (cmap));
637           update_xft_draw_clip (gc);
638         }
639       
640       else
641         {
642           XftDrawChange (gc_x11->xft_draw, impl->xid);
643           update_xft_draw_clip (gc);
644         }
645       
646       gdk_colormap_query_color (cmap, gc_x11->fg_pixel, &color);
647       
648       xft_color.color.red = color.red;
649       xft_color.color.green = color.green;
650       xft_color.color.blue = color.blue;
651       xft_color.color.alpha = 0xffff;
652       
653       pango_xft_render (gc_x11->xft_draw, &xft_color,
654                         font, glyphs, x, y);
655     }
656   else
657 #endif  /* !HAVE_XFT */
658     pango_x_render (impl->xdisplay,
659                     impl->xid,
660                     GDK_GC_GET_XGC (gc),
661                     font, glyphs, x, y);
662 }
663
664 static void
665 gdk_x11_draw_image     (GdkDrawable     *drawable,
666                         GdkGC           *gc,
667                         GdkImage        *image,
668                         gint             xsrc,
669                         gint             ysrc,
670                         gint             xdest,
671                         gint             ydest,
672                         gint             width,
673                         gint             height)
674 {
675   GdkDrawableImplX11 *impl;
676   
677   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
678
679   if (image->type == GDK_IMAGE_SHARED)
680     XShmPutImage (impl->xdisplay, impl->xid,
681                   GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image),
682                   xsrc, ysrc, xdest, ydest, width, height, False);
683   else
684     XPutImage (impl->xdisplay, impl->xid,
685                GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image),
686                xsrc, ysrc, xdest, ydest, width, height);
687 }
688
689 static gint
690 gdk_x11_get_depth (GdkDrawable *drawable)
691 {
692   /* This is a bit bogus but I'm not sure the other way is better */
693
694   return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
695 }
696
697 static GdkVisual*
698 gdk_x11_get_visual (GdkDrawable    *drawable)
699 {
700   return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
701 }