]> Pileus Git - ~andy/gtk/blob - gdk/quartz/gdkgc-quartz.c
2f687e768b68da684d0d77b3a554935807eccb30
[~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 GdkScreen *  
167 gdk_gc_get_screen (GdkGC *gc)
168 {
169   return NULL;
170 }
171
172 void
173 _gdk_quartz_update_context_from_gc (CGContextRef context, GdkGC *gc)
174 {
175   GdkGCQuartz *private;
176
177   if (gc == NULL)
178     return;
179
180   private = GDK_GC_QUARTZ (gc);
181
182   if (private->have_clip_region)
183     {
184       CGRect rect;
185       CGRect *cg_rects;
186       GdkRectangle *rects;
187       gint n_rects, i;
188
189       gdk_region_get_rectangles (_gdk_gc_get_clip_region (gc),
190                                  &rects, &n_rects);
191
192       if (n_rects == 1)
193         cg_rects = &rect;
194       else
195         cg_rects = g_new (CGRect, n_rects);
196
197       for (i = 0; i < n_rects; i++)
198         {
199           cg_rects[i].origin.x = rects[i].x + gc->clip_x_origin;
200           cg_rects[i].origin.y = rects[i].y + gc->clip_y_origin;
201           cg_rects[i].size.width = rects[i].width;
202           cg_rects[i].size.height = rects[i].height;
203         }
204
205       CGContextClipToRects (context, cg_rects, n_rects);
206
207       g_free (rects);
208       if (cg_rects != &rect)
209         g_free (cg_rects);
210     }
211   else if (private->have_clip_mask && private->clip_mask)
212     {
213       /* FIXME: This is 10.4 only. For lower versions, we need to transform the
214        * mask into a region.
215        */
216       CGContextClipToMask (context,
217                            CGRectMake(gc->clip_x_origin, gc->clip_y_origin,
218                                       CGImageGetWidth (private->clip_mask),
219                                       CGImageGetHeight (private->clip_mask)),
220                            private->clip_mask);
221     }
222 }