]> Pileus Git - ~andy/gtk/blob - gdk/quartz/gdkgc-quartz.c
Add these from the win32 backend.
[~andy/gtk] / gdk / quartz / gdkgc-quartz.c
1 /* gdkgc-quartz.c
2  *
3  * Copyright (C) 2005 Imendio AB
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <config.h>
22
23 #include "gdkgc.h"
24 #include "gdkprivate-quartz.h"
25
26 static gpointer parent_class = NULL;
27
28 static void
29 gdk_quartz_gc_get_values (GdkGC       *gc,
30                          GdkGCValues *values)
31 {
32   /* FIXME: Implement */
33 }
34
35 static void
36 gdk_quartz_gc_set_values (GdkGC           *gc,
37                          GdkGCValues     *values,
38                          GdkGCValuesMask  mask)
39 {
40   GdkGCQuartz *private = GDK_GC_QUARTZ (gc);
41
42   private->values_mask |= mask;
43
44   if (mask & GDK_GC_CLIP_MASK)
45     {
46       private->have_clip_region = FALSE;
47       private->have_clip_mask = values->clip_mask != NULL;
48       if (private->clip_mask)
49         CGImageRelease (private->clip_mask);
50
51       if (values->clip_mask)
52         private->clip_mask = CGImageCreateCopy (GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (values->clip_mask)->impl)->image);
53       else
54         private->clip_mask = NULL;
55     }
56 }
57
58 static void
59 gdk_quartz_gc_set_dashes (GdkGC *gc,
60                          gint   dash_offset,
61                          gint8  dash_list[],
62                          gint   n)
63 {
64   /* FIXME: Implement */
65 }
66
67 static void
68 gdk_gc_quartz_finalize (GObject *object)
69 {
70   GdkGCQuartz *private = GDK_GC_QUARTZ (object);
71
72   if (private->clip_mask)
73     CGImageRelease (private->clip_mask);
74
75   G_OBJECT_CLASS (parent_class)->finalize (object);
76 }
77
78 static void
79 gdk_gc_quartz_class_init (GdkGCQuartzClass *klass)
80 {
81   GObjectClass *object_class = G_OBJECT_CLASS (klass);
82   GdkGCClass *gc_class = GDK_GC_CLASS (klass);
83   
84   parent_class = g_type_class_peek_parent (klass);
85
86   object_class->finalize = gdk_gc_quartz_finalize;
87
88   gc_class->get_values = gdk_quartz_gc_get_values;
89   gc_class->set_values = gdk_quartz_gc_set_values;
90   gc_class->set_dashes = gdk_quartz_gc_set_dashes;
91 }
92
93 GType
94 _gdk_gc_quartz_get_type (void)
95 {
96   static GType object_type = 0;
97
98   if (!object_type)
99     {
100       static const GTypeInfo object_info =
101       {
102         sizeof (GdkGCQuartzClass),
103         (GBaseInitFunc) NULL,
104         (GBaseFinalizeFunc) NULL,
105         (GClassInitFunc) gdk_gc_quartz_class_init,
106         NULL,           /* class_finalize */
107         NULL,           /* class_data */
108         sizeof (GdkGCQuartz),
109         0,              /* n_preallocs */
110         (GInstanceInitFunc) NULL,
111       };
112       
113       object_type = g_type_register_static (GDK_TYPE_GC,
114                                             "GdkGCQuartz",
115                                             &object_info, 0);
116     }
117   
118   return object_type;
119 }
120
121 GdkGC *
122 _gdk_quartz_gc_new (GdkDrawable      *drawable,
123                     GdkGCValues      *values,
124                     GdkGCValuesMask   values_mask)
125 {
126   GdkGC *gc;
127
128   gc = g_object_new (GDK_TYPE_GC_QUARTZ, NULL);
129
130   _gdk_gc_init (gc, drawable, values, values_mask);
131
132   gdk_quartz_gc_set_values (gc, values, values_mask);
133
134   return gc;
135 }
136
137 void
138 _gdk_windowing_gc_set_clip_region (GdkGC     *gc,
139                                    GdkRegion *region)
140 {
141   GdkGCQuartz *private = GDK_GC_QUARTZ (gc);
142
143   if ((private->have_clip_region && ! region) || private->have_clip_mask)
144     {
145       if (private->clip_mask)
146         {
147           CGImageRelease (private->clip_mask);
148           private->clip_mask = NULL;
149         }
150       private->have_clip_mask = FALSE;
151     }
152
153   private->have_clip_region = region != NULL;
154
155   gc->clip_x_origin = 0;
156   gc->clip_y_origin = 0;
157 }
158
159 void
160 _gdk_windowing_gc_copy (GdkGC *dst_gc,
161                         GdkGC *src_gc)
162 {
163   /* FIXME: Implement */
164 }
165
166 void
167 _gdk_quartz_update_context_from_gc (CGContextRef context, GdkGC *gc)
168 {
169   GdkGCQuartz *private;
170
171   if (gc == NULL)
172     return;
173
174   private = GDK_GC_QUARTZ (gc);
175
176   if (private->have_clip_region)
177     {
178       CGRect rect;
179       CGRect *cg_rects;
180       GdkRectangle *rects;
181       gint n_rects, i;
182
183       gdk_region_get_rectangles (_gdk_gc_get_clip_region (gc),
184                                  &rects, &n_rects);
185
186       if (n_rects == 1)
187         cg_rects = &rect;
188       else
189         cg_rects = g_new (CGRect, n_rects);
190
191       for (i = 0; i < n_rects; i++)
192         {
193           cg_rects[i].origin.x = rects[i].x + gc->clip_x_origin;
194           cg_rects[i].origin.y = rects[i].y + gc->clip_y_origin;
195           cg_rects[i].size.width = rects[i].width;
196           cg_rects[i].size.height = rects[i].height;
197         }
198
199       CGContextClipToRects (context, cg_rects, n_rects);
200
201       g_free (rects);
202       if (cg_rects != &rect)
203         g_free (cg_rects);
204     }
205   else if (private->have_clip_mask && private->clip_mask)
206     {
207       /* FIXME: This is 10.4 only. For lower versions, we need to transform the
208        * mask into a region.
209        */
210       CGContextClipToMask (context,
211                            CGRectMake(gc->clip_x_origin, gc->clip_y_origin,
212                                       CGImageGetWidth (private->clip_mask),
213                                       CGImageGetHeight (private->clip_mask)),
214                            private->clip_mask);
215     }
216 }