]> Pileus Git - ~andy/gtk/blob - gdk/gdkgc.c
Initial client-side-windows work
[~andy/gtk] / gdk / gdkgc.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 "config.h"
28 #include <string.h>
29
30 #include "gdkcairo.h"
31 #include "gdkgc.h"
32 #include "gdkinternals.h"
33 #include "gdkpixmap.h"
34 #include "gdkrgb.h"
35 #include "gdkprivate.h"
36 #include "gdkalias.h"
37
38 static void gdk_gc_finalize   (GObject      *object);
39
40 typedef struct _GdkGCPrivate GdkGCPrivate;
41
42 struct _GdkGCPrivate
43 {
44   GdkRegion *clip_region;
45
46   GdkSubwindowMode subwindow_mode;
47   
48   GdkFill fill;
49   GdkBitmap *stipple;
50   GdkPixmap *tile;
51   
52   guint32 fg_pixel;
53   guint32 bg_pixel;
54 };
55
56 #define GDK_GC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_GC, GdkGCPrivate))
57
58 G_DEFINE_TYPE (GdkGC, gdk_gc, G_TYPE_OBJECT)
59
60 static void
61 gdk_gc_class_init (GdkGCClass *class)
62 {
63   GObjectClass *object_class = G_OBJECT_CLASS (class);
64   
65   object_class->finalize = gdk_gc_finalize;
66
67   g_type_class_add_private (object_class, sizeof (GdkGCPrivate));
68 }
69
70 static void
71 gdk_gc_init (GdkGC *gc)
72 {
73   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
74
75   priv->fill = GDK_SOLID;
76
77   /* These are the default X11 value, which we match. They are clearly
78    * wrong for TrueColor displays, so apps have to change them.
79    */
80   priv->fg_pixel = 0;
81   priv->bg_pixel = 1;
82 }
83
84 /**
85  * gdk_gc_new:
86  * @drawable: a #GdkDrawable. The created GC must always be used
87  *   with drawables of the same depth as this one.
88  *
89  * Create a new graphics context with default values. 
90  *
91  * Returns: the new graphics context.
92  **/
93 GdkGC*
94 gdk_gc_new (GdkDrawable *drawable)
95 {
96   g_return_val_if_fail (drawable != NULL, NULL);
97
98   return gdk_gc_new_with_values (drawable, NULL, 0);
99 }
100
101 /**
102  * gdk_gc_new_with_values:
103  * @drawable: a #GdkDrawable. The created GC must always be used
104  *   with drawables of the same depth as this one.
105  * @values: a structure containing initial values for the GC.
106  * @values_mask: a bit mask indicating which fields in @values
107  *   are set.
108  * 
109  * Create a new GC with the given initial values.
110  * 
111  * Return value: the new graphics context.
112  **/
113 GdkGC*
114 gdk_gc_new_with_values (GdkDrawable     *drawable,
115                         GdkGCValues     *values,
116                         GdkGCValuesMask  values_mask)
117 {
118   g_return_val_if_fail (drawable != NULL, NULL);
119
120   return GDK_DRAWABLE_GET_CLASS (drawable)->create_gc (drawable,
121                                                        values,
122                                                        values_mask);
123 }
124
125 /**
126  * _gdk_gc_init:
127  * @gc: a #GdkGC
128  * @drawable: a #GdkDrawable.
129  * @values: a structure containing initial values for the GC.
130  * @values_mask: a bit mask indicating which fields in @values
131  *   are set.
132  * 
133  * Does initialization of the generic portions of a #GdkGC
134  * created with the specified values and values_mask. This
135  * should be called out of the implementation of
136  * GdkDrawable.create_gc() immediately after creating the
137  * #GdkGC object.
138  **/
139 void
140 _gdk_gc_init (GdkGC           *gc,
141               GdkDrawable     *drawable,
142               GdkGCValues     *values,
143               GdkGCValuesMask  values_mask)
144 {
145   GdkGCPrivate *priv;
146
147   g_return_if_fail (GDK_IS_GC (gc));
148
149   priv = GDK_GC_GET_PRIVATE (gc);
150
151   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
152     gc->clip_x_origin = values->clip_x_origin;
153   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
154     gc->clip_y_origin = values->clip_y_origin;
155   if (values_mask & GDK_GC_TS_X_ORIGIN)
156     gc->ts_x_origin = values->ts_x_origin;
157   if (values_mask & GDK_GC_TS_Y_ORIGIN)
158     gc->ts_y_origin = values->ts_y_origin;
159   if (values_mask & GDK_GC_FILL)
160     priv->fill = values->fill;
161   if (values_mask & GDK_GC_STIPPLE)
162     {
163       priv->stipple = values->stipple;
164       if (priv->stipple)
165         g_object_ref (priv->stipple);
166     }
167   if (values_mask & GDK_GC_TILE)
168     {
169       priv->tile = values->tile;
170       if (priv->tile)
171         g_object_ref (priv->tile);
172     }
173   if (values_mask & GDK_GC_FOREGROUND)
174     priv->fg_pixel = values->foreground.pixel;
175   if (values_mask & GDK_GC_BACKGROUND)
176     priv->bg_pixel = values->background.pixel;
177   if (values_mask & GDK_GC_SUBWINDOW)
178     priv->subwindow_mode = values->subwindow_mode;
179
180   gc->colormap = gdk_drawable_get_colormap (drawable);
181   if (gc->colormap)
182     g_object_ref (gc->colormap);
183 }
184
185 static void
186 gdk_gc_finalize (GObject *object)
187 {
188   GdkGC *gc = GDK_GC (object);
189   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
190
191   if (priv->clip_region)
192     gdk_region_destroy (priv->clip_region);
193   if (gc->colormap)
194     g_object_unref (gc->colormap);
195   if (priv->tile)
196     g_object_unref (priv->tile);
197   if (priv->stipple)
198     g_object_unref (priv->stipple);
199
200   G_OBJECT_CLASS (gdk_gc_parent_class)->finalize (object);
201 }
202
203 /**
204  * gdk_gc_ref:
205  * @gc: a #GdkGC
206  *
207  * Deprecated function; use g_object_ref() instead.
208  *
209  * Return value: the gc.
210  **/
211 GdkGC *
212 gdk_gc_ref (GdkGC *gc)
213 {
214   return (GdkGC *) g_object_ref (gc);
215 }
216
217 /**
218  * gdk_gc_unref:
219  * @gc: a #GdkGC
220  *
221  * Decrement the reference count of @gc.
222  *
223  * Deprecated: Use g_object_unref() instead.
224  **/
225 void
226 gdk_gc_unref (GdkGC *gc)
227 {
228   g_object_unref (gc);
229 }
230
231 /**
232  * gdk_gc_get_values:
233  * @gc:  a #GdkGC.
234  * @values: the #GdkGCValues structure in which to store the results.
235  * 
236  * Retrieves the current values from a graphics context. Note that 
237  * only the pixel values of the @values->foreground and @values->background
238  * are filled, use gdk_colormap_query_color() to obtain the rgb values
239  * if you need them.
240  **/
241 void
242 gdk_gc_get_values (GdkGC       *gc,
243                    GdkGCValues *values)
244 {
245   g_return_if_fail (GDK_IS_GC (gc));
246   g_return_if_fail (values != NULL);
247
248   GDK_GC_GET_CLASS (gc)->get_values (gc, values);
249 }
250
251 /**
252  * gdk_gc_set_values:
253  * @gc: a #GdkGC
254  * @values: struct containing the new values
255  * @values_mask: mask indicating which struct fields are to be used
256  *
257  * Sets attributes of a graphics context in bulk. For each flag set in
258  * @values_mask, the corresponding field will be read from @values and
259  * set as the new value for @gc. If you're only setting a few values
260  * on @gc, calling individual "setter" functions is likely more
261  * convenient.
262  * 
263  **/
264 void
265 gdk_gc_set_values (GdkGC           *gc,
266                    GdkGCValues     *values,
267                    GdkGCValuesMask  values_mask)
268 {
269   GdkGCPrivate *priv;
270
271   g_return_if_fail (GDK_IS_GC (gc));
272   g_return_if_fail (values != NULL);
273
274   priv = GDK_GC_GET_PRIVATE (gc);
275
276   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
277     gc->clip_x_origin = values->clip_x_origin;
278   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
279     gc->clip_y_origin = values->clip_y_origin;
280   if (values_mask & GDK_GC_TS_X_ORIGIN)
281     gc->ts_x_origin = values->ts_x_origin;
282   if (values_mask & GDK_GC_TS_Y_ORIGIN)
283     gc->ts_y_origin = values->ts_y_origin;
284   if (values_mask & GDK_GC_CLIP_MASK)
285     {
286       if (priv->clip_region)
287         {
288           gdk_region_destroy (priv->clip_region);
289           priv->clip_region = NULL;
290         }
291     }
292   if (values_mask & GDK_GC_FILL)
293     priv->fill = values->fill;
294   if (values_mask & GDK_GC_STIPPLE)
295     {
296       if (priv->stipple != values->stipple)
297         {
298           if (priv->stipple)
299             g_object_unref (priv->stipple);
300           priv->stipple = values->stipple;
301           if (priv->stipple)
302             g_object_ref (priv->stipple);
303         }
304     }
305   if (values_mask & GDK_GC_TILE)
306     {
307       if (priv->tile != values->tile)
308         {
309           if (priv->tile)
310             g_object_unref (priv->tile);
311           priv->tile = values->tile;
312           if (priv->tile)
313             g_object_ref (priv->tile);
314         }
315     }
316   if (values_mask & GDK_GC_FOREGROUND)
317     priv->fg_pixel = values->foreground.pixel;
318   if (values_mask & GDK_GC_BACKGROUND)
319     priv->bg_pixel = values->background.pixel;
320   if (values_mask & GDK_GC_SUBWINDOW)
321     priv->subwindow_mode = values->subwindow_mode;
322   
323   GDK_GC_GET_CLASS (gc)->set_values (gc, values, values_mask);
324 }
325
326 /**
327  * gdk_gc_set_foreground:
328  * @gc: a #GdkGC.
329  * @color: the new foreground color.
330  * 
331  * Sets the foreground color for a graphics context.
332  * Note that this function uses @color->pixel, use 
333  * gdk_gc_set_rgb_fg_color() to specify the foreground 
334  * color as red, green, blue components.
335  **/
336 void
337 gdk_gc_set_foreground (GdkGC          *gc,
338                        const GdkColor *color)
339 {
340   GdkGCValues values;
341
342   g_return_if_fail (GDK_IS_GC (gc));
343   g_return_if_fail (color != NULL);
344
345   values.foreground = *color;
346   gdk_gc_set_values (gc, &values, GDK_GC_FOREGROUND);
347 }
348
349 /**
350  * gdk_gc_set_background:
351  * @gc: a #GdkGC.
352  * @color: the new background color.
353  * 
354  * Sets the background color for a graphics context.
355  * Note that this function uses @color->pixel, use 
356  * gdk_gc_set_rgb_bg_color() to specify the background 
357  * color as red, green, blue components.
358  **/
359 void
360 gdk_gc_set_background (GdkGC          *gc,
361                        const GdkColor *color)
362 {
363   GdkGCValues values;
364
365   g_return_if_fail (GDK_IS_GC (gc));
366   g_return_if_fail (color != NULL);
367
368   values.background = *color;
369   gdk_gc_set_values (gc, &values, GDK_GC_BACKGROUND);
370 }
371
372 /**
373  * gdk_gc_set_font:
374  * @gc: a #GdkGC.
375  * @font: the new font. 
376  * 
377  * Sets the font for a graphics context. (Note that
378  * all text-drawing functions in GDK take a @font
379  * argument; the value set here is used when that
380  * argument is %NULL.)
381  **/
382 void
383 gdk_gc_set_font (GdkGC   *gc,
384                  GdkFont *font)
385 {
386   GdkGCValues values;
387
388   g_return_if_fail (GDK_IS_GC (gc));
389   g_return_if_fail (font != NULL);
390
391   values.font = font;
392   gdk_gc_set_values (gc, &values, GDK_GC_FONT);
393 }
394
395 /**
396  * gdk_gc_set_function:
397  * @gc: a #GdkGC.
398  * @function: the #GdkFunction to use
399  * 
400  * Determines how the current pixel values and the
401  * pixel values being drawn are combined to produce
402  * the final pixel values.
403  **/
404 void
405 gdk_gc_set_function (GdkGC       *gc,
406                      GdkFunction  function)
407 {
408   GdkGCValues values;
409
410   g_return_if_fail (GDK_IS_GC (gc));
411
412   values.function = function;
413   gdk_gc_set_values (gc, &values, GDK_GC_FUNCTION);
414 }
415
416 /**
417  * gdk_gc_set_fill:
418  * @gc: a #GdkGC.
419  * @fill: the new fill mode.
420  * 
421  * Set the fill mode for a graphics context.
422  **/
423 void
424 gdk_gc_set_fill (GdkGC   *gc,
425                  GdkFill  fill)
426 {
427   GdkGCValues values;
428
429   g_return_if_fail (GDK_IS_GC (gc));
430
431   values.fill = fill;
432   gdk_gc_set_values (gc, &values, GDK_GC_FILL);
433 }
434
435 /**
436  * gdk_gc_set_tile:
437  * @gc:  a #GdkGC.
438  * @tile:  the new tile pixmap.
439  * 
440  * Set a tile pixmap for a graphics context.
441  * This will only be used if the fill mode
442  * is %GDK_TILED.
443  **/
444 void
445 gdk_gc_set_tile (GdkGC     *gc,
446                  GdkPixmap *tile)
447 {
448   GdkGCValues values;
449
450   g_return_if_fail (GDK_IS_GC (gc));
451
452   values.tile = tile;
453   gdk_gc_set_values (gc, &values, GDK_GC_TILE);
454 }
455
456 /**
457  * gdk_gc_set_stipple:
458  * @gc: a #GdkGC.
459  * @stipple: the new stipple bitmap.
460  * 
461  * Set the stipple bitmap for a graphics context. The
462  * stipple will only be used if the fill mode is
463  * %GDK_STIPPLED or %GDK_OPAQUE_STIPPLED.
464  **/
465 void
466 gdk_gc_set_stipple (GdkGC     *gc,
467                     GdkPixmap *stipple)
468 {
469   GdkGCValues values;
470
471   g_return_if_fail (GDK_IS_GC (gc));
472
473   values.stipple = stipple;
474   gdk_gc_set_values (gc, &values, GDK_GC_STIPPLE);
475 }
476
477 /**
478  * gdk_gc_set_ts_origin:
479  * @gc:  a #GdkGC.
480  * @x: the x-coordinate of the origin.
481  * @y: the y-coordinate of the origin.
482  * 
483  * Set the origin when using tiles or stipples with
484  * the GC. The tile or stipple will be aligned such
485  * that the upper left corner of the tile or stipple
486  * will coincide with this point.
487  **/
488 void
489 gdk_gc_set_ts_origin (GdkGC *gc,
490                       gint   x,
491                       gint   y)
492 {
493   GdkGCValues values;
494
495   g_return_if_fail (GDK_IS_GC (gc));
496
497   values.ts_x_origin = x;
498   values.ts_y_origin = y;
499   
500   gdk_gc_set_values (gc, &values,
501                      GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
502 }
503
504 /**
505  * gdk_gc_set_clip_origin:
506  * @gc: a #GdkGC.
507  * @x: the x-coordinate of the origin.
508  * @y: the y-coordinate of the origin.
509  * 
510  * Sets the origin of the clip mask. The coordinates are
511  * interpreted relative to the upper-left corner of
512  * the destination drawable of the current operation.
513  **/
514 void
515 gdk_gc_set_clip_origin (GdkGC *gc,
516                         gint   x,
517                         gint   y)
518 {
519   GdkGCValues values;
520
521   g_return_if_fail (GDK_IS_GC (gc));
522
523   values.clip_x_origin = x;
524   values.clip_y_origin = y;
525   
526   gdk_gc_set_values (gc, &values,
527                      GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN);
528 }
529
530 /**
531  * gdk_gc_set_clip_mask:
532  * @gc: the #GdkGC.
533  * @mask: a bitmap.
534  * 
535  * Sets the clip mask for a graphics context from a bitmap.
536  * The clip mask is interpreted relative to the clip
537  * origin. (See gdk_gc_set_clip_origin()).
538  **/
539 void
540 gdk_gc_set_clip_mask (GdkGC     *gc,
541                       GdkBitmap *mask)
542 {
543   GdkGCValues values;
544   
545   g_return_if_fail (GDK_IS_GC (gc));
546   
547   values.clip_mask = mask;
548   gdk_gc_set_values (gc, &values, GDK_GC_CLIP_MASK);
549 }
550
551 /* Takes ownership of passed in region */
552 void
553 _gdk_gc_set_clip_region_internal (GdkGC     *gc,
554                                   GdkRegion *region,
555                                   gboolean reset_origin)
556 {
557   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
558
559   if (priv->clip_region)
560     gdk_region_destroy (priv->clip_region);
561
562   priv->clip_region = region;
563
564   _gdk_windowing_gc_set_clip_region (gc, region, reset_origin);
565 }
566
567 /* Takes ownership of passed in region, returns old clip region */
568 void
569 _gdk_gc_intersect_clip_region (GdkGC     *gc,
570                                GdkRegion *region,
571                                GdkRegion **old_clip_region)
572 {
573   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
574   GdkRegion *old_clip;
575
576   old_clip = priv->clip_region;
577
578   priv->clip_region = region;
579   if (old_clip)
580     gdk_region_intersect (region, old_clip);
581
582   if (old_clip_region)
583     *old_clip_region = old_clip;
584   else
585     gdk_region_destroy (old_clip);
586   
587   _gdk_windowing_gc_set_clip_region (gc, priv->clip_region, FALSE);
588   
589   return old_clip;
590 }
591
592 /**
593  * gdk_gc_set_clip_rectangle:
594  * @gc: a #GdkGC.
595  * @rectangle: the rectangle to clip to.
596  * 
597  * Sets the clip mask for a graphics context from a
598  * rectangle. The clip mask is interpreted relative to the clip
599  * origin. (See gdk_gc_set_clip_origin()).
600  **/
601 void
602 gdk_gc_set_clip_rectangle (GdkGC              *gc,
603                            const GdkRectangle *rectangle)
604 {
605   GdkRegion *region;
606   
607   g_return_if_fail (GDK_IS_GC (gc));
608
609   if (rectangle)
610     region = gdk_region_rectangle (rectangle);
611   else
612     region = NULL;
613
614   _gdk_gc_set_clip_region_internal (gc, region, TRUE);
615 }
616
617 /**
618  * gdk_gc_set_clip_region:
619  * @gc: a #GdkGC.
620  * @region: the #GdkRegion. 
621  * 
622  * Sets the clip mask for a graphics context from a region structure.
623  * The clip mask is interpreted relative to the clip origin. (See
624  * gdk_gc_set_clip_origin()).
625  **/
626 void
627 gdk_gc_set_clip_region (GdkGC           *gc,
628                         const GdkRegion *region)
629 {
630   GdkRegion *copy;
631
632   g_return_if_fail (GDK_IS_GC (gc));
633
634   if (region)
635     copy = gdk_region_copy (region);
636   else
637     copy = NULL;
638
639   _gdk_gc_set_clip_region_internal (gc, copy, TRUE);
640 }
641
642 /**
643  * _gdk_gc_get_clip_region:
644  * @gc: a #GdkGC
645  * 
646  * Gets the current clip region for @gc, if any.
647  * 
648  * Return value: the clip region for the GC, or %NULL.
649  *   (if a clip mask is set, the return will be %NULL)
650  *   This value is owned by the GC and must not be freed.
651  **/
652 GdkRegion *
653 _gdk_gc_get_clip_region (GdkGC *gc)
654 {
655   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
656
657   return GDK_GC_GET_PRIVATE (gc)->clip_region;
658 }
659
660 /**
661  * _gdk_gc_get_fill:
662  * @gc: a #GdkGC
663  * 
664  * Gets the current file style for the GC
665  * 
666  * Return value: the file style for the GC
667  **/
668 GdkFill
669 _gdk_gc_get_fill (GdkGC *gc)
670 {
671   g_return_val_if_fail (GDK_IS_GC (gc), GDK_SOLID);
672
673   return GDK_GC_GET_PRIVATE (gc)->fill;
674 }
675
676 /**
677  * _gdk_gc_get_tile:
678  * @gc: a #GdkGC
679  * 
680  * Gets the tile pixmap for @gc, if any
681  * 
682  * Return value: the tile set on the GC, or %NULL. The
683  *   value is owned by the GC and must not be freed.
684  **/
685 GdkPixmap *
686 _gdk_gc_get_tile (GdkGC *gc)
687 {
688   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
689
690   return GDK_GC_GET_PRIVATE (gc)->tile;
691 }
692
693 /**
694  * _gdk_gc_get_stipple:
695  * @gc: a #GdkGC
696  * 
697  * Gets the stipple pixmap for @gc, if any
698  * 
699  * Return value: the stipple set on the GC, or %NULL. The
700  *   value is owned by the GC and must not be freed.
701  **/
702 GdkBitmap *
703 _gdk_gc_get_stipple (GdkGC *gc)
704 {
705   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
706
707   return GDK_GC_GET_PRIVATE (gc)->stipple;
708 }
709
710 /**
711  * _gdk_gc_get_fg_pixel:
712  * @gc: a #GdkGC
713  * 
714  * Gets the foreground pixel value for @gc. If the
715  * foreground pixel has never been set, returns the
716  * default value 0.
717  * 
718  * Return value: the foreground pixel value of the GC
719  **/
720 guint32
721 _gdk_gc_get_fg_pixel (GdkGC *gc)
722 {
723   g_return_val_if_fail (GDK_IS_GC (gc), 0);
724   
725   return GDK_GC_GET_PRIVATE (gc)->fg_pixel;
726 }
727
728 /**
729  * _gdk_gc_get_bg_pixel:
730  * @gc: a #GdkGC
731  * 
732  * Gets the background pixel value for @gc.If the
733  * foreground pixel has never been set, returns the
734  * default value 1.
735  * 
736  * Return value: the foreground pixel value of the GC
737  **/
738 guint32
739 _gdk_gc_get_bg_pixel (GdkGC *gc)
740 {
741   g_return_val_if_fail (GDK_IS_GC (gc), 0);
742   
743   return GDK_GC_GET_PRIVATE (gc)->bg_pixel;
744 }
745
746 /**
747  * gdk_gc_set_subwindow:
748  * @gc: a #GdkGC.
749  * @mode: the subwindow mode.
750  * 
751  * Sets how drawing with this GC on a window will affect child
752  * windows of that window. 
753  **/
754 void
755 gdk_gc_set_subwindow (GdkGC            *gc,
756                       GdkSubwindowMode  mode)
757 {
758   GdkGCValues values;
759   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
760
761   g_return_if_fail (GDK_IS_GC (gc));
762
763   /* This could get called a lot to reset the subwindow mode in
764      the client side clipping, so bail out early */ 
765   if (priv->subwindow_mode == mode)
766     return;
767   
768   values.subwindow_mode = mode;
769   gdk_gc_set_values (gc, &values, GDK_GC_SUBWINDOW);
770 }
771
772 GdkSubwindowMode
773 _gdk_gc_get_subwindow (GdkGC *gc)
774 {
775   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
776
777   return priv->subwindow_mode;
778 }
779
780 /**
781  * gdk_gc_set_exposures:
782  * @gc: a #GdkGC.
783  * @exposures: if %TRUE, exposure events will be generated.
784  * 
785  * Sets whether copying non-visible portions of a drawable
786  * using this graphics context generate exposure events
787  * for the corresponding regions of the destination
788  * drawable. (See gdk_draw_drawable()).
789  **/
790 void
791 gdk_gc_set_exposures (GdkGC     *gc,
792                       gboolean   exposures)
793 {
794   GdkGCValues values;
795
796   g_return_if_fail (GDK_IS_GC (gc));
797
798   values.graphics_exposures = exposures;
799   gdk_gc_set_values (gc, &values, GDK_GC_EXPOSURES);
800 }
801
802 /**
803  * gdk_gc_set_line_attributes:
804  * @gc: a #GdkGC.
805  * @line_width: the width of lines.
806  * @line_style: the dash-style for lines.
807  * @cap_style: the manner in which the ends of lines are drawn.
808  * @join_style: the in which lines are joined together.
809  * 
810  * Sets various attributes of how lines are drawn. See
811  * the corresponding members of #GdkGCValues for full
812  * explanations of the arguments.
813  **/
814 void
815 gdk_gc_set_line_attributes (GdkGC       *gc,
816                             gint         line_width,
817                             GdkLineStyle line_style,
818                             GdkCapStyle  cap_style,
819                             GdkJoinStyle join_style)
820 {
821   GdkGCValues values;
822
823   values.line_width = line_width;
824   values.line_style = line_style;
825   values.cap_style = cap_style;
826   values.join_style = join_style;
827
828   gdk_gc_set_values (gc, &values,
829                      GDK_GC_LINE_WIDTH |
830                      GDK_GC_LINE_STYLE |
831                      GDK_GC_CAP_STYLE |
832                      GDK_GC_JOIN_STYLE);
833 }
834
835 /**
836  * gdk_gc_set_dashes:
837  * @gc: a #GdkGC.
838  * @dash_offset: the phase of the dash pattern.
839  * @dash_list: an array of dash lengths.
840  * @n: the number of elements in @dash_list.
841  * 
842  * Sets the way dashed-lines are drawn. Lines will be
843  * drawn with alternating on and off segments of the
844  * lengths specified in @dash_list. The manner in
845  * which the on and off segments are drawn is determined
846  * by the @line_style value of the GC. (This can
847  * be changed with gdk_gc_set_line_attributes().)
848  *
849  * The @dash_offset defines the phase of the pattern, 
850  * specifying how many pixels into the dash-list the pattern 
851  * should actually begin.
852  **/
853 void
854 gdk_gc_set_dashes (GdkGC *gc,
855                    gint   dash_offset,
856                    gint8  dash_list[],
857                    gint   n)
858 {
859   g_return_if_fail (GDK_IS_GC (gc));
860   g_return_if_fail (dash_list != NULL);
861
862   GDK_GC_GET_CLASS (gc)->set_dashes (gc, dash_offset, dash_list, n);
863 }
864
865 /**
866  * gdk_gc_offset:
867  * @gc: a #GdkGC
868  * @x_offset: amount by which to offset the GC in the X direction
869  * @y_offset: amount by which to offset the GC in the Y direction
870  * 
871  * Offset attributes such as the clip and tile-stipple origins
872  * of the GC so that drawing at x - x_offset, y - y_offset with
873  * the offset GC  has the same effect as drawing at x, y with the original
874  * GC.
875  **/
876 void
877 gdk_gc_offset (GdkGC *gc,
878                gint   x_offset,
879                gint   y_offset)
880 {
881   if (x_offset != 0 || y_offset != 0)
882     {
883       GdkGCValues values;
884
885       values.clip_x_origin = gc->clip_x_origin - x_offset;
886       values.clip_y_origin = gc->clip_y_origin - y_offset;
887       values.ts_x_origin = gc->ts_x_origin - x_offset;
888       values.ts_y_origin = gc->ts_y_origin - y_offset;
889       
890       gdk_gc_set_values (gc, &values,
891                          GDK_GC_CLIP_X_ORIGIN |
892                          GDK_GC_CLIP_Y_ORIGIN |
893                          GDK_GC_TS_X_ORIGIN |
894                          GDK_GC_TS_Y_ORIGIN);
895     }
896 }
897
898 /**
899  * gdk_gc_copy:
900  * @dst_gc: the destination graphics context.
901  * @src_gc: the source graphics context.
902  * 
903  * Copy the set of values from one graphics context
904  * onto another graphics context.
905  **/
906 void
907 gdk_gc_copy (GdkGC *dst_gc,
908              GdkGC *src_gc)
909 {
910   GdkGCPrivate *dst_priv, *src_priv;
911   
912   g_return_if_fail (GDK_IS_GC (dst_gc));
913   g_return_if_fail (GDK_IS_GC (src_gc));
914
915   dst_priv = GDK_GC_GET_PRIVATE (dst_gc);
916   src_priv = GDK_GC_GET_PRIVATE (src_gc);
917
918   _gdk_windowing_gc_copy (dst_gc, src_gc);
919
920   dst_gc->clip_x_origin = src_gc->clip_x_origin;
921   dst_gc->clip_y_origin = src_gc->clip_y_origin;
922   dst_gc->ts_x_origin = src_gc->ts_x_origin;
923   dst_gc->ts_y_origin = src_gc->ts_y_origin;
924
925   if (src_gc->colormap)
926     g_object_ref (src_gc->colormap);
927
928   if (dst_gc->colormap)
929     g_object_unref (dst_gc->colormap);
930
931   dst_gc->colormap = src_gc->colormap;
932
933   if (dst_priv->clip_region)
934     gdk_region_destroy (dst_priv->clip_region);
935
936   if (src_priv->clip_region)
937     dst_priv->clip_region = gdk_region_copy (src_priv->clip_region);
938   else
939     dst_priv->clip_region = NULL;
940   
941   dst_priv->fill = src_priv->fill;
942   
943   if (dst_priv->stipple)
944     g_object_unref (dst_priv->stipple);
945   dst_priv->stipple = src_priv->stipple;
946   if (dst_priv->stipple)
947     g_object_ref (dst_priv->stipple);
948   
949   if (dst_priv->tile)
950     g_object_unref (dst_priv->tile);
951   dst_priv->tile = src_priv->tile;
952   if (dst_priv->tile)
953     g_object_ref (dst_priv->tile);
954
955   dst_priv->fg_pixel = src_priv->fg_pixel;
956   dst_priv->bg_pixel = src_priv->bg_pixel;
957   dst_priv->subwindow_mode = src_priv->subwindow_mode;
958 }
959
960 /**
961  * gdk_gc_set_colormap:
962  * @gc: a #GdkGC
963  * @colormap: a #GdkColormap
964  * 
965  * Sets the colormap for the GC to the given colormap. The depth
966  * of the colormap's visual must match the depth of the drawable
967  * for which the GC was created.
968  **/
969 void
970 gdk_gc_set_colormap (GdkGC       *gc,
971                      GdkColormap *colormap)
972 {
973   g_return_if_fail (GDK_IS_GC (gc));
974   g_return_if_fail (GDK_IS_COLORMAP (colormap));
975
976   if (gc->colormap != colormap)
977     {
978       if (gc->colormap)
979         g_object_unref (gc->colormap);
980
981       gc->colormap = colormap;
982       g_object_ref (gc->colormap);
983     }
984     
985 }
986
987 /**
988  * gdk_gc_get_colormap:
989  * @gc: a #GdkGC
990  * 
991  * Retrieves the colormap for a given GC, if it exists.
992  * A GC will have a colormap if the drawable for which it was created
993  * has a colormap, or if a colormap was set explicitely with
994  * gdk_gc_set_colormap.
995  * 
996  * Return value: the colormap of @gc, or %NULL if @gc doesn't have one.
997  **/
998 GdkColormap *
999 gdk_gc_get_colormap (GdkGC *gc)
1000 {
1001   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
1002
1003   return gc->colormap;
1004 }
1005
1006 static GdkColormap *
1007 gdk_gc_get_colormap_warn (GdkGC *gc)
1008 {
1009   GdkColormap *colormap = gdk_gc_get_colormap (gc);
1010   if (!colormap)
1011     {
1012       g_warning ("gdk_gc_set_rgb_fg_color() and gdk_gc_set_rgb_bg_color() can\n"
1013                  "only be used on GC's with a colormap. A GC will have a colormap\n"
1014                  "if it is created for a drawable with a colormap, or if a\n"
1015                  "colormap has been set explicitly with gdk_gc_set_colormap.\n");
1016       return NULL;
1017     }
1018
1019   return colormap;
1020 }
1021
1022 /**
1023  * gdk_gc_set_rgb_fg_color:
1024  * @gc: a #GdkGC
1025  * @color: an unallocated #GdkColor.
1026  * 
1027  * Set the foreground color of a GC using an unallocated color. The
1028  * pixel value for the color will be determined using GdkRGB. If the
1029  * colormap for the GC has not previously been initialized for GdkRGB,
1030  * then for pseudo-color colormaps (colormaps with a small modifiable
1031  * number of colors), a colorcube will be allocated in the colormap.
1032  * 
1033  * Calling this function for a GC without a colormap is an error.
1034  **/
1035 void
1036 gdk_gc_set_rgb_fg_color (GdkGC          *gc,
1037                          const GdkColor *color)
1038 {
1039   GdkColormap *cmap;
1040   GdkColor tmp_color;
1041
1042   g_return_if_fail (GDK_IS_GC (gc));
1043   g_return_if_fail (color != NULL);
1044
1045   cmap = gdk_gc_get_colormap_warn (gc);
1046   if (!cmap)
1047     return;
1048
1049   tmp_color = *color;
1050   gdk_rgb_find_color (cmap, &tmp_color);
1051   gdk_gc_set_foreground (gc, &tmp_color);
1052 }
1053
1054 /**
1055  * gdk_gc_set_rgb_bg_color:
1056  * @gc: a #GdkGC
1057  * @color: an unallocated #GdkColor.
1058  * 
1059  * Set the background color of a GC using an unallocated color. The
1060  * pixel value for the color will be determined using GdkRGB. If the
1061  * colormap for the GC has not previously been initialized for GdkRGB,
1062  * then for pseudo-color colormaps (colormaps with a small modifiable
1063  * number of colors), a colorcube will be allocated in the colormap.
1064  * 
1065  * Calling this function for a GC without a colormap is an error.
1066  **/
1067 void
1068 gdk_gc_set_rgb_bg_color (GdkGC          *gc,
1069                          const GdkColor *color)
1070 {
1071   GdkColormap *cmap;
1072   GdkColor tmp_color;
1073
1074   g_return_if_fail (GDK_IS_GC (gc));
1075   g_return_if_fail (color != NULL);
1076
1077   cmap = gdk_gc_get_colormap_warn (gc);
1078   if (!cmap)
1079     return;
1080
1081   tmp_color = *color;
1082   gdk_rgb_find_color (cmap, &tmp_color);
1083   gdk_gc_set_background (gc, &tmp_color);
1084 }
1085
1086 static cairo_surface_t *
1087 make_stipple_tile_surface (cairo_t   *cr,
1088                            GdkBitmap *stipple,
1089                            GdkColor  *foreground,
1090                            GdkColor  *background)
1091 {
1092   cairo_t *tmp_cr;
1093   cairo_surface_t *surface; 
1094   cairo_surface_t *alpha_surface;
1095   gint width, height;
1096
1097   gdk_drawable_get_size (stipple,
1098                          &width, &height);
1099   
1100   alpha_surface = _gdk_drawable_ref_cairo_surface (stipple);
1101   
1102   surface = cairo_surface_create_similar (cairo_get_target (cr),
1103                                           CAIRO_CONTENT_COLOR_ALPHA,
1104                                           width, height);
1105
1106   tmp_cr = cairo_create (surface);
1107   
1108   cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SOURCE);
1109  
1110   if (background)
1111       gdk_cairo_set_source_color (tmp_cr, background);
1112   else
1113       cairo_set_source_rgba (tmp_cr, 0, 0, 0 ,0);
1114
1115   cairo_paint (tmp_cr);
1116
1117   cairo_set_operator (tmp_cr, CAIRO_OPERATOR_OVER);
1118
1119   gdk_cairo_set_source_color (tmp_cr, foreground);
1120   cairo_mask_surface (tmp_cr, alpha_surface, 0, 0);
1121   
1122   cairo_destroy (tmp_cr);
1123   cairo_surface_destroy (alpha_surface);
1124
1125   return surface;
1126 }
1127
1128 static void
1129 gc_get_foreground (GdkGC    *gc,
1130                    GdkColor *color)
1131 {
1132   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
1133   
1134   color->pixel = priv->bg_pixel;
1135
1136   if (gc->colormap)
1137     gdk_colormap_query_color (gc->colormap, priv->fg_pixel, color);
1138   else
1139     g_warning ("No colormap in gc_get_foreground");
1140 }
1141
1142 static void
1143 gc_get_background (GdkGC    *gc,
1144                    GdkColor *color)
1145 {
1146   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
1147   
1148   color->pixel = priv->bg_pixel;
1149
1150   if (gc->colormap)
1151     gdk_colormap_query_color (gc->colormap, priv->bg_pixel, color);
1152   else
1153     g_warning ("No colormap in gc_get_background");
1154 }
1155
1156 /**
1157  * _gdk_gc_update_context:
1158  * @gc: a #GdkGC
1159  * @cr: a #cairo_t
1160  * @override_foreground: a foreground color to use to override the
1161  *   foreground color of the GC
1162  * @override_stipple: a stipple pattern to use to override the
1163  *   stipple from the GC. If this is present and the fill mode
1164  *   of the GC isn't %GDK_STIPPLED or %GDK_OPAQUE_STIPPLED
1165  *   the fill mode will be forced to %GDK_STIPPLED
1166  * @gc_changed: pass %FALSE if the @gc has not changed since the
1167  *     last call to this function
1168  * @target_drawable: The drawable you're drawing in. If passed in
1169  *     this is used for client side window clip emulation.
1170  * 
1171  * Set the attributes of a cairo context to match those of a #GdkGC
1172  * as far as possible. Some aspects of a #GdkGC, such as clip masks
1173  * and functions other than %GDK_COPY are not currently handled.
1174  **/
1175 void
1176 _gdk_gc_update_context (GdkGC          *gc,
1177                         cairo_t        *cr,
1178                         const GdkColor *override_foreground,
1179                         GdkBitmap      *override_stipple,
1180                         gboolean        gc_changed,
1181                         GdkDrawable    *target_drawable)
1182 {
1183   GdkGCPrivate *priv;
1184   GdkFill fill;
1185   GdkColor foreground;
1186   GdkColor background;
1187   cairo_surface_t *tile_surface = NULL;
1188   GdkBitmap *stipple = NULL;
1189
1190   g_return_if_fail (GDK_IS_GC (gc));
1191   g_return_if_fail (cr != NULL);
1192   g_return_if_fail (override_stipple == NULL || GDK_IS_PIXMAP (override_stipple));
1193
1194   priv = GDK_GC_GET_PRIVATE (gc);
1195
1196   fill = priv->fill;
1197   if (override_stipple && fill != GDK_OPAQUE_STIPPLED)
1198     fill = GDK_STIPPLED;
1199
1200   if (fill != GDK_TILED)
1201     {
1202       if (override_foreground)
1203         foreground = *override_foreground;
1204       else
1205         gc_get_foreground (gc, &foreground);
1206     }
1207
1208   if (fill == GDK_OPAQUE_STIPPLED)
1209     gc_get_background (gc, &background);
1210
1211
1212   switch (fill)
1213     {
1214     case GDK_SOLID:
1215       break;
1216     case GDK_TILED:
1217       if (!priv->tile)
1218         fill = GDK_SOLID;
1219       break;
1220     case GDK_STIPPLED:
1221     case GDK_OPAQUE_STIPPLED:
1222       if (override_stipple)
1223         stipple = override_stipple;
1224       else
1225         stipple = priv->stipple;
1226       
1227       if (!stipple)
1228         fill = GDK_SOLID;
1229       break;
1230     }
1231   
1232   switch (fill)
1233     {
1234     case GDK_SOLID:
1235       gdk_cairo_set_source_color (cr, &foreground);
1236       break;
1237     case GDK_TILED:
1238       tile_surface = _gdk_drawable_ref_cairo_surface (priv->tile);
1239       break;
1240     case GDK_STIPPLED:
1241       tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, NULL);
1242       break;
1243     case GDK_OPAQUE_STIPPLED:
1244       tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, &background);
1245       break;
1246     }
1247
1248   /* Tiles, stipples, and clip regions are all specified in device space,
1249    * not user space. For the clip region, we can simply change the matrix,
1250    * clip, then clip back, but for the source pattern, we need to
1251    * compute the right matrix.
1252    *
1253    * What we want is:
1254    *
1255    *     CTM_inverse * Pattern_matrix = Translate(- ts_x, - ts_y)
1256    *
1257    * (So that ts_x, ts_y in device space is taken to 0,0 in pattern
1258    * space). So, pattern_matrix = CTM * Translate(- ts_x, - tx_y);
1259    */
1260
1261   if (tile_surface)
1262     {
1263       cairo_pattern_t *pattern = cairo_pattern_create_for_surface (tile_surface);
1264       cairo_matrix_t user_to_device;
1265       cairo_matrix_t user_to_pattern;
1266       cairo_matrix_t device_to_pattern;
1267
1268       cairo_get_matrix (cr, &user_to_device);
1269       cairo_matrix_init_translate (&device_to_pattern,
1270                                    - gc->ts_x_origin, - gc->ts_y_origin);
1271       cairo_matrix_multiply (&user_to_pattern,
1272                              &user_to_device, &device_to_pattern);
1273       
1274       cairo_pattern_set_matrix (pattern, &user_to_pattern);
1275       cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
1276       cairo_set_source (cr, pattern);
1277       
1278       cairo_surface_destroy (tile_surface);
1279       cairo_pattern_destroy (pattern);
1280     }
1281
1282   if (!gc_changed)
1283     return;
1284
1285   cairo_reset_clip (cr);
1286   if (priv->clip_region)
1287     {
1288       cairo_save (cr);
1289
1290       cairo_identity_matrix (cr);
1291       cairo_translate (cr, gc->clip_x_origin, gc->clip_y_origin);
1292
1293       cairo_new_path (cr);
1294       gdk_cairo_region (cr, priv->clip_region);
1295
1296       cairo_restore (cr);
1297
1298       cairo_clip (cr);
1299     }
1300
1301   /* The reset above resets the window clip rect, so we want to re-set that */
1302   if (target_drawable && GDK_DRAWABLE_GET_CLASS (target_drawable)->set_cairo_clip)
1303     GDK_DRAWABLE_GET_CLASS (target_drawable)->set_cairo_clip (target_drawable, cr);
1304 }
1305
1306
1307 #define __GDK_GC_C__
1308 #include "gdkaliasdef.c"