📄 gdkdrawable-x11.c
字号:
/* 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 "gdkx.h"#include "gdkregion-generic.h"#include <pango/pangoxft.h>#include <stdlib.h>#include <string.h> /* for memcpy() */#if defined (HAVE_IPC_H) && defined (HAVE_SHM_H) && defined (HAVE_XSHM_H)#define USE_SHM#endif#ifdef USE_SHM#include <X11/extensions/XShm.h>#endif /* USE_SHM */#include "gdkprivate-x11.h"#include "gdkdrawable-x11.h"#include "gdkpixmap-x11.h"#include "gdkscreen-x11.h"#include "gdkdisplay-x11.h"#include "gdkalias.h"static void gdk_x11_draw_rectangle (GdkDrawable *drawable, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height);static void gdk_x11_draw_arc (GdkDrawable *drawable, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height, gint angle1, gint angle2);static void gdk_x11_draw_polygon (GdkDrawable *drawable, GdkGC *gc, gboolean filled, GdkPoint *points, gint npoints);static void gdk_x11_draw_text (GdkDrawable *drawable, GdkFont *font, GdkGC *gc, gint x, gint y, const gchar *text, gint text_length);static void gdk_x11_draw_text_wc (GdkDrawable *drawable, GdkFont *font, GdkGC *gc, gint x, gint y, const GdkWChar *text, gint text_length);static void gdk_x11_draw_drawable (GdkDrawable *drawable, GdkGC *gc, GdkPixmap *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height);static void gdk_x11_draw_points (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, gint npoints);static void gdk_x11_draw_segments (GdkDrawable *drawable, GdkGC *gc, GdkSegment *segs, gint nsegs);static void gdk_x11_draw_lines (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, gint npoints);static void gdk_x11_draw_glyphs (GdkDrawable *drawable, GdkGC *gc, PangoFont *font, gint x, gint y, PangoGlyphString *glyphs);static void gdk_x11_draw_glyphs_transformed (GdkDrawable *drawable, GdkGC *gc, PangoMatrix *matrix, PangoFont *font, gint x, gint y, PangoGlyphString *glyphs);static void gdk_x11_draw_image (GdkDrawable *drawable, GdkGC *gc, GdkImage *image, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height);static void gdk_x11_draw_pixbuf (GdkDrawable *drawable, GdkGC *gc, GdkPixbuf *pixbuf, gint src_x, gint src_y, gint dest_x, gint dest_y, gint width, gint height, GdkRgbDither dither, gint x_dither, gint y_dither);static void gdk_x11_draw_trapezoids (GdkDrawable *drawable, GdkGC *gc, GdkTrapezoid *trapezoids, gint n_trapezoids);static void gdk_x11_set_colormap (GdkDrawable *drawable, GdkColormap *colormap);static GdkColormap* gdk_x11_get_colormap (GdkDrawable *drawable);static gint gdk_x11_get_depth (GdkDrawable *drawable);static GdkScreen * gdk_x11_get_screen (GdkDrawable *drawable);static GdkVisual* gdk_x11_get_visual (GdkDrawable *drawable);static void gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass);static void gdk_drawable_impl_x11_finalize (GObject *object);static gpointer parent_class = NULL;GType_gdk_drawable_impl_x11_get_type (void){ static GType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (GdkDrawableImplX11Class), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gdk_drawable_impl_x11_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GdkDrawableImplX11), 0, /* n_preallocs */ (GInstanceInitFunc) NULL, }; object_type = g_type_register_static (GDK_TYPE_DRAWABLE, "GdkDrawableImplX11", &object_info, 0); } return object_type;}static voidgdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass){ GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->finalize = gdk_drawable_impl_x11_finalize; drawable_class->create_gc = _gdk_x11_gc_new; drawable_class->draw_rectangle = gdk_x11_draw_rectangle; drawable_class->draw_arc = gdk_x11_draw_arc; drawable_class->draw_polygon = gdk_x11_draw_polygon; drawable_class->draw_text = gdk_x11_draw_text; drawable_class->draw_text_wc = gdk_x11_draw_text_wc; drawable_class->draw_drawable = gdk_x11_draw_drawable; drawable_class->draw_points = gdk_x11_draw_points; drawable_class->draw_segments = gdk_x11_draw_segments; drawable_class->draw_lines = gdk_x11_draw_lines; drawable_class->draw_glyphs = gdk_x11_draw_glyphs; drawable_class->draw_glyphs_transformed = gdk_x11_draw_glyphs_transformed; drawable_class->draw_image = gdk_x11_draw_image; drawable_class->draw_pixbuf = gdk_x11_draw_pixbuf; drawable_class->draw_trapezoids = gdk_x11_draw_trapezoids; drawable_class->set_colormap = gdk_x11_set_colormap; drawable_class->get_colormap = gdk_x11_get_colormap; drawable_class->get_depth = gdk_x11_get_depth; drawable_class->get_screen = gdk_x11_get_screen; drawable_class->get_visual = gdk_x11_get_visual; drawable_class->_copy_to_image = _gdk_x11_copy_to_image;}static voidgdk_drawable_impl_x11_finalize (GObject *object){ gdk_drawable_set_colormap (GDK_DRAWABLE (object), NULL); G_OBJECT_CLASS (parent_class)->finalize (object);}static voidtry_pixmap (Display *xdisplay, int screen, int depth){ Pixmap pixmap = XCreatePixmap (xdisplay, RootWindow (xdisplay, screen), 1, 1, depth); XFreePixmap (xdisplay, pixmap);}gboolean_gdk_x11_have_render (GdkDisplay *display){ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); GdkDisplayX11 *x11display = GDK_DISPLAY_X11 (display); if (x11display->have_render == GDK_UNKNOWN) { int event_base, error_base; x11display->have_render = XRenderQueryExtension (xdisplay, &event_base, &error_base) ? GDK_YES : GDK_NO; if (x11display->have_render == GDK_YES) { /* * Sun advertises RENDER, but fails to support 32-bit pixmaps. * That is just no good. Therefore, we check all screens * for proper support. */ int screen; for (screen = 0; screen < ScreenCount (xdisplay); screen++) { int count; int *depths = XListDepths (xdisplay, screen, &count); gboolean has_8 = FALSE, has_32 = FALSE; if (depths) { int i; for (i = 0; i < count; i++) { if (depths[i] == 8) has_8 = TRUE; else if (depths[i] == 32) has_32 = TRUE; } XFree (depths); } /* At this point, we might have a false positive; * buggy versions of Xinerama only report depths for * which there is an associated visual; so we actually * go ahead and try create pixmaps. */ if (!(has_8 && has_32)) { gdk_error_trap_push (); if (!has_8) try_pixmap (xdisplay, screen, 8); if (!has_32) try_pixmap (xdisplay, screen, 32); XSync (xdisplay, False); if (gdk_error_trap_pop () == 0) { has_8 = TRUE; has_32 = TRUE; } } if (!(has_8 && has_32)) { g_warning ("The X server advertises that RENDER support is present,\n" "but fails to supply the necessary pixmap support. In\n" "other words, it is buggy."); x11display->have_render = GDK_NO; break; } } } } return x11display->have_render == GDK_YES;}gboolean_gdk_x11_have_render_with_trapezoids (GdkDisplay *display){ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); GdkDisplayX11 *x11display = GDK_DISPLAY_X11 (display); if (x11display->have_render_with_trapezoids == GDK_UNKNOWN) { x11display->have_render_with_trapezoids = GDK_NO; if (_gdk_x11_have_render (display)) { /* * Require protocol >= 0.4 for CompositeTrapezoids support. */ int major_version, minor_version; #define XRENDER_TETRAPEZOIDS_MAJOR 0#define XRENDER_TETRAPEZOIDS_MINOR 4 if (XRenderQueryVersion (xdisplay, &major_version, &minor_version)) if ((major_version == XRENDER_TETRAPEZOIDS_MAJOR) && (minor_version >= XRENDER_TETRAPEZOIDS_MINOR)) x11display->have_render_with_trapezoids = GDK_YES; } } return x11display->have_render_with_trapezoids == GDK_YES;}static XftDraw *gdk_x11_drawable_get_xft_draw (GdkDrawable *drawable){ GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable); if (impl->xft_draw == NULL) { GdkColormap *colormap = gdk_drawable_get_colormap (drawable); if (colormap) { GdkVisual *visual; visual = gdk_colormap_get_visual (colormap); impl->xft_draw = XftDrawCreate (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_VISUAL_XVISUAL (visual), GDK_COLORMAP_XCOLORMAP (colormap)); } else if (gdk_drawable_get_depth (drawable) == 1) { impl->xft_draw = XftDrawCreateBitmap (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid); } else { g_warning ("Using Xft rendering requires the drawable argument to\n" "have a specified colormap. All windows have a colormap,\n" "however, pixmaps only have colormap by default if they\n" "were created with a non-NULL window argument. Otherwise\n" "a colormap must be set on them with gdk_drawable_set_colormap"); return NULL; } } return impl->xft_draw;}static Picturegdk_x11_drawable_get_picture (GdkDrawable *drawable){ XftDraw *draw = gdk_x11_drawable_get_xft_draw (drawable); return draw ? XftDrawPicture (draw) : None;}static voidgdk_x11_drawable_update_xft_clip (GdkDrawable *drawable, GdkGC *gc){ GdkGCX11 *gc_private = gc ? GDK_GC_X11 (gc) : NULL; XftDraw *xft_draw = gdk_x11_drawable_get_xft_draw (drawable); if (gc && gc_private->clip_region) { GdkRegionBox *boxes = gc_private->clip_region->rects; gint n_boxes = gc_private->clip_region->numRects;#if 0 /* Until XftDrawSetClipRectangles is there */ XRectangle *rects = g_new (XRectangle, n_boxes); int i; for (i=0; i < n_boxes; i++) { rects[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT); rects[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT); rects[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x; rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y; } XftDrawSetClipRectangles (xft_draw, 0, 0, rects, n_boxes); g_free (rects);#else Region xregion = XCreateRegion (); int i; for (i=0; i < n_boxes; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -