?? gdkgc-x11.c
字號:
/* 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 Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include <config.h>#include "gdkgc.h"#include "gdkprivate-x11.h"#include "gdkregion-generic.h"#include "gdkx.h"#include "gdkalias.h"#include <string.h>typedef enum { GDK_GC_DIRTY_CLIP = 1 << 0, GDK_GC_DIRTY_TS = 1 << 1} GdkGCDirtyValues;static void gdk_x11_gc_values_to_xvalues (GdkGCValues *values, GdkGCValuesMask mask, XGCValues *xvalues, unsigned long *xvalues_mask);static void gdk_x11_gc_get_values (GdkGC *gc, GdkGCValues *values);static void gdk_x11_gc_set_values (GdkGC *gc, GdkGCValues *values, GdkGCValuesMask values_mask);static void gdk_x11_gc_set_dashes (GdkGC *gc, gint dash_offset, gint8 dash_list[], gint n);static void gdk_gc_x11_class_init (GdkGCX11Class *klass);static void gdk_gc_x11_finalize (GObject *object);static gpointer parent_class = NULL;GType_gdk_gc_x11_get_type (void){ static GType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (GdkGCX11Class), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gdk_gc_x11_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GdkGCX11), 0, /* n_preallocs */ (GInstanceInitFunc) NULL, }; object_type = g_type_register_static (GDK_TYPE_GC, "GdkGCX11", &object_info, 0); } return object_type;}static voidgdk_gc_x11_class_init (GdkGCX11Class *klass){ GObjectClass *object_class = G_OBJECT_CLASS (klass); GdkGCClass *gc_class = GDK_GC_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->finalize = gdk_gc_x11_finalize; gc_class->get_values = gdk_x11_gc_get_values; gc_class->set_values = gdk_x11_gc_set_values; gc_class->set_dashes = gdk_x11_gc_set_dashes;}static voidgdk_gc_x11_finalize (GObject *object){ GdkGCX11 *x11_gc = GDK_GC_X11 (object); if (x11_gc->clip_region) gdk_region_destroy (x11_gc->clip_region); if (x11_gc->fg_picture != None) XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), x11_gc->fg_picture); if (x11_gc->stipple) g_object_unref (x11_gc->stipple); if (x11_gc->tile) g_object_unref (x11_gc->tile); XFreeGC (GDK_GC_XDISPLAY (x11_gc), GDK_GC_XGC (x11_gc)); G_OBJECT_CLASS (parent_class)->finalize (object);}GdkGC *_gdk_x11_gc_new (GdkDrawable *drawable, GdkGCValues *values, GdkGCValuesMask values_mask){ GdkGC *gc; GdkGCX11 *private; XGCValues xvalues; unsigned long xvalues_mask; /* NOTICE that the drawable here has to be the impl drawable, * not the publically-visible drawables. */ g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_X11 (drawable), NULL); gc = g_object_new (_gdk_gc_x11_get_type (), NULL); private = GDK_GC_X11 (gc); private->dirty_mask = 0; private->have_clip_mask = FALSE; private->clip_region = NULL; private->screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen; private->depth = gdk_drawable_get_depth (drawable); if (values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN)) { values_mask &= ~(GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN); private->dirty_mask |= GDK_GC_DIRTY_CLIP; } if (values_mask & (GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN)) { values_mask &= ~(GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN); private->dirty_mask |= GDK_GC_DIRTY_TS; } if (values_mask & GDK_GC_FOREGROUND) private->fg_pixel = values->foreground.pixel; if (values_mask & GDK_GC_BACKGROUND) private->bg_pixel = values->background.pixel; if (values_mask & GDK_GC_FILL) private->fill = values->fill; if (values_mask & GDK_GC_STIPPLE) { private->stipple = values->stipple; if (private->stipple) g_object_ref (private->stipple); } if (values_mask & GDK_GC_TILE) { private->tile = values->tile; if (private->tile) g_object_ref (private->tile); } if ((values_mask & GDK_GC_CLIP_MASK) && values->clip_mask) private->have_clip_mask = TRUE; xvalues.function = GXcopy; xvalues.fill_style = FillSolid; xvalues.arc_mode = ArcPieSlice; xvalues.subwindow_mode = ClipByChildren; xvalues.graphics_exposures = False; xvalues_mask = GCFunction | GCFillStyle | GCArcMode | GCSubwindowMode | GCGraphicsExposures; gdk_x11_gc_values_to_xvalues (values, values_mask, &xvalues, &xvalues_mask); private->xgc = XCreateGC (GDK_GC_XDISPLAY (gc), GDK_DRAWABLE_IMPL_X11 (drawable)->xid, xvalues_mask, &xvalues); return gc;}GC_gdk_x11_gc_flush (GdkGC *gc){ Display *xdisplay = GDK_GC_XDISPLAY (gc); GdkGCX11 *private = GDK_GC_X11 (gc); GC xgc = private->xgc; if (private->dirty_mask & GDK_GC_DIRTY_CLIP) { if (!private->clip_region) XSetClipOrigin (xdisplay, xgc, gc->clip_x_origin, gc->clip_y_origin); else { XRectangle *rectangles; gint n_rects; _gdk_region_get_xrectangles (private->clip_region, gc->clip_x_origin, gc->clip_y_origin, &rectangles, &n_rects); XSetClipRectangles (xdisplay, xgc, 0, 0, rectangles, n_rects, YXBanded); g_free (rectangles); } } if (private->dirty_mask & GDK_GC_DIRTY_TS) { XSetTSOrigin (xdisplay, xgc, gc->ts_x_origin, gc->ts_y_origin); } private->dirty_mask = 0; return xgc;}static voidgdk_x11_gc_get_values (GdkGC *gc, GdkGCValues *values){ XGCValues xvalues; if (XGetGCValues (GDK_GC_XDISPLAY (gc), GDK_GC_XGC (gc), 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_for_display (GDK_GC_DISPLAY (gc), 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; case GXclear: values->function = GDK_CLEAR; break; case GXand: values->function = GDK_AND; break; case GXandReverse: values->function = GDK_AND_REVERSE; break; case GXandInverted: values->function = GDK_AND_INVERT; break; case GXnoop: values->function = GDK_NOOP; break; case GXor: values->function = GDK_OR; break; case GXequiv: values->function = GDK_EQUIV; break; case GXorReverse: values->function = GDK_OR_REVERSE; break; case GXcopyInverted: values->function =GDK_COPY_INVERT; break; case GXorInverted: values->function = GDK_OR_INVERT; break; case GXnand: values->function = GDK_NAND; break; case GXset: values->function = GDK_SET; break; case GXnor: values->function = GDK_NOR; 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_for_display (GDK_GC_DISPLAY (gc), xvalues.tile); values->stipple = gdk_pixmap_lookup_for_display (GDK_GC_DISPLAY (gc), 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)); }}static voidclear_fg_picture (GdkGC *gc){ GdkGCX11 *x11_gc = GDK_GC_X11 (gc); if (x11_gc->fg_picture != None) { XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), x11_gc->fg_picture); x11_gc->fg_picture = None; }}static voidgdk_x11_gc_set_values (GdkGC *gc, GdkGCValues *values, GdkGCValuesMask values_mask){ GdkGCX11 *x11_gc; XGCValues xvalues; unsigned long xvalues_mask = 0; x11_gc = GDK_GC_X11 (gc); if (values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN)) { values_mask &= ~(GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN); x11_gc->dirty_mask |= GDK_GC_DIRTY_CLIP; } if (values_mask & (GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN)) { values_mask &= ~(GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN); x11_gc->dirty_mask |= GDK_GC_DIRTY_TS; } if (values_mask & GDK_GC_CLIP_MASK) { if (x11_gc->clip_region) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -