]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkdrawable-x11.c
Remove all references to offscreen flag which was no longer used.
[~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 Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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-1999.  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 <pango/pangox.h>
29
30 static void gdk_x11_drawable_destroy (GdkDrawable      *drawable);
31
32 static void gdk_x11_draw_rectangle   (GdkDrawable      *drawable,
33                                       GdkGC            *gc,
34                                       gint              filled,
35                                       gint              x,
36                                       gint              y,
37                                       gint              width,
38                                       gint              height);
39 static void gdk_x11_draw_arc         (GdkDrawable      *drawable,
40                                       GdkGC            *gc,
41                                       gint              filled,
42                                       gint              x,
43                                       gint              y,
44                                       gint              width,
45                                       gint              height,
46                                       gint              angle1,
47                                       gint              angle2);
48 static void gdk_x11_draw_polygon     (GdkDrawable      *drawable,
49                                       GdkGC            *gc,
50                                       gint              filled,
51                                       GdkPoint         *points,
52                                       gint              npoints);
53 static void gdk_x11_draw_text        (GdkDrawable      *drawable,
54                                       GdkFont          *font,
55                                       GdkGC            *gc,
56                                       gint              x,
57                                       gint              y,
58                                       const gchar      *text,
59                                       gint              text_length);
60 static void gdk_x11_draw_text_wc     (GdkDrawable      *drawable,
61                                       GdkFont          *font,
62                                       GdkGC            *gc,
63                                       gint              x,
64                                       gint              y,
65                                       const GdkWChar   *text,
66                                       gint              text_length);
67 static void gdk_x11_draw_drawable    (GdkDrawable      *drawable,
68                                       GdkGC            *gc,
69                                       GdkPixmap        *src,
70                                       gint              xsrc,
71                                       gint              ysrc,
72                                       gint              xdest,
73                                       gint              ydest,
74                                       gint              width,
75                                       gint              height);
76 static void gdk_x11_draw_points      (GdkDrawable      *drawable,
77                                       GdkGC            *gc,
78                                       GdkPoint         *points,
79                                       gint              npoints);
80 static void gdk_x11_draw_segments    (GdkDrawable      *drawable,
81                                       GdkGC            *gc,
82                                       GdkSegment       *segs,
83                                       gint              nsegs);
84 static void gdk_x11_draw_lines       (GdkDrawable      *drawable,
85                                       GdkGC            *gc,
86                                       GdkPoint         *points,
87                                       gint              npoints);
88 static void gdk_x11_draw_glyphs      (GdkDrawable      *drawable,
89                                       GdkGC            *gc,
90                                       PangoFont        *font,
91                                       gint              x,
92                                       gint              y,
93                                       PangoGlyphString *glyphs);
94
95 GdkDrawableClass _gdk_x11_drawable_class = {
96   gdk_x11_drawable_destroy,
97   _gdk_x11_gc_new,
98   gdk_x11_draw_rectangle,
99   gdk_x11_draw_arc,
100   gdk_x11_draw_polygon,
101   gdk_x11_draw_text,
102   gdk_x11_draw_text_wc,
103   gdk_x11_draw_drawable,
104   gdk_x11_draw_points,
105   gdk_x11_draw_segments,
106   gdk_x11_draw_lines,
107   gdk_x11_draw_glyphs,
108 };
109
110 /*****************************************************
111  * X11 specific implementations of generic functions *
112  *****************************************************/
113
114 GdkColormap*
115 gdk_drawable_get_colormap (GdkDrawable *drawable)
116 {
117   GdkDrawablePrivate *drawable_private;
118   XWindowAttributes window_attributes;
119   
120   g_return_val_if_fail (drawable != NULL, NULL);
121   drawable_private = (GdkDrawablePrivate*) drawable;
122   
123   if (!GDK_DRAWABLE_DESTROYED (drawable))
124     {
125       if (drawable_private->colormap == NULL &&
126           GDK_IS_WINDOW (drawable))
127         {
128           XGetWindowAttributes (GDK_DRAWABLE_XDISPLAY (drawable),
129                                 GDK_DRAWABLE_XID (drawable),
130                                 &window_attributes);
131           drawable_private->colormap =  gdk_colormap_lookup (window_attributes.colormap);
132         }
133
134       return drawable_private->colormap;
135     }
136   
137   return NULL;
138 }
139
140 void
141 gdk_drawable_set_colormap (GdkDrawable *drawable,
142                            GdkColormap *colormap)
143 {
144   GdkDrawablePrivate *drawable_private;
145   GdkColormapPrivateX *colormap_private;
146   
147   g_return_if_fail (drawable != NULL);
148   g_return_if_fail (colormap != NULL);
149   
150   drawable_private = (GdkDrawablePrivate *)drawable;
151   colormap_private = (GdkColormapPrivateX *)colormap;
152   
153   if (!GDK_DRAWABLE_DESTROYED (drawable))
154     {
155       if (GDK_IS_WINDOW (drawable))
156         {
157           g_return_if_fail (colormap_private->base.visual !=
158                             ((GdkColormapPrivate *)(drawable_private->colormap))->visual);
159
160           XSetWindowColormap (GDK_DRAWABLE_XDISPLAY (drawable),
161                               GDK_DRAWABLE_XID (drawable),
162                               colormap_private->xcolormap);
163         }
164
165       if (drawable_private->colormap)
166         gdk_colormap_unref (drawable_private->colormap);
167       drawable_private->colormap = colormap;
168       gdk_colormap_ref (drawable_private->colormap);
169
170       if (GDK_IS_WINDOW (drawable) &&
171           drawable_private->window_type != GDK_WINDOW_TOPLEVEL)
172         gdk_window_add_colormap_windows (drawable);
173     }
174 }
175
176 /* Drawing
177  */
178 static void 
179 gdk_x11_drawable_destroy (GdkDrawable *drawable)
180 {
181   
182 }
183
184 static void
185 gdk_x11_draw_rectangle (GdkDrawable *drawable,
186                         GdkGC       *gc,
187                         gint         filled,
188                         gint         x,
189                         gint         y,
190                         gint         width,
191                         gint         height)
192 {
193   if (filled)
194     XFillRectangle (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
195                     GDK_GC_GET_XGC (gc), x, y, width, height);
196   else
197     XDrawRectangle (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
198                     GDK_GC_GET_XGC (gc), x, y, width, height);
199 }
200
201 static void
202 gdk_x11_draw_arc (GdkDrawable *drawable,
203                   GdkGC       *gc,
204                   gint         filled,
205                   gint         x,
206                   gint         y,
207                   gint         width,
208                   gint         height,
209                   gint         angle1,
210                   gint         angle2)
211 {
212   if (filled)
213     XFillArc (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
214               GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
215   else
216     XDrawArc (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
217               GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
218 }
219
220 static void
221 gdk_x11_draw_polygon (GdkDrawable *drawable,
222                       GdkGC       *gc,
223                       gint         filled,
224                       GdkPoint    *points,
225                       gint         npoints)
226 {
227   XPoint *tmp_points;
228   gint tmp_npoints, i;
229
230   if (!filled &&
231       (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y))
232     {
233       tmp_npoints = npoints + 1;
234       tmp_points = g_new (XPoint, tmp_npoints);
235       tmp_points[npoints].x = points[0].x;
236       tmp_points[npoints].y = points[0].y;
237     }
238   else
239     {
240       tmp_npoints = npoints;
241       tmp_points = g_new (XPoint, tmp_npoints);
242     }
243
244   for (i=0; i<npoints; i++)
245     {
246       tmp_points[i].x = points[i].x;
247       tmp_points[i].y = points[i].y;
248     }
249   
250   if (filled)
251     XFillPolygon (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
252                   GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, Complex, CoordModeOrigin);
253   else
254     XDrawLines (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
255                 GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, CoordModeOrigin);
256
257   g_free (tmp_points);
258 }
259
260 /* gdk_x11_draw_text
261  *
262  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
263  *
264  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
265  */
266 static void
267 gdk_x11_draw_text (GdkDrawable *drawable,
268                    GdkFont     *font,
269                    GdkGC       *gc,
270                    gint         x,
271                    gint         y,
272                    const gchar *text,
273                    gint         text_length)
274 {
275   if (font->type == GDK_FONT_FONT)
276     {
277       XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
278       XSetFont(GDK_DRAWABLE_XDISPLAY (drawable), GDK_GC_GET_XGC (gc), xfont->fid);
279       if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
280         {
281           XDrawString (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
282                        GDK_GC_GET_XGC (gc), x, y, text, text_length);
283         }
284       else
285         {
286           XDrawString16 (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
287                          GDK_GC_GET_XGC (gc), x, y, (XChar2b *) text, text_length / 2);
288         }
289     }
290   else if (font->type == GDK_FONT_FONTSET)
291     {
292       XFontSet fontset = (XFontSet) GDK_FONT_XFONT (font);
293       XmbDrawString (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
294                      fontset, GDK_GC_GET_XGC (gc), x, y, text, text_length);
295     }
296   else
297     g_error("undefined font type\n");
298 }
299
300 static void
301 gdk_x11_draw_text_wc (GdkDrawable    *drawable,
302                       GdkFont        *font,
303                       GdkGC          *gc,
304                       gint            x,
305                       gint            y,
306                       const GdkWChar *text,
307                       gint            text_length)
308 {
309   if (font->type == GDK_FONT_FONT)
310     {
311       XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
312       gchar *text_8bit;
313       gint i;
314       XSetFont(GDK_DRAWABLE_XDISPLAY (drawable), GDK_GC_GET_XGC (gc), xfont->fid);
315       text_8bit = g_new (gchar, text_length);
316       for (i=0; i<text_length; i++) text_8bit[i] = text[i];
317       XDrawString (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
318                    GDK_GC_GET_XGC (gc), x, y, text_8bit, text_length);
319       g_free (text_8bit);
320     }
321   else if (font->type == GDK_FONT_FONTSET)
322     {
323       if (sizeof(GdkWChar) == sizeof(wchar_t))
324         {
325           XwcDrawString (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
326                          (XFontSet) GDK_FONT_XFONT (font),
327                          GDK_GC_GET_XGC (gc), x, y, (wchar_t *)text, text_length);
328         }
329       else
330         {
331           wchar_t *text_wchar;
332           gint i;
333           text_wchar = g_new (wchar_t, text_length);
334           for (i=0; i<text_length; i++) text_wchar[i] = text[i];
335           XwcDrawString (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
336                          (XFontSet) GDK_FONT_XFONT (font),
337                          GDK_GC_GET_XGC (gc), x, y, text_wchar, text_length);
338           g_free (text_wchar);
339         }
340     }
341   else
342     g_error("undefined font type\n");
343 }
344
345 static void
346 gdk_x11_draw_drawable (GdkDrawable *drawable,
347                        GdkGC       *gc,
348                        GdkPixmap   *src,
349                        gint         xsrc,
350                        gint         ysrc,
351                        gint         xdest,
352                        gint         ydest,
353                        gint         width,
354                        gint         height)
355 {
356   int src_depth = gdk_drawable_get_depth (src);
357   int dest_depth = gdk_drawable_get_depth (drawable);
358
359   if (src_depth == 1)
360     {
361       XCopyArea (GDK_DRAWABLE_XDISPLAY (drawable),
362                  GDK_DRAWABLE_XID (src),
363                  GDK_DRAWABLE_XID (drawable),
364                  GDK_GC_GET_XGC (gc),
365                  xsrc, ysrc,
366                  width, height,
367                  xdest, ydest);
368     }
369   else if (dest_depth != 0 && src_depth == dest_depth)
370     {
371       XCopyArea (GDK_DRAWABLE_XDISPLAY (drawable),
372                  GDK_DRAWABLE_XID (src),
373                  GDK_DRAWABLE_XID (drawable),
374                  GDK_GC_GET_XGC (gc),
375                  xsrc, ysrc,
376                  width, height,
377                  xdest, ydest);
378     }
379   else
380     g_warning ("Attempt to copy between drawables of mismatched depths!\n");
381 }
382
383 static void
384 gdk_x11_draw_points (GdkDrawable *drawable,
385                      GdkGC       *gc,
386                      GdkPoint    *points,
387                      gint         npoints)
388 {
389   /* We special-case npoints == 1, because X will merge multiple
390    * consecutive XDrawPoint requests into a PolyPoint request
391    */
392   if (npoints == 1)
393     {
394       XDrawPoint (GDK_DRAWABLE_XDISPLAY (drawable),
395                   GDK_DRAWABLE_XID (drawable),
396                   GDK_GC_GET_XGC (gc),
397                   points[0].x, points[0].y);
398     }
399   else
400     {
401       gint i;
402       XPoint *tmp_points = g_new (XPoint, npoints);
403
404       for (i=0; i<npoints; i++)
405         {
406           tmp_points[i].x = points[i].x;
407           tmp_points[i].y = points[i].y;
408         }
409       
410       XDrawPoints (GDK_DRAWABLE_XDISPLAY (drawable),
411                    GDK_DRAWABLE_XID (drawable),
412                    GDK_GC_GET_XGC (gc),
413                    tmp_points,
414                    npoints,
415                    CoordModeOrigin);
416
417       g_free (tmp_points);
418     }
419 }
420
421 static void
422 gdk_x11_draw_segments (GdkDrawable *drawable,
423                        GdkGC       *gc,
424                        GdkSegment  *segs,
425                        gint         nsegs)
426 {
427   /* We special-case nsegs == 1, because X will merge multiple
428    * consecutive XDrawLine requests into a PolySegment request
429    */
430   if (nsegs == 1)
431     {
432       XDrawLine (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable),
433                  GDK_GC_GET_XGC (gc), segs[0].x1, segs[0].y1,
434                  segs[0].x2, segs[0].y2);
435     }
436   else
437     {
438       gint i;
439       XSegment *tmp_segs = g_new (XSegment, nsegs);
440
441       for (i=0; i<nsegs; i++)
442         {
443           tmp_segs[i].x1 = segs[i].x1;
444           tmp_segs[i].x2 = segs[i].x2;
445           tmp_segs[i].y1 = segs[i].y1;
446           tmp_segs[i].y2 = segs[i].y2;
447         }
448       
449       XDrawSegments (GDK_DRAWABLE_XDISPLAY (drawable),
450                      GDK_DRAWABLE_XID (drawable),
451                      GDK_GC_GET_XGC (gc),
452                      tmp_segs, nsegs);
453
454       g_free (tmp_segs);
455     }
456 }
457
458 static void
459 gdk_x11_draw_lines (GdkDrawable *drawable,
460                     GdkGC       *gc,
461                     GdkPoint    *points,
462                     gint         npoints)
463 {
464   gint i;
465   XPoint *tmp_points = g_new (XPoint, npoints);
466
467   for (i=0; i<npoints; i++)
468     {
469       tmp_points[i].x = points[i].x;
470       tmp_points[i].y = points[i].y;
471     }
472       
473   XDrawLines (GDK_DRAWABLE_XDISPLAY (drawable),
474               GDK_DRAWABLE_XID (drawable),
475               GDK_GC_GET_XGC (gc),
476               tmp_points, npoints,
477               CoordModeOrigin);
478
479   g_free (tmp_points);
480 }
481
482 static void
483 gdk_x11_draw_glyphs (GdkDrawable      *drawable,
484                      GdkGC            *gc,
485                      PangoFont        *font,
486                      gint              x,
487                      gint              y,
488                      PangoGlyphString *glyphs)
489 {
490   pango_x_render (GDK_DRAWABLE_XDISPLAY (drawable),
491                   GDK_DRAWABLE_XID (drawable),
492                   GDK_GC_GET_XGC (gc),
493                   font, glyphs, x, y);
494 }