1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gdkprivate.h"
25 gdk_gc_new (GdkWindow *window)
27 return gdk_gc_new_with_values (window, NULL, 0);
31 gdk_gc_new_with_values (GdkWindow *window,
33 GdkGCValuesMask values_mask)
35 GdkWindowPrivate *window_private;
37 GdkGCPrivate *private;
40 unsigned long xvalues_mask;
42 g_return_val_if_fail (window != NULL, NULL);
44 window_private = (GdkWindowPrivate*) window;
45 if (window_private->destroyed)
48 private = g_new (GdkGCPrivate, 1);
49 gc = (GdkGC*) private;
51 xwindow = window_private->xwindow;
52 private->xdisplay = window_private->xdisplay;
53 private->ref_count = 1;
55 xvalues.function = GXcopy;
56 xvalues.fill_style = FillSolid;
57 xvalues.arc_mode = ArcPieSlice;
58 xvalues.subwindow_mode = ClipByChildren;
59 xvalues.graphics_exposures = True;
60 xvalues_mask = GCFunction | GCFillStyle | GCArcMode | GCSubwindowMode | GCGraphicsExposures;
62 if (values_mask & GDK_GC_FOREGROUND)
64 xvalues.foreground = values->foreground.pixel;
65 xvalues_mask |= GCForeground;
67 if (values_mask & GDK_GC_BACKGROUND)
69 xvalues.background = values->background.pixel;
70 xvalues_mask |= GCBackground;
72 if ((values_mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT))
74 xvalues.font = ((XFontStruct *) ((GdkFontPrivate*) values->font)->xfont)->fid;
75 xvalues_mask |= GCFont;
77 if (values_mask & GDK_GC_FUNCTION)
79 switch (values->function)
82 xvalues.function = GXcopy;
85 xvalues.function = GXinvert;
88 xvalues.function = GXxor;
91 xvalues_mask |= GCFunction;
93 if (values_mask & GDK_GC_FILL)
98 xvalues.fill_style = FillSolid;
101 xvalues.fill_style = FillTiled;
104 xvalues.fill_style = FillStippled;
106 case GDK_OPAQUE_STIPPLED:
107 xvalues.fill_style = FillOpaqueStippled;
110 xvalues_mask |= GCFillStyle;
112 if (values_mask & GDK_GC_TILE)
114 xvalues.tile = ((GdkPixmapPrivate*) values->tile)->xwindow;
115 xvalues_mask |= GCTile;
117 if (values_mask & GDK_GC_STIPPLE)
119 xvalues.stipple = ((GdkPixmapPrivate*) values->stipple)->xwindow;
120 xvalues_mask |= GCStipple;
122 if (values_mask & GDK_GC_CLIP_MASK)
124 xvalues.clip_mask = ((GdkPixmapPrivate*) values->clip_mask)->xwindow;
125 xvalues_mask |= GCClipMask;
127 if (values_mask & GDK_GC_SUBWINDOW)
129 xvalues.subwindow_mode = values->subwindow_mode;
130 xvalues_mask |= GCSubwindowMode;
132 if (values_mask & GDK_GC_TS_X_ORIGIN)
134 xvalues.ts_x_origin = values->ts_x_origin;
135 xvalues_mask |= GCTileStipXOrigin;
137 if (values_mask & GDK_GC_TS_Y_ORIGIN)
139 xvalues.ts_y_origin = values->ts_y_origin;
140 xvalues_mask |= GCTileStipYOrigin;
142 if (values_mask & GDK_GC_CLIP_X_ORIGIN)
144 xvalues.clip_x_origin = values->clip_x_origin;
145 xvalues_mask |= GCClipXOrigin;
147 if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
149 xvalues.clip_y_origin = values->clip_y_origin;
150 xvalues_mask |= GCClipYOrigin;
153 if (values_mask & GDK_GC_EXPOSURES)
154 xvalues.graphics_exposures = values->graphics_exposures;
156 xvalues.graphics_exposures = False;
157 xvalues_mask |= GCGraphicsExposures;
159 if (values_mask & GDK_GC_LINE_WIDTH)
161 xvalues.line_width = values->line_width;
162 xvalues_mask |= GCLineWidth;
164 if (values_mask & GDK_GC_LINE_STYLE)
166 switch (values->line_style)
169 xvalues.line_style = LineSolid;
171 case GDK_LINE_ON_OFF_DASH:
172 xvalues.line_style = LineOnOffDash;
174 case GDK_LINE_DOUBLE_DASH:
175 xvalues.line_style = LineDoubleDash;
178 xvalues_mask |= GCLineStyle;
180 if (values_mask & GDK_GC_CAP_STYLE)
182 switch (values->cap_style)
184 case GDK_CAP_NOT_LAST:
185 xvalues.cap_style = CapNotLast;
188 xvalues.cap_style = CapButt;
191 xvalues.cap_style = CapRound;
193 case GDK_CAP_PROJECTING:
194 xvalues.cap_style = CapProjecting;
197 xvalues_mask |= GCCapStyle;
199 if (values_mask & GDK_GC_JOIN_STYLE)
201 switch (values->join_style)
204 xvalues.join_style = JoinMiter;
207 xvalues.join_style = JoinRound;
210 xvalues.join_style = JoinBevel;
213 xvalues_mask |= GCJoinStyle;
216 private->xgc = XCreateGC (private->xdisplay, xwindow, xvalues_mask, &xvalues);
222 gdk_gc_destroy (GdkGC *gc)
228 gdk_gc_ref (GdkGC *gc)
230 GdkGCPrivate *private = (GdkGCPrivate*) gc;
232 g_return_val_if_fail (gc != NULL, NULL);
233 private->ref_count += 1;
239 gdk_gc_unref (GdkGC *gc)
241 GdkGCPrivate *private = (GdkGCPrivate*) gc;
243 g_return_if_fail (gc != NULL);
245 if (private->ref_count > 1)
246 private->ref_count -= 1;
249 XFreeGC (private->xdisplay, private->xgc);
250 memset (gc, 0, sizeof (GdkGCPrivate));
256 gdk_gc_get_values (GdkGC *gc,
259 GdkGCPrivate *private;
262 g_return_if_fail (gc != NULL);
263 g_return_if_fail (values != NULL);
265 private = (GdkGCPrivate*) gc;
267 if (XGetGCValues (private->xdisplay, private->xgc,
268 GCForeground | GCBackground | GCFont |
269 GCFunction | GCTile | GCStipple | /* GCClipMask | */
270 GCSubwindowMode | GCGraphicsExposures |
271 GCTileStipXOrigin | GCTileStipYOrigin |
272 GCClipXOrigin | GCClipYOrigin |
273 GCLineWidth | GCLineStyle | GCCapStyle |
274 GCFillStyle | GCJoinStyle, &xvalues))
276 values->foreground.pixel = xvalues.foreground;
277 values->background.pixel = xvalues.background;
278 values->font = gdk_font_lookup (xvalues.font);
280 switch (xvalues.function)
283 values->function = GDK_COPY;
286 values->function = GDK_INVERT;
289 values->function = GDK_XOR;
293 switch (xvalues.fill_style)
296 values->fill = GDK_SOLID;
299 values->fill = GDK_TILED;
302 values->fill = GDK_STIPPLED;
304 case FillOpaqueStippled:
305 values->fill = GDK_OPAQUE_STIPPLED;
309 values->tile = gdk_pixmap_lookup (xvalues.tile);
310 values->stipple = gdk_pixmap_lookup (xvalues.stipple);
311 values->clip_mask = NULL;
312 values->subwindow_mode = xvalues.subwindow_mode;
313 values->ts_x_origin = xvalues.ts_x_origin;
314 values->ts_y_origin = xvalues.ts_y_origin;
315 values->clip_x_origin = xvalues.clip_x_origin;
316 values->clip_y_origin = xvalues.clip_y_origin;
317 values->graphics_exposures = xvalues.graphics_exposures;
318 values->line_width = xvalues.line_width;
320 switch (xvalues.line_style)
323 values->line_style = GDK_LINE_SOLID;
326 values->line_style = GDK_LINE_ON_OFF_DASH;
329 values->line_style = GDK_LINE_DOUBLE_DASH;
333 switch (xvalues.cap_style)
336 values->cap_style = GDK_CAP_NOT_LAST;
339 values->cap_style = GDK_CAP_BUTT;
342 values->cap_style = GDK_CAP_ROUND;
345 values->cap_style = GDK_CAP_PROJECTING;
349 switch (xvalues.join_style)
352 values->join_style = GDK_JOIN_MITER;
355 values->join_style = GDK_JOIN_ROUND;
358 values->join_style = GDK_JOIN_BEVEL;
364 memset (values, 0, sizeof (GdkGCValues));
369 gdk_gc_set_foreground (GdkGC *gc,
372 GdkGCPrivate *private;
374 g_return_if_fail (gc != NULL);
375 g_return_if_fail (color != NULL);
377 private = (GdkGCPrivate*) gc;
378 XSetForeground (private->xdisplay, private->xgc, color->pixel);
382 gdk_gc_set_background (GdkGC *gc,
385 GdkGCPrivate *private;
387 g_return_if_fail (gc != NULL);
388 g_return_if_fail (color != NULL);
390 private = (GdkGCPrivate*) gc;
391 XSetBackground (private->xdisplay, private->xgc, color->pixel);
395 gdk_gc_set_font (GdkGC *gc,
398 GdkGCPrivate *gc_private;
399 GdkFontPrivate *font_private;
401 g_return_if_fail (gc != NULL);
402 g_return_if_fail (font != NULL);
404 if (font->type == GDK_FONT_FONT)
406 gc_private = (GdkGCPrivate*) gc;
407 font_private = (GdkFontPrivate*) font;
409 XSetFont (gc_private->xdisplay, gc_private->xgc,
410 ((XFontStruct *) font_private->xfont)->fid);
415 gdk_gc_set_function (GdkGC *gc,
416 GdkFunction function)
418 GdkGCPrivate *private;
420 g_return_if_fail (gc != NULL);
422 private = (GdkGCPrivate*) gc;
427 XSetFunction (private->xdisplay, private->xgc, GXcopy);
430 XSetFunction (private->xdisplay, private->xgc, GXinvert);
433 XSetFunction (private->xdisplay, private->xgc, GXxor);
439 gdk_gc_set_fill (GdkGC *gc,
442 GdkGCPrivate *private;
444 g_return_if_fail (gc != NULL);
446 private = (GdkGCPrivate*) gc;
451 XSetFillStyle (private->xdisplay, private->xgc, FillSolid);
454 XSetFillStyle (private->xdisplay, private->xgc, FillTiled);
457 XSetFillStyle (private->xdisplay, private->xgc, FillStippled);
459 case GDK_OPAQUE_STIPPLED:
460 XSetFillStyle (private->xdisplay, private->xgc, FillOpaqueStippled);
466 gdk_gc_set_tile (GdkGC *gc,
469 GdkGCPrivate *private;
470 GdkPixmapPrivate *pixmap_private;
473 g_return_if_fail (gc != NULL);
475 private = (GdkGCPrivate*) gc;
480 pixmap_private = (GdkPixmapPrivate*) tile;
481 pixmap = pixmap_private->xwindow;
484 XSetTile (private->xdisplay, private->xgc, pixmap);
488 gdk_gc_set_stipple (GdkGC *gc,
491 GdkGCPrivate *private;
492 GdkPixmapPrivate *pixmap_private;
495 g_return_if_fail (gc != NULL);
497 private = (GdkGCPrivate*) gc;
502 pixmap_private = (GdkPixmapPrivate*) stipple;
503 pixmap = pixmap_private->xwindow;
506 XSetStipple (private->xdisplay, private->xgc, pixmap);
510 gdk_gc_set_ts_origin (GdkGC *gc,
514 GdkGCPrivate *private;
516 g_return_if_fail (gc != NULL);
518 private = (GdkGCPrivate*) gc;
520 XSetTSOrigin (private->xdisplay, private->xgc, x, y);
524 gdk_gc_set_clip_origin (GdkGC *gc,
528 GdkGCPrivate *private;
530 g_return_if_fail (gc != NULL);
532 private = (GdkGCPrivate*) gc;
534 XSetClipOrigin (private->xdisplay, private->xgc, x, y);
538 gdk_gc_set_clip_mask (GdkGC *gc,
541 GdkGCPrivate *private;
544 g_return_if_fail (gc != NULL);
548 GdkWindowPrivate *mask_private;
550 mask_private = (GdkWindowPrivate*) mask;
551 if (mask_private->destroyed)
553 xmask = mask_private->xwindow;
558 private = (GdkGCPrivate*) gc;
560 XSetClipMask (private->xdisplay, private->xgc, xmask);
565 gdk_gc_set_clip_rectangle (GdkGC *gc,
566 GdkRectangle *rectangle)
568 GdkGCPrivate *private;
569 XRectangle xrectangle;
571 g_return_if_fail (gc != NULL);
573 private = (GdkGCPrivate*) gc;
577 xrectangle.x = rectangle->x;
578 xrectangle.y = rectangle->y;
579 xrectangle.width = rectangle->width;
580 xrectangle.height = rectangle->height;
582 XSetClipRectangles (private->xdisplay, private->xgc, 0, 0,
583 &xrectangle, 1, Unsorted);
586 XSetClipMask (private->xdisplay, private->xgc, None);
590 gdk_gc_set_clip_region (GdkGC *gc,
593 GdkGCPrivate *private;
595 g_return_if_fail (gc != NULL);
597 private = (GdkGCPrivate*) gc;
601 GdkRegionPrivate *region_private;
603 region_private = (GdkRegionPrivate*) region;
604 XSetRegion (private->xdisplay, private->xgc, region_private->xregion);
607 XSetClipMask (private->xdisplay, private->xgc, None);
611 gdk_gc_set_subwindow (GdkGC *gc,
612 GdkSubwindowMode mode)
614 GdkGCPrivate *private;
616 g_return_if_fail (gc != NULL);
618 private = (GdkGCPrivate*) gc;
620 XSetSubwindowMode (private->xdisplay, private->xgc, mode);
624 gdk_gc_set_exposures (GdkGC *gc,
627 GdkGCPrivate *private;
629 g_return_if_fail (gc != NULL);
631 private = (GdkGCPrivate*) gc;
633 XSetGraphicsExposures (private->xdisplay, private->xgc, exposures);
637 gdk_gc_set_line_attributes (GdkGC *gc,
639 GdkLineStyle line_style,
640 GdkCapStyle cap_style,
641 GdkJoinStyle join_style)
643 GdkGCPrivate *private;
648 g_return_if_fail (gc != NULL);
650 private = (GdkGCPrivate*) gc;
655 xline_style = LineSolid;
657 case GDK_LINE_ON_OFF_DASH:
658 xline_style = LineOnOffDash;
660 case GDK_LINE_DOUBLE_DASH:
661 xline_style = LineDoubleDash;
669 case GDK_CAP_NOT_LAST:
670 xcap_style = CapNotLast;
673 xcap_style = CapButt;
676 xcap_style = CapRound;
678 case GDK_CAP_PROJECTING:
679 xcap_style = CapProjecting;
688 xjoin_style = JoinMiter;
691 xjoin_style = JoinRound;
694 xjoin_style = JoinBevel;
700 XSetLineAttributes (private->xdisplay, private->xgc, line_width,
701 xline_style, xcap_style, xjoin_style);
705 gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc)
707 GdkGCPrivate *dst_private, *src_private;
709 src_private = (GdkGCPrivate *) src_gc;
710 dst_private = (GdkGCPrivate *) dst_gc;
712 XCopyGC (src_private->xdisplay, src_private->xgc, ~((~1) << GCLastBit),