diff options
Diffstat (limited to 'gdk/gdkgc.c')
-rw-r--r-- | gdk/gdkgc.c | 636 |
1 files changed, 636 insertions, 0 deletions
diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c new file mode 100644 index 000000000..3dc11ce6c --- /dev/null +++ b/gdk/gdkgc.c @@ -0,0 +1,636 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <string.h> +#include <X11/Xlib.h> +#include "gdk.h" +#include "gdkprivate.h" + + +GdkGC* +gdk_gc_new (GdkWindow *window) +{ + return gdk_gc_new_with_values (window, NULL, 0); +} + +GdkGC* +gdk_gc_new_with_values (GdkWindow *window, + GdkGCValues *values, + GdkGCValuesMask values_mask) +{ + GdkGC *gc; + GdkGCPrivate *private; + Window xwindow; + XGCValues xvalues; + unsigned long xvalues_mask; + + private = g_new (GdkGCPrivate, 1); + gc = (GdkGC*) private; + + xwindow = ((GdkWindowPrivate*) window)->xwindow; + private->xdisplay = ((GdkWindowPrivate*) window)->xdisplay; + + xvalues.function = GXcopy; + xvalues.fill_style = FillSolid; + xvalues.arc_mode = ArcPieSlice; + xvalues.subwindow_mode = ClipByChildren; + xvalues.graphics_exposures = True; + xvalues_mask = GCFunction | GCFillStyle | GCArcMode | GCSubwindowMode | GCGraphicsExposures; + + if (values_mask & GDK_GC_FOREGROUND) + { + xvalues.foreground = values->foreground.pixel; + xvalues_mask |= GCForeground; + } + if (values_mask & GDK_GC_BACKGROUND) + { + xvalues.background = values->background.pixel; + xvalues_mask |= GCBackground; + } + if ((values_mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT)) + { + xvalues.font = ((XFontStruct *) ((GdkFontPrivate*) values->font)->xfont)->fid; + xvalues_mask |= GCFont; + } + if (values_mask & GDK_GC_FUNCTION) + { + switch (values->function) + { + case GDK_COPY: + xvalues.function = GXcopy; + break; + case GDK_INVERT: + xvalues.function = GXinvert; + break; + case GDK_XOR: + xvalues.function = GXxor; + break; + } + xvalues_mask |= GCFunction; + } + if (values_mask & GDK_GC_FILL) + { + switch (values->fill) + { + case GDK_SOLID: + xvalues.fill_style = FillSolid; + break; + case GDK_TILED: + xvalues.fill_style = FillTiled; + break; + case GDK_STIPPLED: + xvalues.fill_style = FillStippled; + break; + case GDK_OPAQUE_STIPPLED: + xvalues.fill_style = FillOpaqueStippled; + break; + } + xvalues_mask |= GCFillStyle; + } + if (values_mask & GDK_GC_TILE) + { + xvalues.tile = ((GdkPixmapPrivate*) values->tile)->xwindow; + xvalues_mask |= GCTile; + } + if (values_mask & GDK_GC_STIPPLE) + { + xvalues.stipple = ((GdkPixmapPrivate*) values->stipple)->xwindow; + xvalues_mask |= GCStipple; + } + if (values_mask & GDK_GC_CLIP_MASK) + { + xvalues.clip_mask = ((GdkPixmapPrivate*) values->clip_mask)->xwindow; + xvalues_mask |= GCClipMask; + } + if (values_mask & GDK_GC_SUBWINDOW) + { + xvalues.subwindow_mode = values->subwindow_mode; + xvalues_mask |= GCSubwindowMode; + } + if (values_mask & GDK_GC_TS_X_ORIGIN) + { + xvalues.ts_x_origin = values->ts_x_origin; + xvalues_mask |= GCTileStipXOrigin; + } + if (values_mask & GDK_GC_TS_Y_ORIGIN) + { + xvalues.ts_y_origin = values->ts_y_origin; + xvalues_mask |= GCTileStipYOrigin; + } + if (values_mask & GDK_GC_CLIP_X_ORIGIN) + { + xvalues.clip_x_origin = values->clip_x_origin; + xvalues_mask |= GCClipXOrigin; + } + if (values_mask & GDK_GC_CLIP_Y_ORIGIN) + { + xvalues.clip_y_origin = values->clip_y_origin; + xvalues_mask |= GCClipYOrigin; + } + if (values_mask & GDK_GC_EXPOSURES) + { + xvalues.graphics_exposures = values->graphics_exposures; + xvalues_mask |= GCGraphicsExposures; + } + if (values_mask & GDK_GC_LINE_WIDTH) + { + xvalues.line_width = values->line_width; + xvalues_mask |= GCLineWidth; + } + if (values_mask & GDK_GC_LINE_STYLE) + { + switch (values->line_style) + { + case GDK_LINE_SOLID: + xvalues.line_style = LineSolid; + break; + case GDK_LINE_ON_OFF_DASH: + xvalues.line_style = LineOnOffDash; + break; + case GDK_LINE_DOUBLE_DASH: + xvalues.line_style = LineDoubleDash; + break; + } + xvalues_mask |= GCLineStyle; + } + if (values_mask & GDK_GC_CAP_STYLE) + { + switch (values->cap_style) + { + case GDK_CAP_NOT_LAST: + xvalues.cap_style = CapNotLast; + break; + case GDK_CAP_BUTT: + xvalues.cap_style = CapButt; + break; + case GDK_CAP_ROUND: + xvalues.cap_style = CapRound; + break; + case GDK_CAP_PROJECTING: + xvalues.cap_style = CapProjecting; + break; + } + xvalues_mask |= GCCapStyle; + } + if (values_mask & GDK_GC_JOIN_STYLE) + { + switch (values->join_style) + { + case GDK_JOIN_MITER: + xvalues.join_style = JoinMiter; + break; + case GDK_JOIN_ROUND: + xvalues.join_style = JoinRound; + break; + case GDK_JOIN_BEVEL: + xvalues.join_style = JoinBevel; + break; + } + xvalues_mask |= GCJoinStyle; + } + + private->xgc = XCreateGC (private->xdisplay, xwindow, xvalues_mask, &xvalues); + + return gc; +} + +void +gdk_gc_destroy (GdkGC *gc) +{ + GdkGCPrivate *private; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + XFreeGC (private->xdisplay, private->xgc); + + memset (gc, 0, sizeof (GdkGCPrivate)); + g_free (gc); +} + +void +gdk_gc_get_values (GdkGC *gc, + GdkGCValues *values) +{ + GdkGCPrivate *private; + XGCValues xvalues; + + g_return_if_fail (gc != NULL); + g_return_if_fail (values != NULL); + + private = (GdkGCPrivate*) gc; + + if (XGetGCValues (private->xdisplay, private->xgc, + GCForeground | GCBackground | GCFont | + GCFunction | GCTile | GCStipple | /* GCClipMask | */ + GCSubwindowMode | GCGraphicsExposures | + GCTileStipXOrigin | GCTileStipYOrigin | + GCClipXOrigin | GCClipYOrigin | + GCLineWidth | GCLineStyle | GCCapStyle | + GCFillStyle | GCJoinStyle, &xvalues)) + { + values->foreground.pixel = xvalues.foreground; + values->background.pixel = xvalues.background; + values->font = gdk_font_lookup (xvalues.font); + + switch (xvalues.function) + { + case GXcopy: + values->function = GDK_COPY; + break; + case GXinvert: + values->function = GDK_INVERT; + break; + case GXxor: + values->function = GDK_XOR; + break; + } + + switch (xvalues.fill_style) + { + case FillSolid: + values->fill = GDK_SOLID; + break; + case FillTiled: + values->fill = GDK_TILED; + break; + case FillStippled: + values->fill = GDK_STIPPLED; + break; + case FillOpaqueStippled: + values->fill = GDK_OPAQUE_STIPPLED; + break; + } + + values->tile = gdk_pixmap_lookup (xvalues.tile); + values->stipple = gdk_pixmap_lookup (xvalues.stipple); + values->clip_mask = NULL; + values->subwindow_mode = xvalues.subwindow_mode; + values->ts_x_origin = xvalues.ts_x_origin; + values->ts_y_origin = xvalues.ts_y_origin; + values->clip_x_origin = xvalues.clip_x_origin; + values->clip_y_origin = xvalues.clip_y_origin; + values->graphics_exposures = xvalues.graphics_exposures; + values->line_width = xvalues.line_width; + + switch (xvalues.line_style) + { + case LineSolid: + values->line_style = GDK_LINE_SOLID; + break; + case LineOnOffDash: + values->line_style = GDK_LINE_ON_OFF_DASH; + break; + case LineDoubleDash: + values->line_style = GDK_LINE_DOUBLE_DASH; + break; + } + + switch (xvalues.cap_style) + { + case CapNotLast: + values->cap_style = GDK_CAP_NOT_LAST; + break; + case CapButt: + values->cap_style = GDK_CAP_BUTT; + break; + case CapRound: + values->cap_style = GDK_CAP_ROUND; + break; + case CapProjecting: + values->cap_style = GDK_CAP_PROJECTING; + break; + } + + switch (xvalues.join_style) + { + case JoinMiter: + values->join_style = GDK_JOIN_MITER; + break; + case JoinRound: + values->join_style = GDK_JOIN_ROUND; + break; + case JoinBevel: + values->join_style = GDK_JOIN_BEVEL; + break; + } + } + else + { + memset (values, 0, sizeof (GdkGCValues)); + } +} + +void +gdk_gc_set_foreground (GdkGC *gc, + GdkColor *color) +{ + GdkGCPrivate *private; + + g_return_if_fail (gc != NULL); + g_return_if_fail (color != NULL); + + private = (GdkGCPrivate*) gc; + XSetForeground (private->xdisplay, private->xgc, color->pixel); +} + +void +gdk_gc_set_background (GdkGC *gc, + GdkColor *color) +{ + GdkGCPrivate *private; + + g_return_if_fail (gc != NULL); + g_return_if_fail (color != NULL); + + private = (GdkGCPrivate*) gc; + XSetBackground (private->xdisplay, private->xgc, color->pixel); +} + +void +gdk_gc_set_font (GdkGC *gc, + GdkFont *font) +{ + GdkGCPrivate *gc_private; + GdkFontPrivate *font_private; + + g_return_if_fail (gc != NULL); + g_return_if_fail (font != NULL); + + gc_private = (GdkGCPrivate*) gc; + font_private = (GdkFontPrivate*) font; + + XSetFont (gc_private->xdisplay, gc_private->xgc, + ((XFontStruct *) font_private->xfont)->fid); +} + +void +gdk_gc_set_function (GdkGC *gc, + GdkFunction function) +{ + GdkGCPrivate *private; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + switch (function) + { + case GDK_COPY: + XSetFunction (private->xdisplay, private->xgc, GXcopy); + break; + case GDK_INVERT: + XSetFunction (private->xdisplay, private->xgc, GXinvert); + break; + case GDK_XOR: + XSetFunction (private->xdisplay, private->xgc, GXor); + break; + } +} + +void +gdk_gc_set_fill (GdkGC *gc, + GdkFill fill) +{ + GdkGCPrivate *private; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + switch (fill) + { + case GDK_SOLID: + XSetFillStyle (private->xdisplay, private->xgc, FillSolid); + break; + case GDK_TILED: + XSetFillStyle (private->xdisplay, private->xgc, FillTiled); + break; + case GDK_STIPPLED: + XSetFillStyle (private->xdisplay, private->xgc, FillStippled); + break; + case GDK_OPAQUE_STIPPLED: + XSetFillStyle (private->xdisplay, private->xgc, FillOpaqueStippled); + break; + } +} + +void +gdk_gc_set_tile (GdkGC *gc, + GdkPixmap *tile) +{ + GdkGCPrivate *private; + GdkPixmapPrivate *pixmap_private; + Pixmap pixmap; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + pixmap = None; + if (tile) + { + pixmap_private = (GdkPixmapPrivate*) tile; + pixmap = pixmap_private->xwindow; + } + + XSetTile (private->xdisplay, private->xgc, pixmap); +} + +void +gdk_gc_set_stipple (GdkGC *gc, + GdkPixmap *stipple) +{ + GdkGCPrivate *private; + GdkPixmapPrivate *pixmap_private; + Pixmap pixmap; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + pixmap = None; + if (stipple) + { + pixmap_private = (GdkPixmapPrivate*) stipple; + pixmap = pixmap_private->xwindow; + } + + XSetStipple (private->xdisplay, private->xgc, pixmap); +} + +void +gdk_gc_set_ts_origin (GdkGC *gc, + gint x, + gint y) +{ + GdkGCPrivate *private; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + XSetTSOrigin (private->xdisplay, private->xgc, x, y); +} + +void +gdk_gc_set_clip_origin (GdkGC *gc, + gint x, + gint y) +{ + GdkGCPrivate *private; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + XSetClipOrigin (private->xdisplay, private->xgc, x, y); +} + +void +gdk_gc_set_clip_mask (GdkGC *gc, + GdkBitmap *mask) +{ + GdkGCPrivate *private; + Pixmap xmask; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + if (mask) + xmask = ((GdkWindowPrivate*) mask)->xwindow; + else + xmask = None; + + XSetClipMask (private->xdisplay, private->xgc, xmask); +} + + +void +gdk_gc_set_clip_rectangle (GdkGC *gc, + GdkRectangle *rectangle) +{ + GdkGCPrivate *private; + XRectangle xrectangle; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + xrectangle.x = rectangle->x; + xrectangle.y = rectangle->y; + xrectangle.width = rectangle->width; + xrectangle.height = rectangle->height; + + XSetClipRectangles (private->xdisplay, private->xgc, 0, 0, + &xrectangle, 1, Unsorted); +} + +void +gdk_gc_set_subwindow (GdkGC *gc, + GdkSubwindowMode mode) +{ + GdkGCPrivate *private; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + XSetSubwindowMode (private->xdisplay, private->xgc, mode); +} + +void +gdk_gc_set_exposures (GdkGC *gc, + gint exposures) +{ + GdkGCPrivate *private; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + XSetGraphicsExposures (private->xdisplay, private->xgc, exposures); +} + +void +gdk_gc_set_line_attributes (GdkGC *gc, + gint line_width, + GdkLineStyle line_style, + GdkCapStyle cap_style, + GdkJoinStyle join_style) +{ + GdkGCPrivate *private; + int xline_style; + int xcap_style; + int xjoin_style; + + g_return_if_fail (gc != NULL); + + private = (GdkGCPrivate*) gc; + + switch (line_style) + { + case GDK_LINE_SOLID: + xline_style = LineSolid; + break; + case GDK_LINE_ON_OFF_DASH: + xline_style = LineOnOffDash; + break; + case GDK_LINE_DOUBLE_DASH: + xline_style = LineDoubleDash; + break; + default: + xline_style = None; + } + + switch (cap_style) + { + case GDK_CAP_NOT_LAST: + xcap_style = CapNotLast; + break; + case GDK_CAP_BUTT: + xcap_style = CapButt; + break; + case GDK_CAP_ROUND: + xcap_style = CapRound; + break; + case GDK_CAP_PROJECTING: + xcap_style = CapProjecting; + break; + default: + xcap_style = None; + } + + switch (join_style) + { + case GDK_JOIN_MITER: + xjoin_style = JoinMiter; + break; + case GDK_JOIN_ROUND: + xjoin_style = JoinRound; + break; + case GDK_JOIN_BEVEL: + xjoin_style = JoinBevel; + break; + default: + xjoin_style = None; + } + + XSetLineAttributes (private->xdisplay, private->xgc, line_width, + xline_style, xcap_style, xjoin_style); +} |