]> Pileus Git - ~andy/gtk/blob - gdk/gdkgc.c
applied patch from Andreas Persenius <ndap@swipnet.se> that updates the
[~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 <string.h>
28
29 #include "gdkgc.h"
30 #include "gdkrgb.h"
31 #include "gdkprivate.h"
32
33 static void gdk_gc_class_init (GObjectClass *class);
34 static void gdk_gc_finalize   (GObject      *object);
35
36 static GObjectClass *parent_class;
37
38 GType
39 gdk_gc_get_type (void)
40 {
41   static GType object_type = 0;
42
43   if (!object_type)
44     {
45       static const GTypeInfo object_info =
46       {
47         sizeof (GdkGCClass),
48         (GBaseInitFunc) NULL,
49         (GBaseFinalizeFunc) NULL,
50         (GClassInitFunc) gdk_gc_class_init,
51         NULL,           /* class_finalize */
52         NULL,           /* class_data */
53         sizeof (GdkGC),
54         0,              /* n_preallocs */
55         (GInstanceInitFunc) NULL,
56       };
57       
58       object_type = g_type_register_static (G_TYPE_OBJECT,
59                                             "GdkGC",
60                                             &object_info);
61     }
62   
63   return object_type;
64 }
65
66 static void
67 gdk_gc_class_init (GObjectClass *class)
68 {
69   parent_class = g_type_class_peek_parent (class);
70   
71   class->finalize = gdk_gc_finalize;
72 }
73
74 GdkGC*
75 gdk_gc_new (GdkDrawable *drawable)
76 {
77   g_return_val_if_fail (drawable != NULL, NULL);
78
79   return gdk_gc_new_with_values (drawable, NULL, 0);
80 }
81
82 GdkGC*
83 gdk_gc_new_with_values (GdkDrawable     *drawable,
84                         GdkGCValues     *values,
85                         GdkGCValuesMask  values_mask)
86 {
87   GdkGC *gc;
88
89   g_return_val_if_fail (drawable != NULL, NULL);
90
91   gc = GDK_DRAWABLE_GET_CLASS (drawable)->create_gc (drawable,
92                                                      values,
93                                                      values_mask);
94
95   if (gc == NULL) /* This would mean the drawable was destroyed. */
96     return NULL;
97   
98   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
99     gc->clip_x_origin = values->clip_x_origin;
100   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
101     gc->clip_y_origin = values->clip_y_origin;
102   if (values_mask & GDK_GC_TS_X_ORIGIN)
103     gc->ts_x_origin = values->ts_x_origin;
104   if (values_mask & GDK_GC_TS_Y_ORIGIN)
105     gc->ts_y_origin = values->ts_y_origin;
106
107   gc->colormap = gdk_drawable_get_colormap (drawable);
108   if (gc->colormap)
109     g_object_ref (G_OBJECT (gc->colormap));
110   
111   return gc;
112 }
113
114 static void
115 gdk_gc_finalize (GObject *object)
116 {
117   GdkGC *gc = GDK_GC (object);
118   
119   if (gc->colormap)
120     g_object_unref (G_OBJECT (gc->colormap));
121
122   parent_class->finalize (object);
123 }
124
125 GdkGC *
126 gdk_gc_ref (GdkGC *gc)
127 {
128   return (GdkGC *) g_object_ref (G_OBJECT (gc));
129 }
130
131 void
132 gdk_gc_unref (GdkGC *gc)
133 {
134   g_object_unref (G_OBJECT (gc));
135 }
136
137 void
138 gdk_gc_get_values (GdkGC       *gc,
139                    GdkGCValues *values)
140 {
141   g_return_if_fail (GDK_IS_GC (gc));
142   g_return_if_fail (values != NULL);
143
144   GDK_GC_GET_CLASS (gc)->get_values (gc, values);
145 }
146
147 void
148 gdk_gc_set_values (GdkGC           *gc,
149                    GdkGCValues     *values,
150                    GdkGCValuesMask  values_mask)
151 {
152   g_return_if_fail (GDK_IS_GC (gc));
153   g_return_if_fail (values != NULL);
154
155   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
156     gc->clip_x_origin = values->clip_x_origin;
157   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
158     gc->clip_y_origin = values->clip_y_origin;
159   if (values_mask & GDK_GC_TS_X_ORIGIN)
160     gc->ts_x_origin = values->ts_x_origin;
161   if (values_mask & GDK_GC_TS_Y_ORIGIN)
162     gc->ts_y_origin = values->ts_y_origin;
163   
164   GDK_GC_GET_CLASS (gc)->set_values (gc, values, values_mask);
165 }
166
167 void
168 gdk_gc_set_foreground (GdkGC    *gc,
169                        GdkColor *color)
170 {
171   GdkGCValues values;
172
173   g_return_if_fail (GDK_IS_GC (gc));
174   g_return_if_fail (color != NULL);
175
176   values.foreground = *color;
177   gdk_gc_set_values (gc, &values, GDK_GC_FOREGROUND);
178 }
179
180 void
181 gdk_gc_set_background (GdkGC    *gc,
182                        GdkColor *color)
183 {
184   GdkGCValues values;
185
186   g_return_if_fail (GDK_IS_GC (gc));
187   g_return_if_fail (color != NULL);
188
189   values.background = *color;
190   gdk_gc_set_values (gc, &values, GDK_GC_BACKGROUND);
191 }
192
193 void
194 gdk_gc_set_font (GdkGC   *gc,
195                  GdkFont *font)
196 {
197   GdkGCValues values;
198
199   g_return_if_fail (GDK_IS_GC (gc));
200   g_return_if_fail (font != NULL);
201
202   values.font = font;
203   gdk_gc_set_values (gc, &values, GDK_GC_FONT);
204 }
205
206 void
207 gdk_gc_set_function (GdkGC       *gc,
208                      GdkFunction  function)
209 {
210   GdkGCValues values;
211
212   g_return_if_fail (GDK_IS_GC (gc));
213
214   values.function = function;
215   gdk_gc_set_values (gc, &values, GDK_GC_FUNCTION);
216 }
217
218 void
219 gdk_gc_set_fill (GdkGC   *gc,
220                  GdkFill  fill)
221 {
222   GdkGCValues values;
223
224   g_return_if_fail (GDK_IS_GC (gc));
225
226   values.fill = fill;
227   gdk_gc_set_values (gc, &values, GDK_GC_FILL);
228 }
229
230 void
231 gdk_gc_set_tile (GdkGC     *gc,
232                  GdkPixmap *tile)
233 {
234   GdkGCValues values;
235
236   g_return_if_fail (GDK_IS_GC (gc));
237
238   values.tile = tile;
239   gdk_gc_set_values (gc, &values, GDK_GC_TILE);
240 }
241
242 void
243 gdk_gc_set_stipple (GdkGC     *gc,
244                     GdkPixmap *stipple)
245 {
246   GdkGCValues values;
247
248   g_return_if_fail (GDK_IS_GC (gc));
249
250   values.stipple = stipple;
251   gdk_gc_set_values (gc, &values, GDK_GC_STIPPLE);
252 }
253
254 void
255 gdk_gc_set_ts_origin (GdkGC *gc,
256                       gint   x,
257                       gint   y)
258 {
259   GdkGCValues values;
260
261   g_return_if_fail (GDK_IS_GC (gc));
262
263   values.ts_x_origin = x;
264   values.ts_y_origin = y;
265   
266   gdk_gc_set_values (gc, &values,
267                      GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
268 }
269
270 void
271 gdk_gc_set_clip_origin (GdkGC *gc,
272                         gint   x,
273                         gint   y)
274 {
275   GdkGCValues values;
276
277   g_return_if_fail (GDK_IS_GC (gc));
278
279   values.clip_x_origin = x;
280   values.clip_y_origin = y;
281   
282   gdk_gc_set_values (gc, &values,
283                      GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN);
284 }
285
286 void
287 gdk_gc_set_clip_mask (GdkGC     *gc,
288                       GdkBitmap *mask)
289 {
290   GdkGCValues values;
291   
292   g_return_if_fail (GDK_IS_GC (gc));
293   
294   values.clip_mask = mask;
295   gdk_gc_set_values (gc, &values, GDK_GC_CLIP_MASK);
296 }
297
298
299 void
300 gdk_gc_set_subwindow (GdkGC            *gc,
301                       GdkSubwindowMode  mode)
302 {
303   GdkGCValues values;
304
305   g_return_if_fail (GDK_IS_GC (gc));
306
307   values.subwindow_mode = mode;
308   gdk_gc_set_values (gc, &values, GDK_GC_SUBWINDOW);
309 }
310
311 void
312 gdk_gc_set_exposures (GdkGC     *gc,
313                       gboolean   exposures)
314 {
315   GdkGCValues values;
316
317   g_return_if_fail (GDK_IS_GC (gc));
318
319   values.graphics_exposures = exposures;
320   gdk_gc_set_values (gc, &values, GDK_GC_EXPOSURES);
321 }
322
323 void
324 gdk_gc_set_line_attributes (GdkGC       *gc,
325                             gint         line_width,
326                             GdkLineStyle line_style,
327                             GdkCapStyle  cap_style,
328                             GdkJoinStyle join_style)
329 {
330   GdkGCValues values;
331
332   values.line_width = line_width;
333   values.line_style = line_style;
334   values.cap_style = cap_style;
335   values.join_style = join_style;
336
337   gdk_gc_set_values (gc, &values,
338                      GDK_GC_LINE_WIDTH |
339                      GDK_GC_LINE_STYLE |
340                      GDK_GC_CAP_STYLE |
341                      GDK_GC_JOIN_STYLE);
342 }
343
344 void
345 gdk_gc_set_dashes (GdkGC *gc,
346                    gint   dash_offset,
347                    gint8  dash_list[],
348                    gint   n)
349 {
350   g_return_if_fail (GDK_IS_GC (gc));
351   g_return_if_fail (dash_list != NULL);
352
353   GDK_GC_GET_CLASS (gc)->set_dashes (gc, dash_offset, dash_list, n);
354 }
355
356 /**
357  * gdk_gc_set_colormap:
358  * @gc: a #GdkGC
359  * @colormap: a #GdkColormap
360  * 
361  * Sets the colormap for the GC to the given colormap. The depth
362  * of the colormap's visual must match the depth of the drawable
363  * for which the GC was created.
364  **/
365 void
366 gdk_gc_set_colormap (GdkGC       *gc,
367                      GdkColormap *colormap)
368 {
369   g_return_if_fail (GDK_IS_GC (gc));
370   g_return_if_fail (GDK_IS_COLORMAP (colormap));
371
372   if (gc->colormap != colormap)
373     {
374       if (gc->colormap)
375         g_object_unref (G_OBJECT (gc->colormap));
376
377       gc->colormap = colormap;
378       g_object_ref (G_OBJECT (gc->colormap));
379     }
380     
381 }
382
383 /**
384  * gdk_gc_get_colormap:
385  * @gc: a #GdkGC
386  * 
387  * Retrieves the colormap for a given GC, if it exists.
388  * A GC will have a colormap if the drawable for which it was created
389  * has a colormap, or if a colormap was set explicitely with
390  * gdk_gc_set_colormap.
391  * 
392  * Return value: 
393  **/
394 GdkColormap *
395 gdk_gc_get_colormap (GdkGC *gc)
396 {
397   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
398
399   return gc->colormap;
400 }
401
402 static GdkColormap *
403 gdk_gc_get_colormap_warn (GdkGC *gc)
404 {
405   GdkColormap *colormap = gdk_gc_get_colormap (gc);
406   if (!colormap)
407     {
408       g_warning ("gdk_gc_set_rgb_fg_color() and gdk_gc_set_rgb_bg_color() can\n"
409                  "only be used on GC's with a colormap. A GC will have a colormap\n"
410                  "if it is created for a drawable with a colormap, or if a\n"
411                  "colormap has been set explicitly with gdk_gc_set_colormap.\n");
412       return NULL;
413     }
414
415   return colormap;
416 }
417
418 /**
419  * gdk_gc_set_rgb_fg_color:
420  * @gc: a #GdkGC
421  * @color: an unallocated #GdkColor.
422  * 
423  * Set the foreground color of a GC using an unallocated color. The
424  * pixel value for the color will be determined using GdkRGB. If the
425  * colormap for the GC has not previously been initialized for GdkRGB,
426  * then for pseudo-color colormaps (colormaps with a small modifiable
427  * number of colors), a colorcube will be allocated in the colormap.
428  * 
429  * Calling this function for a GC without a colormap is an error.
430  **/
431 void
432 gdk_gc_set_rgb_fg_color (GdkGC *gc, GdkColor *color)
433 {
434   GdkColormap *cmap;
435   GdkColor tmp_color;
436
437   g_return_if_fail (GDK_IS_GC (gc));
438   g_return_if_fail (color != NULL);
439
440   cmap = gdk_gc_get_colormap_warn (gc);
441   if (!cmap)
442     return;
443
444   tmp_color = *color;
445   gdk_rgb_find_color (cmap, &tmp_color);
446   gdk_gc_set_foreground (gc, &tmp_color);
447 }
448
449 /**
450  * gdk_gc_set_rgb_bg_color:
451  * @gc: a #GdkGC
452  * @color: an unallocated #GdkColor.
453  * 
454  * Set the background color of a GC using an unallocated color. The
455  * pixel value for the color will be determined using GdkRGB. If the
456  * colormap for the GC has not previously been initialized for GdkRGB,
457  * then for pseudo-color colormaps (colormaps with a small modifiable
458  * number of colors), a colorcube will be allocated in the colormap.
459  * 
460  * Calling this function for a GC without a colormap is an error.
461  **/
462 void
463 gdk_gc_set_rgb_bg_color (GdkGC *gc, GdkColor *color)
464 {
465   GdkColormap *cmap;
466   GdkColor tmp_color;
467
468   g_return_if_fail (GDK_IS_GC (gc));
469   g_return_if_fail (color != NULL);
470
471   cmap = gdk_gc_get_colormap_warn (gc);
472   if (!cmap)
473     return;
474
475   tmp_color = *color;
476   gdk_rgb_find_color (cmap, &tmp_color);
477   gdk_gc_set_foreground (gc, &tmp_color);
478 }