Blame gdk/x11/gdkdrawable-x11.c

Packit Service fb6fa5
/* GIMP Drawing Kit
Packit Service fb6fa5
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit Service fb6fa5
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit Service fb6fa5
 * files for a list of changes.  These files are distributed with
Packit Service fb6fa5
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
Packit Service fb6fa5
#include "gdkx.h"
Packit Service fb6fa5
#include "gdkregion-generic.h"
Packit Service fb6fa5
Packit Service fb6fa5
#include <cairo-xlib.h>
Packit Service fb6fa5
Packit Service fb6fa5
#include <stdlib.h>
Packit Service fb6fa5
#include <string.h>		/* for memcpy() */
Packit Service fb6fa5
Packit Service fb6fa5
#if defined (HAVE_IPC_H) && defined (HAVE_SHM_H) && defined (HAVE_XSHM_H)
Packit Service fb6fa5
#define USE_SHM
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef USE_SHM
Packit Service fb6fa5
#include <X11/extensions/XShm.h>
Packit Service fb6fa5
#endif /* USE_SHM */
Packit Service fb6fa5
Packit Service fb6fa5
#include "gdkprivate-x11.h"
Packit Service fb6fa5
#include "gdkdrawable-x11.h"
Packit Service fb6fa5
#include "gdkpixmap-x11.h"
Packit Service fb6fa5
#include "gdkscreen-x11.h"
Packit Service fb6fa5
#include "gdkdisplay-x11.h"
Packit Service fb6fa5
Packit Service fb6fa5
#include "gdkalias.h"
Packit Service fb6fa5
Packit Service fb6fa5
static void gdk_x11_draw_rectangle (GdkDrawable    *drawable,
Packit Service fb6fa5
				    GdkGC          *gc,
Packit Service fb6fa5
				    gboolean        filled,
Packit Service fb6fa5
				    gint            x,
Packit Service fb6fa5
				    gint            y,
Packit Service fb6fa5
				    gint            width,
Packit Service fb6fa5
				    gint            height);
Packit Service fb6fa5
static void gdk_x11_draw_arc       (GdkDrawable    *drawable,
Packit Service fb6fa5
				    GdkGC          *gc,
Packit Service fb6fa5
				    gboolean        filled,
Packit Service fb6fa5
				    gint            x,
Packit Service fb6fa5
				    gint            y,
Packit Service fb6fa5
				    gint            width,
Packit Service fb6fa5
				    gint            height,
Packit Service fb6fa5
				    gint            angle1,
Packit Service fb6fa5
				    gint            angle2);
Packit Service fb6fa5
static void gdk_x11_draw_polygon   (GdkDrawable    *drawable,
Packit Service fb6fa5
				    GdkGC          *gc,
Packit Service fb6fa5
				    gboolean        filled,
Packit Service fb6fa5
				    GdkPoint       *points,
Packit Service fb6fa5
				    gint            npoints);
Packit Service fb6fa5
static void gdk_x11_draw_text      (GdkDrawable    *drawable,
Packit Service fb6fa5
				    GdkFont        *font,
Packit Service fb6fa5
				    GdkGC          *gc,
Packit Service fb6fa5
				    gint            x,
Packit Service fb6fa5
				    gint            y,
Packit Service fb6fa5
				    const gchar    *text,
Packit Service fb6fa5
				    gint            text_length);
Packit Service fb6fa5
static void gdk_x11_draw_text_wc   (GdkDrawable    *drawable,
Packit Service fb6fa5
				    GdkFont        *font,
Packit Service fb6fa5
				    GdkGC          *gc,
Packit Service fb6fa5
				    gint            x,
Packit Service fb6fa5
				    gint            y,
Packit Service fb6fa5
				    const GdkWChar *text,
Packit Service fb6fa5
				    gint            text_length);
Packit Service fb6fa5
static void gdk_x11_draw_drawable  (GdkDrawable    *drawable,
Packit Service fb6fa5
				    GdkGC          *gc,
Packit Service fb6fa5
				    GdkPixmap      *src,
Packit Service fb6fa5
				    gint            xsrc,
Packit Service fb6fa5
				    gint            ysrc,
Packit Service fb6fa5
				    gint            xdest,
Packit Service fb6fa5
				    gint            ydest,
Packit Service fb6fa5
				    gint            width,
Packit Service fb6fa5
				    gint            height,
Packit Service fb6fa5
				    GdkDrawable    *original_src);
Packit Service fb6fa5
static void gdk_x11_draw_points    (GdkDrawable    *drawable,
Packit Service fb6fa5
				    GdkGC          *gc,
Packit Service fb6fa5
				    GdkPoint       *points,
Packit Service fb6fa5
				    gint            npoints);
Packit Service fb6fa5
static void gdk_x11_draw_segments  (GdkDrawable    *drawable,
Packit Service fb6fa5
				    GdkGC          *gc,
Packit Service fb6fa5
				    GdkSegment     *segs,
Packit Service fb6fa5
				    gint            nsegs);
Packit Service fb6fa5
static void gdk_x11_draw_lines     (GdkDrawable    *drawable,
Packit Service fb6fa5
				    GdkGC          *gc,
Packit Service fb6fa5
				    GdkPoint       *points,
Packit Service fb6fa5
				    gint            npoints);
Packit Service fb6fa5
Packit Service fb6fa5
static void gdk_x11_draw_image     (GdkDrawable     *drawable,
Packit Service fb6fa5
                                    GdkGC           *gc,
Packit Service fb6fa5
                                    GdkImage        *image,
Packit Service fb6fa5
                                    gint             xsrc,
Packit Service fb6fa5
                                    gint             ysrc,
Packit Service fb6fa5
                                    gint             xdest,
Packit Service fb6fa5
                                    gint             ydest,
Packit Service fb6fa5
                                    gint             width,
Packit Service fb6fa5
                                    gint             height);
Packit Service fb6fa5
static void gdk_x11_draw_pixbuf    (GdkDrawable     *drawable,
Packit Service fb6fa5
				    GdkGC           *gc,
Packit Service fb6fa5
				    GdkPixbuf       *pixbuf,
Packit Service fb6fa5
				    gint             src_x,
Packit Service fb6fa5
				    gint             src_y,
Packit Service fb6fa5
				    gint             dest_x,
Packit Service fb6fa5
				    gint             dest_y,
Packit Service fb6fa5
				    gint             width,
Packit Service fb6fa5
				    gint             height,
Packit Service fb6fa5
				    GdkRgbDither     dither,
Packit Service fb6fa5
				    gint             x_dither,
Packit Service fb6fa5
				    gint             y_dither);
Packit Service fb6fa5
Packit Service fb6fa5
static cairo_surface_t *gdk_x11_ref_cairo_surface (GdkDrawable *drawable);
Packit Service fb6fa5
     
Packit Service fb6fa5
static void gdk_x11_set_colormap   (GdkDrawable    *drawable,
Packit Service fb6fa5
                                    GdkColormap    *colormap);
Packit Service fb6fa5
Packit Service fb6fa5
static GdkColormap* gdk_x11_get_colormap   (GdkDrawable    *drawable);
Packit Service fb6fa5
static gint         gdk_x11_get_depth      (GdkDrawable    *drawable);
Packit Service fb6fa5
static GdkScreen *  gdk_x11_get_screen	   (GdkDrawable    *drawable);
Packit Service fb6fa5
static GdkVisual*   gdk_x11_get_visual     (GdkDrawable    *drawable);
Packit Service fb6fa5
Packit Service fb6fa5
static void gdk_drawable_impl_x11_finalize   (GObject *object);
Packit Service fb6fa5
Packit Service fb6fa5
static const cairo_user_data_key_t gdk_x11_cairo_key;
Packit Service fb6fa5
Packit Service fb6fa5
G_DEFINE_TYPE (GdkDrawableImplX11, _gdk_drawable_impl_x11, GDK_TYPE_DRAWABLE)
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
_gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
Packit Service fb6fa5
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit Service fb6fa5
  
Packit Service fb6fa5
  object_class->finalize = gdk_drawable_impl_x11_finalize;
Packit Service fb6fa5
  
Packit Service fb6fa5
  drawable_class->create_gc = _gdk_x11_gc_new;
Packit Service fb6fa5
  drawable_class->draw_rectangle = gdk_x11_draw_rectangle;
Packit Service fb6fa5
  drawable_class->draw_arc = gdk_x11_draw_arc;
Packit Service fb6fa5
  drawable_class->draw_polygon = gdk_x11_draw_polygon;
Packit Service fb6fa5
  drawable_class->draw_text = gdk_x11_draw_text;
Packit Service fb6fa5
  drawable_class->draw_text_wc = gdk_x11_draw_text_wc;
Packit Service fb6fa5
  drawable_class->draw_drawable_with_src = gdk_x11_draw_drawable;
Packit Service fb6fa5
  drawable_class->draw_points = gdk_x11_draw_points;
Packit Service fb6fa5
  drawable_class->draw_segments = gdk_x11_draw_segments;
Packit Service fb6fa5
  drawable_class->draw_lines = gdk_x11_draw_lines;
Packit Service fb6fa5
  drawable_class->draw_image = gdk_x11_draw_image;
Packit Service fb6fa5
  drawable_class->draw_pixbuf = gdk_x11_draw_pixbuf;
Packit Service fb6fa5
  
Packit Service fb6fa5
  drawable_class->ref_cairo_surface = gdk_x11_ref_cairo_surface;
Packit Service fb6fa5
Packit Service fb6fa5
  drawable_class->set_colormap = gdk_x11_set_colormap;
Packit Service fb6fa5
  drawable_class->get_colormap = gdk_x11_get_colormap;
Packit Service fb6fa5
Packit Service fb6fa5
  drawable_class->get_depth = gdk_x11_get_depth;
Packit Service fb6fa5
  drawable_class->get_screen = gdk_x11_get_screen;
Packit Service fb6fa5
  drawable_class->get_visual = gdk_x11_get_visual;
Packit Service fb6fa5
  
Packit Service fb6fa5
  drawable_class->_copy_to_image = _gdk_x11_copy_to_image;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
_gdk_drawable_impl_x11_init (GdkDrawableImplX11 *impl)
Packit Service fb6fa5
{
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_drawable_impl_x11_finalize (GObject *object)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gdk_drawable_set_colormap (GDK_DRAWABLE (object), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  G_OBJECT_CLASS (_gdk_drawable_impl_x11_parent_class)->finalize (object);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * _gdk_x11_drawable_finish:
Packit Service fb6fa5
 * @drawable: a #GdkDrawableImplX11.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Performs necessary cleanup prior to freeing a pixmap or
Packit Service fb6fa5
 * destroying a window.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_x11_drawable_finish (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (impl->picture)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XRenderFreePicture (GDK_SCREEN_XDISPLAY (impl->screen),
Packit Service fb6fa5
			  impl->picture);
Packit Service fb6fa5
      impl->picture = None;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (impl->cairo_surface)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      cairo_surface_finish (impl->cairo_surface);
Packit Service fb6fa5
      cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key,
Packit Service fb6fa5
				   NULL, NULL);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * _gdk_x11_drawable_update_size:
Packit Service fb6fa5
 * @drawable: a #GdkDrawableImplX11.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Updates the state of the drawable (in particular the drawable's
Packit Service fb6fa5
 * cairo surface) when its size has changed.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_x11_drawable_update_size (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (impl->cairo_surface)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      int width, height;
Packit Service fb6fa5
      
Packit Service fb6fa5
      gdk_drawable_get_size (drawable, &width, &height);
Packit Service fb6fa5
      cairo_xlib_surface_set_size (impl->cairo_surface, width, height);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
try_pixmap (Display *xdisplay,
Packit Service fb6fa5
	    int      screen,
Packit Service fb6fa5
	    int      depth)
Packit Service fb6fa5
{
Packit Service fb6fa5
  Pixmap pixmap = XCreatePixmap (xdisplay,
Packit Service fb6fa5
				 RootWindow (xdisplay, screen),
Packit Service fb6fa5
				 1, 1, depth);
Packit Service fb6fa5
  XFreePixmap (xdisplay, pixmap);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
_gdk_x11_have_render (GdkDisplay *display)
Packit Service fb6fa5
{
Packit Service fb6fa5
  Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
Packit Service fb6fa5
  GdkDisplayX11 *x11display = GDK_DISPLAY_X11 (display);
Packit Service fb6fa5
Packit Service fb6fa5
  if (x11display->have_render == GDK_UNKNOWN)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      int event_base, error_base;
Packit Service fb6fa5
      x11display->have_render =
Packit Service fb6fa5
	XRenderQueryExtension (xdisplay, &event_base, &error_base)
Packit Service fb6fa5
	? GDK_YES : GDK_NO;
Packit Service fb6fa5
Packit Service fb6fa5
      if (x11display->have_render == GDK_YES)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  /*
Packit Service fb6fa5
	   * Sun advertises RENDER, but fails to support 32-bit pixmaps.
Packit Service fb6fa5
	   * That is just no good.  Therefore, we check all screens
Packit Service fb6fa5
	   * for proper support.
Packit Service fb6fa5
	   */
Packit Service fb6fa5
Packit Service fb6fa5
	  int screen;
Packit Service fb6fa5
	  for (screen = 0; screen < ScreenCount (xdisplay); screen++)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      int count;
Packit Service fb6fa5
	      int *depths = XListDepths (xdisplay, screen, &count);
Packit Service fb6fa5
	      gboolean has_8 = FALSE, has_32 = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
	      if (depths)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  int i;
Packit Service fb6fa5
Packit Service fb6fa5
		  for (i = 0; i < count; i++)
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      if (depths[i] == 8)
Packit Service fb6fa5
			has_8 = TRUE;
Packit Service fb6fa5
		      else if (depths[i] == 32)
Packit Service fb6fa5
			has_32 = TRUE;
Packit Service fb6fa5
		    }
Packit Service fb6fa5
		  XFree (depths);
Packit Service fb6fa5
		}
Packit Service fb6fa5
Packit Service fb6fa5
	      /* At this point, we might have a false positive;
Packit Service fb6fa5
	       * buggy versions of Xinerama only report depths for
Packit Service fb6fa5
	       * which there is an associated visual; so we actually
Packit Service fb6fa5
	       * go ahead and try create pixmaps.
Packit Service fb6fa5
	       */
Packit Service fb6fa5
	      if (!(has_8 && has_32))
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  gdk_error_trap_push ();
Packit Service fb6fa5
		  if (!has_8)
Packit Service fb6fa5
		    try_pixmap (xdisplay, screen, 8);
Packit Service fb6fa5
		  if (!has_32)
Packit Service fb6fa5
		    try_pixmap (xdisplay, screen, 32);
Packit Service fb6fa5
		  XSync (xdisplay, False);
Packit Service fb6fa5
		  if (gdk_error_trap_pop () == 0)
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      has_8 = TRUE;
Packit Service fb6fa5
		      has_32 = TRUE;
Packit Service fb6fa5
		    }
Packit Service fb6fa5
		}
Packit Service fb6fa5
	      
Packit Service fb6fa5
	      if (!(has_8 && has_32))
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  g_warning ("The X server advertises that RENDER support is present,\n"
Packit Service fb6fa5
			     "but fails to supply the necessary pixmap support.  In\n"
Packit Service fb6fa5
			     "other words, it is buggy.");
Packit Service fb6fa5
		  x11display->have_render = GDK_NO;
Packit Service fb6fa5
		  break;
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return x11display->have_render == GDK_YES;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static Picture
Packit Service fb6fa5
gdk_x11_drawable_get_picture (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (!impl->picture)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
Packit Service fb6fa5
      XRenderPictFormat *format;
Packit Service fb6fa5
      
Packit Service fb6fa5
      GdkVisual *visual = gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
Packit Service fb6fa5
      if (!visual)
Packit Service fb6fa5
	return None;
Packit Service fb6fa5
Packit Service fb6fa5
      format = XRenderFindVisualFormat (xdisplay, GDK_VISUAL_XVISUAL (visual));
Packit Service fb6fa5
      if (format)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  XRenderPictureAttributes attributes;
Packit Service fb6fa5
	  attributes.graphics_exposures = False;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  impl->picture = XRenderCreatePicture (xdisplay, impl->xid, format,
Packit Service fb6fa5
						CPGraphicsExposure, &attributes);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return impl->picture;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable,
Packit Service fb6fa5
				      GdkGC       *gc)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
  Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
Packit Service fb6fa5
  Picture picture = gdk_x11_drawable_get_picture (drawable);
Packit Service fb6fa5
  GdkRegion *clip_region = gc ? _gdk_gc_get_clip_region (gc) : NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  if (clip_region)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkRegionBox *boxes = clip_region->rects;
Packit Service fb6fa5
      gint n_boxes = clip_region->numRects;
Packit Service fb6fa5
      XRectangle *rects = g_new (XRectangle, n_boxes);
Packit Service fb6fa5
      int i;
Packit Service fb6fa5
Packit Service fb6fa5
      for (i=0; i < n_boxes; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  rects[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
Packit Service fb6fa5
	  rects[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
Packit Service fb6fa5
	  rects[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x;
Packit Service fb6fa5
	  rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      XRenderSetPictureClipRectangles (xdisplay, picture,
Packit Service fb6fa5
				       0, 0, rects, n_boxes);
Packit Service fb6fa5
      
Packit Service fb6fa5
      g_free (rects);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XRenderPictureAttributes pa;
Packit Service fb6fa5
      GdkBitmap *mask;
Packit Service fb6fa5
      gulong pa_mask;
Packit Service fb6fa5
Packit Service fb6fa5
      pa_mask = CPClipMask;
Packit Service fb6fa5
      if (gc && (mask = _gdk_gc_get_clip_mask (gc)))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  pa.clip_mask = GDK_PIXMAP_XID (mask);
Packit Service fb6fa5
	  pa.clip_x_origin = gc->clip_x_origin;
Packit Service fb6fa5
	  pa.clip_y_origin = gc->clip_y_origin;
Packit Service fb6fa5
	  pa_mask |= CPClipXOrigin | CPClipYOrigin;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	pa.clip_mask = None;
Packit Service fb6fa5
Packit Service fb6fa5
      XRenderChangePicture (xdisplay, picture,
Packit Service fb6fa5
			    pa_mask, &pa);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/*****************************************************
Packit Service fb6fa5
 * X11 specific implementations of generic functions *
Packit Service fb6fa5
 *****************************************************/
Packit Service fb6fa5
Packit Service fb6fa5
static GdkColormap*
Packit Service fb6fa5
gdk_x11_get_colormap (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
  return impl->colormap;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_set_colormap (GdkDrawable *drawable,
Packit Service fb6fa5
                      GdkColormap *colormap)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
  if (impl->colormap == colormap)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (impl->colormap)
Packit Service fb6fa5
    g_object_unref (impl->colormap);
Packit Service fb6fa5
  impl->colormap = colormap;
Packit Service fb6fa5
  if (impl->colormap)
Packit Service fb6fa5
    g_object_ref (impl->colormap);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* Drawing
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_rectangle (GdkDrawable *drawable,
Packit Service fb6fa5
			GdkGC       *gc,
Packit Service fb6fa5
			gboolean     filled,
Packit Service fb6fa5
			gint         x,
Packit Service fb6fa5
			gint         y,
Packit Service fb6fa5
			gint         width,
Packit Service fb6fa5
			gint         height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (filled)
Packit Service fb6fa5
    XFillRectangle (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
Packit Service fb6fa5
		    GDK_GC_GET_XGC (gc), x, y, width, height);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    XDrawRectangle (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
Packit Service fb6fa5
		    GDK_GC_GET_XGC (gc), x, y, width, height);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_arc (GdkDrawable *drawable,
Packit Service fb6fa5
		  GdkGC       *gc,
Packit Service fb6fa5
		  gboolean     filled,
Packit Service fb6fa5
		  gint         x,
Packit Service fb6fa5
		  gint         y,
Packit Service fb6fa5
		  gint         width,
Packit Service fb6fa5
		  gint         height,
Packit Service fb6fa5
		  gint         angle1,
Packit Service fb6fa5
		  gint         angle2)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (filled)
Packit Service fb6fa5
    XFillArc (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
Packit Service fb6fa5
	      GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    XDrawArc (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
Packit Service fb6fa5
	      GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_polygon (GdkDrawable *drawable,
Packit Service fb6fa5
		      GdkGC       *gc,
Packit Service fb6fa5
		      gboolean     filled,
Packit Service fb6fa5
		      GdkPoint    *points,
Packit Service fb6fa5
		      gint         npoints)
Packit Service fb6fa5
{
Packit Service fb6fa5
  XPoint *tmp_points;
Packit Service fb6fa5
  gint tmp_npoints, i;
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (!filled &&
Packit Service fb6fa5
      (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      tmp_npoints = npoints + 1;
Packit Service fb6fa5
      tmp_points = g_new (XPoint, tmp_npoints);
Packit Service fb6fa5
      tmp_points[npoints].x = points[0].x;
Packit Service fb6fa5
      tmp_points[npoints].y = points[0].y;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      tmp_npoints = npoints;
Packit Service fb6fa5
      tmp_points = g_new (XPoint, tmp_npoints);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  for (i=0; i
Packit Service fb6fa5
    {
Packit Service fb6fa5
      tmp_points[i].x = points[i].x;
Packit Service fb6fa5
      tmp_points[i].y = points[i].y;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (filled)
Packit Service fb6fa5
    XFillPolygon (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
Packit Service fb6fa5
		  GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, Complex, CoordModeOrigin);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    XDrawLines (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
Packit Service fb6fa5
		GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, CoordModeOrigin);
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (tmp_points);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* gdk_x11_draw_text
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
Packit Service fb6fa5
 */
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_text (GdkDrawable *drawable,
Packit Service fb6fa5
		   GdkFont     *font,
Packit Service fb6fa5
		   GdkGC       *gc,
Packit Service fb6fa5
		   gint         x,
Packit Service fb6fa5
		   gint         y,
Packit Service fb6fa5
		   const gchar *text,
Packit Service fb6fa5
		   gint         text_length)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
  Display *xdisplay;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
  xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (font->type == GDK_FONT_FONT)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
Packit Service fb6fa5
      XSetFont(xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
Packit Service fb6fa5
      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  XDrawString (xdisplay, impl->xid,
Packit Service fb6fa5
		       GDK_GC_GET_XGC (gc), x, y, text, text_length);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  XDrawString16 (xdisplay, impl->xid,
Packit Service fb6fa5
			 GDK_GC_GET_XGC (gc), x, y, (XChar2b *) text, text_length / 2);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (font->type == GDK_FONT_FONTSET)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XFontSet fontset = (XFontSet) GDK_FONT_XFONT (font);
Packit Service fb6fa5
      XmbDrawString (xdisplay, impl->xid,
Packit Service fb6fa5
		     fontset, GDK_GC_GET_XGC (gc), x, y, text, text_length);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    g_error("undefined font type\n");
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_text_wc (GdkDrawable    *drawable,
Packit Service fb6fa5
		      GdkFont	     *font,
Packit Service fb6fa5
		      GdkGC	     *gc,
Packit Service fb6fa5
		      gint	      x,
Packit Service fb6fa5
		      gint	      y,
Packit Service fb6fa5
		      const GdkWChar *text,
Packit Service fb6fa5
		      gint	      text_length)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
  Display *xdisplay;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
  xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (font->type == GDK_FONT_FONT)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
Packit Service fb6fa5
      gchar *text_8bit;
Packit Service fb6fa5
      gint i;
Packit Service fb6fa5
      XSetFont(xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
Packit Service fb6fa5
      text_8bit = g_new (gchar, text_length);
Packit Service fb6fa5
      for (i=0; i
Packit Service fb6fa5
      XDrawString (xdisplay, impl->xid,
Packit Service fb6fa5
                   GDK_GC_GET_XGC (gc), x, y, text_8bit, text_length);
Packit Service fb6fa5
      g_free (text_8bit);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (font->type == GDK_FONT_FONTSET)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (sizeof(GdkWChar) == sizeof(wchar_t))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  XwcDrawString (xdisplay, impl->xid,
Packit Service fb6fa5
			 (XFontSet) GDK_FONT_XFONT (font),
Packit Service fb6fa5
			 GDK_GC_GET_XGC (gc), x, y, (wchar_t *)text, text_length);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  wchar_t *text_wchar;
Packit Service fb6fa5
	  gint i;
Packit Service fb6fa5
	  text_wchar = g_new (wchar_t, text_length);
Packit Service fb6fa5
	  for (i=0; i
Packit Service fb6fa5
	  XwcDrawString (xdisplay, impl->xid,
Packit Service fb6fa5
			 (XFontSet) GDK_FONT_XFONT (font),
Packit Service fb6fa5
			 GDK_GC_GET_XGC (gc), x, y, text_wchar, text_length);
Packit Service fb6fa5
	  g_free (text_wchar);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    g_error("undefined font type\n");
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_drawable (GdkDrawable *drawable,
Packit Service fb6fa5
		       GdkGC       *gc,
Packit Service fb6fa5
		       GdkPixmap   *src,
Packit Service fb6fa5
		       gint         xsrc,
Packit Service fb6fa5
		       gint         ysrc,
Packit Service fb6fa5
		       gint         xdest,
Packit Service fb6fa5
		       gint         ydest,
Packit Service fb6fa5
		       gint         width,
Packit Service fb6fa5
		       gint         height,
Packit Service fb6fa5
		       GdkDrawable *original_src)
Packit Service fb6fa5
{
Packit Service fb6fa5
  int src_depth = gdk_drawable_get_depth (src);
Packit Service fb6fa5
  int dest_depth = gdk_drawable_get_depth (drawable);
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
  GdkDrawableImplX11 *src_impl;
Packit Service fb6fa5
  
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
  if (GDK_IS_DRAWABLE_IMPL_X11 (src))
Packit Service fb6fa5
    src_impl = GDK_DRAWABLE_IMPL_X11 (src);
Packit Service fb6fa5
  else if (GDK_IS_WINDOW (src))
Packit Service fb6fa5
    src_impl = GDK_DRAWABLE_IMPL_X11(((GdkWindowObject *)src)->impl);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    src_impl = GDK_DRAWABLE_IMPL_X11(((GdkPixmapObject *)src)->impl);
Packit Service fb6fa5
Packit Service fb6fa5
  if (GDK_IS_WINDOW_IMPL_X11 (impl) &&
Packit Service fb6fa5
      GDK_IS_PIXMAP_IMPL_X11 (src_impl))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkPixmapImplX11 *src_pixmap = GDK_PIXMAP_IMPL_X11 (src_impl);
Packit Service fb6fa5
      /* Work around an Xserver bug where non-visible areas from
Packit Service fb6fa5
       * a pixmap to a window will clear the window background
Packit Service fb6fa5
       * in destination areas that are supposed to be clipped out.
Packit Service fb6fa5
       * This is a problem with client side windows as this means
Packit Service fb6fa5
       * things may draw outside the virtual windows. This could
Packit Service fb6fa5
       * also happen for window to window copies, but I don't
Packit Service fb6fa5
       * think we generate any calls like that.
Packit Service fb6fa5
       *
Packit Service fb6fa5
       * See: 
Packit Service fb6fa5
       * http://lists.freedesktop.org/archives/xorg/2009-February/043318.html
Packit Service fb6fa5
       */
Packit Service fb6fa5
      if (xsrc < 0)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  width += xsrc;
Packit Service fb6fa5
	  xdest -= xsrc;
Packit Service fb6fa5
	  xsrc = 0;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (ysrc < 0)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  height += ysrc;
Packit Service fb6fa5
	  ydest -= ysrc;
Packit Service fb6fa5
	  ysrc = 0;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      if (xsrc + width > src_pixmap->width)
Packit Service fb6fa5
	width = src_pixmap->width - xsrc;
Packit Service fb6fa5
      if (ysrc + height > src_pixmap->height)
Packit Service fb6fa5
	height = src_pixmap->height - ysrc;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (src_depth == 1)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen),
Packit Service fb6fa5
                 src_impl->xid,
Packit Service fb6fa5
		 impl->xid,
Packit Service fb6fa5
		 GDK_GC_GET_XGC (gc),
Packit Service fb6fa5
		 xsrc, ysrc,
Packit Service fb6fa5
		 width, height,
Packit Service fb6fa5
		 xdest, ydest);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (dest_depth != 0 && src_depth == dest_depth)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen),
Packit Service fb6fa5
                 src_impl->xid,
Packit Service fb6fa5
		 impl->xid,
Packit Service fb6fa5
		 GDK_GC_GET_XGC (gc),
Packit Service fb6fa5
		 xsrc, ysrc,
Packit Service fb6fa5
		 width, height,
Packit Service fb6fa5
		 xdest, ydest);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    g_warning ("Attempt to draw a drawable with depth %d to a drawable with depth %d",
Packit Service fb6fa5
               src_depth, dest_depth);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_points (GdkDrawable *drawable,
Packit Service fb6fa5
		     GdkGC       *gc,
Packit Service fb6fa5
		     GdkPoint    *points,
Packit Service fb6fa5
		     gint         npoints)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* We special-case npoints == 1, because X will merge multiple
Packit Service fb6fa5
   * consecutive XDrawPoint requests into a PolyPoint request
Packit Service fb6fa5
   */
Packit Service fb6fa5
  if (npoints == 1)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XDrawPoint (GDK_SCREEN_XDISPLAY (impl->screen),
Packit Service fb6fa5
		  impl->xid,
Packit Service fb6fa5
		  GDK_GC_GET_XGC (gc),
Packit Service fb6fa5
		  points[0].x, points[0].y);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gint i;
Packit Service fb6fa5
      XPoint *tmp_points = g_new (XPoint, npoints);
Packit Service fb6fa5
Packit Service fb6fa5
      for (i=0; i
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  tmp_points[i].x = points[i].x;
Packit Service fb6fa5
	  tmp_points[i].y = points[i].y;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      XDrawPoints (GDK_SCREEN_XDISPLAY (impl->screen),
Packit Service fb6fa5
		   impl->xid,
Packit Service fb6fa5
		   GDK_GC_GET_XGC (gc),
Packit Service fb6fa5
		   tmp_points,
Packit Service fb6fa5
		   npoints,
Packit Service fb6fa5
		   CoordModeOrigin);
Packit Service fb6fa5
Packit Service fb6fa5
      g_free (tmp_points);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_segments (GdkDrawable *drawable,
Packit Service fb6fa5
		       GdkGC       *gc,
Packit Service fb6fa5
		       GdkSegment  *segs,
Packit Service fb6fa5
		       gint         nsegs)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* We special-case nsegs == 1, because X will merge multiple
Packit Service fb6fa5
   * consecutive XDrawLine requests into a PolySegment request
Packit Service fb6fa5
   */
Packit Service fb6fa5
  if (nsegs == 1)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XDrawLine (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
Packit Service fb6fa5
		 GDK_GC_GET_XGC (gc), segs[0].x1, segs[0].y1,
Packit Service fb6fa5
		 segs[0].x2, segs[0].y2);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gint i;
Packit Service fb6fa5
      XSegment *tmp_segs = g_new (XSegment, nsegs);
Packit Service fb6fa5
Packit Service fb6fa5
      for (i=0; i
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  tmp_segs[i].x1 = segs[i].x1;
Packit Service fb6fa5
	  tmp_segs[i].x2 = segs[i].x2;
Packit Service fb6fa5
	  tmp_segs[i].y1 = segs[i].y1;
Packit Service fb6fa5
	  tmp_segs[i].y2 = segs[i].y2;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      XDrawSegments (GDK_SCREEN_XDISPLAY (impl->screen),
Packit Service fb6fa5
		     impl->xid,
Packit Service fb6fa5
		     GDK_GC_GET_XGC (gc),
Packit Service fb6fa5
		     tmp_segs, nsegs);
Packit Service fb6fa5
Packit Service fb6fa5
      g_free (tmp_segs);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_lines (GdkDrawable *drawable,
Packit Service fb6fa5
		    GdkGC       *gc,
Packit Service fb6fa5
		    GdkPoint    *points,
Packit Service fb6fa5
		    gint         npoints)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
  XPoint *tmp_points = g_new (XPoint, npoints);
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
  
Packit Service fb6fa5
  for (i=0; i
Packit Service fb6fa5
    {
Packit Service fb6fa5
      tmp_points[i].x = points[i].x;
Packit Service fb6fa5
      tmp_points[i].y = points[i].y;
Packit Service fb6fa5
    }
Packit Service fb6fa5
      
Packit Service fb6fa5
  XDrawLines (GDK_SCREEN_XDISPLAY (impl->screen),
Packit Service fb6fa5
	      impl->xid,
Packit Service fb6fa5
	      GDK_GC_GET_XGC (gc),
Packit Service fb6fa5
	      tmp_points, npoints,
Packit Service fb6fa5
	      CoordModeOrigin);
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (tmp_points);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_image     (GdkDrawable     *drawable,
Packit Service fb6fa5
                        GdkGC           *gc,
Packit Service fb6fa5
                        GdkImage        *image,
Packit Service fb6fa5
                        gint             xsrc,
Packit Service fb6fa5
                        gint             ysrc,
Packit Service fb6fa5
                        gint             xdest,
Packit Service fb6fa5
                        gint             ydest,
Packit Service fb6fa5
                        gint             width,
Packit Service fb6fa5
                        gint             height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl;
Packit Service fb6fa5
Packit Service fb6fa5
  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef USE_SHM  
Packit Service fb6fa5
  if (image->type == GDK_IMAGE_SHARED)
Packit Service fb6fa5
    XShmPutImage (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
Packit Service fb6fa5
                  GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image),
Packit Service fb6fa5
                  xsrc, ysrc, xdest, ydest, width, height, False);
Packit Service fb6fa5
  else
Packit Service fb6fa5
#endif
Packit Service fb6fa5
    XPutImage (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
Packit Service fb6fa5
               GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image),
Packit Service fb6fa5
               xsrc, ysrc, xdest, ydest, width, height);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gdk_x11_get_depth (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  /* This is a bit bogus but I'm not sure the other way is better */
Packit Service fb6fa5
Packit Service fb6fa5
  return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static GdkDrawable *
Packit Service fb6fa5
get_impl_drawable (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (GDK_IS_WINDOW (drawable))
Packit Service fb6fa5
    return ((GdkWindowObject *)drawable)->impl;
Packit Service fb6fa5
  else if (GDK_IS_PIXMAP (drawable))
Packit Service fb6fa5
    return ((GdkPixmapObject *)drawable)->impl;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_warning (G_STRLOC " drawable is not a pixmap or window");
Packit Service fb6fa5
      return NULL;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static GdkScreen*
Packit Service fb6fa5
gdk_x11_get_screen (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (GDK_IS_DRAWABLE_IMPL_X11 (drawable))
Packit Service fb6fa5
    return GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return GDK_DRAWABLE_IMPL_X11 (get_impl_drawable (drawable))->screen;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static GdkVisual*
Packit Service fb6fa5
gdk_x11_get_visual (GdkDrawable    *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_x11_drawable_get_xdisplay:
Packit Service fb6fa5
 * @drawable: a #GdkDrawable.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Returns the display of a #GdkDrawable.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: an Xlib <type>Display*</type>.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
Display *
Packit Service fb6fa5
gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (GDK_IS_DRAWABLE_IMPL_X11 (drawable))
Packit Service fb6fa5
    return GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (drawable)->screen);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (get_impl_drawable (drawable))->screen);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_x11_drawable_get_xid:
Packit Service fb6fa5
 * @drawable: a #GdkDrawable.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Returns the X resource (window or pixmap) belonging to a #GdkDrawable.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: the ID of @drawable's X resource.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
XID
Packit Service fb6fa5
gdk_x11_drawable_get_xid (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawable *impl;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (GDK_IS_WINDOW (drawable))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkWindow *window = (GdkWindow *)drawable;
Packit Service fb6fa5
      
Packit Service fb6fa5
      /* Try to ensure the window has a native window */
Packit Service fb6fa5
      if (!_gdk_window_has_impl (window))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gdk_window_ensure_native (window);
Packit Service fb6fa5
Packit Service fb6fa5
	  /* We sync here to ensure the window is created in the Xserver when
Packit Service fb6fa5
	   * this function returns. This is required because the returned XID
Packit Service fb6fa5
	   * for this window must be valid immediately, even with another
Packit Service fb6fa5
	   * connection to the Xserver */
Packit Service fb6fa5
	  gdk_display_sync (gdk_drawable_get_display (window));
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (!GDK_WINDOW_IS_X11 (window))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          g_warning (G_STRLOC " drawable is not a native X11 window");
Packit Service fb6fa5
          return None;
Packit Service fb6fa5
        }
Packit Service fb6fa5
      
Packit Service fb6fa5
      impl = ((GdkWindowObject *)drawable)->impl;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (GDK_IS_PIXMAP (drawable))
Packit Service fb6fa5
    impl = ((GdkPixmapObject *)drawable)->impl;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_warning (G_STRLOC " drawable is not a pixmap or window");
Packit Service fb6fa5
      return None;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return ((GdkDrawableImplX11 *)impl)->xid;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkDrawable *
Packit Service fb6fa5
gdk_x11_window_get_drawable_impl (GdkWindow *window)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return ((GdkWindowObject *)window)->impl;
Packit Service fb6fa5
}
Packit Service fb6fa5
GdkDrawable *
Packit Service fb6fa5
gdk_x11_pixmap_get_drawable_impl (GdkPixmap *pixmap)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return ((GdkPixmapObject *)pixmap)->impl;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* Code for accelerated alpha compositing using the RENDER extension.
Packit Service fb6fa5
 * It's a bit long because there are lots of possibilities for
Packit Service fb6fa5
 * what's the fastest depending on the available picture formats,
Packit Service fb6fa5
 * whether we can used shared pixmaps, etc.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
static GdkX11FormatType
Packit Service fb6fa5
select_format (GdkDisplay         *display,
Packit Service fb6fa5
	       XRenderPictFormat **format,
Packit Service fb6fa5
	       XRenderPictFormat **mask)
Packit Service fb6fa5
{
Packit Service fb6fa5
  Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
Packit Service fb6fa5
  XRenderPictFormat pf;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!_gdk_x11_have_render (display))
Packit Service fb6fa5
    return GDK_X11_FORMAT_NONE;
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* Look for a 32-bit xRGB and Axxx formats that exactly match the
Packit Service fb6fa5
   * in memory data format. We can use them as pixmap and mask
Packit Service fb6fa5
   * to deal with non-premultiplied data.
Packit Service fb6fa5
   */
Packit Service fb6fa5
Packit Service fb6fa5
  pf.type = PictTypeDirect;
Packit Service fb6fa5
  pf.depth = 32;
Packit Service fb6fa5
  pf.direct.redMask = 0xff;
Packit Service fb6fa5
  pf.direct.greenMask = 0xff;
Packit Service fb6fa5
  pf.direct.blueMask = 0xff;
Packit Service fb6fa5
  
Packit Service fb6fa5
  pf.direct.alphaMask = 0;
Packit Service fb6fa5
  if (ImageByteOrder (xdisplay) == LSBFirst)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* ABGR */
Packit Service fb6fa5
      pf.direct.red = 0;
Packit Service fb6fa5
      pf.direct.green = 8;
Packit Service fb6fa5
      pf.direct.blue = 16;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* RGBA */
Packit Service fb6fa5
      pf.direct.red = 24;
Packit Service fb6fa5
      pf.direct.green = 16;
Packit Service fb6fa5
      pf.direct.blue = 8;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  *format = XRenderFindFormat (xdisplay,
Packit Service fb6fa5
			       (PictFormatType | PictFormatDepth |
Packit Service fb6fa5
				PictFormatRedMask | PictFormatRed |
Packit Service fb6fa5
				PictFormatGreenMask | PictFormatGreen |
Packit Service fb6fa5
				PictFormatBlueMask | PictFormatBlue |
Packit Service fb6fa5
				PictFormatAlphaMask),
Packit Service fb6fa5
			       &pf,
Packit Service fb6fa5
			       0);
Packit Service fb6fa5
Packit Service fb6fa5
  pf.direct.alphaMask = 0xff;
Packit Service fb6fa5
  if (ImageByteOrder (xdisplay) == LSBFirst)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* ABGR */
Packit Service fb6fa5
      pf.direct.alpha = 24;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      pf.direct.alpha = 0;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  *mask = XRenderFindFormat (xdisplay,
Packit Service fb6fa5
			     (PictFormatType | PictFormatDepth |
Packit Service fb6fa5
			      PictFormatAlphaMask | PictFormatAlpha),
Packit Service fb6fa5
			     &pf,
Packit Service fb6fa5
			     0);
Packit Service fb6fa5
Packit Service fb6fa5
  if (*format && *mask)
Packit Service fb6fa5
    return GDK_X11_FORMAT_EXACT_MASK;
Packit Service fb6fa5
Packit Service fb6fa5
  /* OK, that failed, now look for xRGB and Axxx formats in
Packit Service fb6fa5
   * RENDER's preferred order
Packit Service fb6fa5
   */
Packit Service fb6fa5
  pf.direct.alphaMask = 0;
Packit Service fb6fa5
  /* ARGB */
Packit Service fb6fa5
  pf.direct.red = 16;
Packit Service fb6fa5
  pf.direct.green = 8;
Packit Service fb6fa5
  pf.direct.blue = 0;
Packit Service fb6fa5
  
Packit Service fb6fa5
  *format = XRenderFindFormat (xdisplay,
Packit Service fb6fa5
			       (PictFormatType | PictFormatDepth |
Packit Service fb6fa5
				PictFormatRedMask | PictFormatRed |
Packit Service fb6fa5
				PictFormatGreenMask | PictFormatGreen |
Packit Service fb6fa5
				PictFormatBlueMask | PictFormatBlue |
Packit Service fb6fa5
				PictFormatAlphaMask),
Packit Service fb6fa5
			       &pf,
Packit Service fb6fa5
			       0);
Packit Service fb6fa5
Packit Service fb6fa5
  pf.direct.alphaMask = 0xff;
Packit Service fb6fa5
  pf.direct.alpha = 24;
Packit Service fb6fa5
  
Packit Service fb6fa5
  *mask = XRenderFindFormat (xdisplay,
Packit Service fb6fa5
			     (PictFormatType | PictFormatDepth |
Packit Service fb6fa5
			      PictFormatAlphaMask | PictFormatAlpha),
Packit Service fb6fa5
			     &pf,
Packit Service fb6fa5
			     0);
Packit Service fb6fa5
Packit Service fb6fa5
  if (*format && *mask)
Packit Service fb6fa5
    return GDK_X11_FORMAT_ARGB_MASK;
Packit Service fb6fa5
Packit Service fb6fa5
  /* Finally, if neither of the above worked, fall back to
Packit Service fb6fa5
   * looking for combined ARGB -- we'll premultiply ourselves.
Packit Service fb6fa5
   */
Packit Service fb6fa5
Packit Service fb6fa5
  pf.type = PictTypeDirect;
Packit Service fb6fa5
  pf.depth = 32;
Packit Service fb6fa5
  pf.direct.red = 16;
Packit Service fb6fa5
  pf.direct.green = 8;
Packit Service fb6fa5
  pf.direct.blue = 0;
Packit Service fb6fa5
  pf.direct.alphaMask = 0xff;
Packit Service fb6fa5
  pf.direct.alpha = 24;
Packit Service fb6fa5
Packit Service fb6fa5
  *format = XRenderFindFormat (xdisplay,
Packit Service fb6fa5
			       (PictFormatType | PictFormatDepth |
Packit Service fb6fa5
				PictFormatRedMask | PictFormatRed |
Packit Service fb6fa5
				PictFormatGreenMask | PictFormatGreen |
Packit Service fb6fa5
				PictFormatBlueMask | PictFormatBlue |
Packit Service fb6fa5
				PictFormatAlphaMask | PictFormatAlpha),
Packit Service fb6fa5
			       &pf,
Packit Service fb6fa5
			       0);
Packit Service fb6fa5
  *mask = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  if (*format)
Packit Service fb6fa5
    return GDK_X11_FORMAT_ARGB;
Packit Service fb6fa5
Packit Service fb6fa5
  return GDK_X11_FORMAT_NONE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
#if 0
Packit Service fb6fa5
static void
Packit Service fb6fa5
list_formats (XRenderPictFormat *pf)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
  
Packit Service fb6fa5
  for (i=0 ;; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      XRenderPictFormat *pf = XRenderFindFormat (impl->xdisplay, 0, NULL, i);
Packit Service fb6fa5
      if (pf)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  g_print ("%2d R-%#06x/%#06x G-%#06x/%#06x B-%#06x/%#06x A-%#06x/%#06x\n",
Packit Service fb6fa5
		   pf->depth,
Packit Service fb6fa5
		   pf->direct.red,
Packit Service fb6fa5
		   pf->direct.redMask,
Packit Service fb6fa5
		   pf->direct.green,
Packit Service fb6fa5
		   pf->direct.greenMask,
Packit Service fb6fa5
		   pf->direct.blue,
Packit Service fb6fa5
		   pf->direct.blueMask,
Packit Service fb6fa5
		   pf->direct.alpha,
Packit Service fb6fa5
		   pf->direct.alphaMask);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	break;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
#endif  
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_x11_convert_to_format (guchar           *src_buf,
Packit Service fb6fa5
                            gint              src_rowstride,
Packit Service fb6fa5
                            guchar           *dest_buf,
Packit Service fb6fa5
                            gint              dest_rowstride,
Packit Service fb6fa5
                            GdkX11FormatType  dest_format,
Packit Service fb6fa5
                            GdkByteOrder      dest_byteorder,
Packit Service fb6fa5
                            gint              width,
Packit Service fb6fa5
                            gint              height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  for (i=0; i < height; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      switch (dest_format)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	case GDK_X11_FORMAT_EXACT_MASK:
Packit Service fb6fa5
	  {
Packit Service fb6fa5
	    memcpy (dest_buf + i * dest_rowstride,
Packit Service fb6fa5
		    src_buf + i * src_rowstride,
Packit Service fb6fa5
		    width * 4);
Packit Service fb6fa5
	    break;
Packit Service fb6fa5
	  }
Packit Service fb6fa5
	case GDK_X11_FORMAT_ARGB_MASK:
Packit Service fb6fa5
	  {
Packit Service fb6fa5
	    guchar *row = src_buf + i * src_rowstride;
Packit Service fb6fa5
	    if (((gsize)row & 3) != 0)
Packit Service fb6fa5
	      {
Packit Service fb6fa5
		guchar *p = row;
Packit Service fb6fa5
		guint32 *q = (guint32 *)(dest_buf + i * dest_rowstride);
Packit Service fb6fa5
		guchar *end = p + 4 * width;
Packit Service fb6fa5
Packit Service fb6fa5
		while (p < end)
Packit Service fb6fa5
		  {
Packit Service fb6fa5
		    *q = (p[3] << 24) | (p[0] << 16) | (p[1] << 8) | p[2];
Packit Service fb6fa5
		    p += 4;
Packit Service fb6fa5
		    q++;
Packit Service fb6fa5
		  }
Packit Service fb6fa5
	      }
Packit Service fb6fa5
	    else
Packit Service fb6fa5
	      {
Packit Service fb6fa5
		guint32 *p = (guint32 *)row;
Packit Service fb6fa5
		guint32 *q = (guint32 *)(dest_buf + i * dest_rowstride);
Packit Service fb6fa5
		guint32 *end = p + width;
Packit Service fb6fa5
Packit Service fb6fa5
#if G_BYTE_ORDER == G_LITTLE_ENDIAN	    
Packit Service fb6fa5
		if (dest_byteorder == GDK_LSB_FIRST)
Packit Service fb6fa5
		  {
Packit Service fb6fa5
		    /* ABGR => ARGB */
Packit Service fb6fa5
		
Packit Service fb6fa5
		    while (p < end)
Packit Service fb6fa5
		      {
Packit Service fb6fa5
			*q = ( (*p & 0xff00ff00) |
Packit Service fb6fa5
			       ((*p & 0x000000ff) << 16) |
Packit Service fb6fa5
			       ((*p & 0x00ff0000) >> 16));
Packit Service fb6fa5
			q++;
Packit Service fb6fa5
			p++;
Packit Service fb6fa5
		      }
Packit Service fb6fa5
		  }
Packit Service fb6fa5
		else
Packit Service fb6fa5
		  {
Packit Service fb6fa5
		    /* ABGR => BGRA */
Packit Service fb6fa5
		
Packit Service fb6fa5
		    while (p < end)
Packit Service fb6fa5
		      {
Packit Service fb6fa5
			*q = (((*p & 0xff000000) >> 24) |
Packit Service fb6fa5
			      ((*p & 0x00ffffff) << 8));
Packit Service fb6fa5
			q++;
Packit Service fb6fa5
			p++;
Packit Service fb6fa5
		      }
Packit Service fb6fa5
		  }
Packit Service fb6fa5
#else /* G_BYTE_ORDER == G_BIG_ENDIAN */
Packit Service fb6fa5
		if (dest_byteorder == GDK_LSB_FIRST)
Packit Service fb6fa5
		  {
Packit Service fb6fa5
		    /* RGBA => BGRA */
Packit Service fb6fa5
		
Packit Service fb6fa5
		    while (p < end)
Packit Service fb6fa5
		      {
Packit Service fb6fa5
			*q = ( (*p & 0x00ff00ff) |
Packit Service fb6fa5
			       ((*p & 0x0000ff00) << 16) |
Packit Service fb6fa5
			       ((*p & 0xff000000) >> 16));
Packit Service fb6fa5
			q++;
Packit Service fb6fa5
			p++;
Packit Service fb6fa5
		      }
Packit Service fb6fa5
		  }
Packit Service fb6fa5
		else
Packit Service fb6fa5
		  {
Packit Service fb6fa5
		    /* RGBA => ARGB */
Packit Service fb6fa5
		
Packit Service fb6fa5
		    while (p < end)
Packit Service fb6fa5
		      {
Packit Service fb6fa5
			*q = (((*p & 0xffffff00) >> 8) |
Packit Service fb6fa5
			      ((*p & 0x000000ff) << 24));
Packit Service fb6fa5
			q++;
Packit Service fb6fa5
			p++;
Packit Service fb6fa5
		      }
Packit Service fb6fa5
		  }
Packit Service fb6fa5
#endif /* G_BYTE_ORDER*/	    
Packit Service fb6fa5
	      }
Packit Service fb6fa5
	    break;
Packit Service fb6fa5
	  }
Packit Service fb6fa5
	case GDK_X11_FORMAT_ARGB:
Packit Service fb6fa5
	  {
Packit Service fb6fa5
	    guchar *p = (src_buf + i * src_rowstride);
Packit Service fb6fa5
	    guchar *q = (dest_buf + i * dest_rowstride);
Packit Service fb6fa5
	    guchar *end = p + 4 * width;
Packit Service fb6fa5
	    guint t1,t2,t3;
Packit Service fb6fa5
	    
Packit Service fb6fa5
#define MULT(d,c,a,t) G_STMT_START { t = c * a; d = ((t >> 8) + t) >> 8; } G_STMT_END
Packit Service fb6fa5
	    
Packit Service fb6fa5
	    if (dest_byteorder == GDK_LSB_FIRST)
Packit Service fb6fa5
	      {
Packit Service fb6fa5
		while (p < end)
Packit Service fb6fa5
		  {
Packit Service fb6fa5
		    MULT(q[0], p[2], p[3], t1);
Packit Service fb6fa5
		    MULT(q[1], p[1], p[3], t2);
Packit Service fb6fa5
		    MULT(q[2], p[0], p[3], t3);
Packit Service fb6fa5
		    q[3] = p[3];
Packit Service fb6fa5
		    p += 4;
Packit Service fb6fa5
		    q += 4;
Packit Service fb6fa5
		  }
Packit Service fb6fa5
	      }
Packit Service fb6fa5
	    else
Packit Service fb6fa5
	      {
Packit Service fb6fa5
		while (p < end)
Packit Service fb6fa5
		  {
Packit Service fb6fa5
		    q[0] = p[3];
Packit Service fb6fa5
		    MULT(q[1], p[0], p[3], t1);
Packit Service fb6fa5
		    MULT(q[2], p[1], p[3], t2);
Packit Service fb6fa5
		    MULT(q[3], p[2], p[3], t3);
Packit Service fb6fa5
		    p += 4;
Packit Service fb6fa5
		    q += 4;
Packit Service fb6fa5
		  }
Packit Service fb6fa5
	      }
Packit Service fb6fa5
#undef MULT
Packit Service fb6fa5
	    break;
Packit Service fb6fa5
	  }
Packit Service fb6fa5
	case GDK_X11_FORMAT_NONE:
Packit Service fb6fa5
	  g_assert_not_reached ();
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
draw_with_images (GdkDrawable       *drawable,
Packit Service fb6fa5
		  GdkGC             *gc,
Packit Service fb6fa5
		  GdkX11FormatType   format_type,
Packit Service fb6fa5
		  XRenderPictFormat *format,
Packit Service fb6fa5
		  XRenderPictFormat *mask_format,
Packit Service fb6fa5
		  guchar            *src_rgb,
Packit Service fb6fa5
		  gint               src_rowstride,
Packit Service fb6fa5
		  gint               dest_x,
Packit Service fb6fa5
		  gint               dest_y,
Packit Service fb6fa5
		  gint               width,
Packit Service fb6fa5
		  gint               height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
Packit Service fb6fa5
  Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
Packit Service fb6fa5
  GdkImage *image;
Packit Service fb6fa5
  GdkPixmap *pix;
Packit Service fb6fa5
  GdkGC *pix_gc;
Packit Service fb6fa5
  Picture pict;
Packit Service fb6fa5
  Picture dest_pict;
Packit Service fb6fa5
  Picture mask = None;
Packit Service fb6fa5
  gint x0, y0;
Packit Service fb6fa5
Packit Service fb6fa5
  pix = gdk_pixmap_new (gdk_screen_get_root_window (screen), width, height, 32);
Packit Service fb6fa5
						  
Packit Service fb6fa5
  pict = XRenderCreatePicture (xdisplay, 
Packit Service fb6fa5
			       GDK_PIXMAP_XID (pix),
Packit Service fb6fa5
			       format, 0, NULL);
Packit Service fb6fa5
  if (mask_format)
Packit Service fb6fa5
    mask = XRenderCreatePicture (xdisplay, 
Packit Service fb6fa5
				 GDK_PIXMAP_XID (pix),
Packit Service fb6fa5
				 mask_format, 0, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  dest_pict = gdk_x11_drawable_get_picture (drawable);  
Packit Service fb6fa5
  
Packit Service fb6fa5
  pix_gc = _gdk_drawable_get_scratch_gc (pix, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
Packit Service fb6fa5
      for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gint xs0, ys0;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  image = _gdk_image_get_scratch (screen, width1, height1, 32, &xs0, &ys0;;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  _gdk_x11_convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
Packit Service fb6fa5
                                      (guchar *)image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl,
Packit Service fb6fa5
                                      format_type, image->byte_order, 
Packit Service fb6fa5
                                      width1, height1);
Packit Service fb6fa5
Packit Service fb6fa5
	  gdk_draw_image (pix, pix_gc,
Packit Service fb6fa5
			  image, xs0, ys0, x0, y0, width1, height1);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  XRenderComposite (xdisplay, PictOpOver, pict, mask, dest_pict, 
Packit Service fb6fa5
		    0, 0, 0, 0, dest_x, dest_y, width, height);
Packit Service fb6fa5
Packit Service fb6fa5
  XRenderFreePicture (xdisplay, pict);
Packit Service fb6fa5
  if (mask)
Packit Service fb6fa5
    XRenderFreePicture (xdisplay, mask);
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_object_unref (pix);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
typedef struct _ShmPixmapInfo ShmPixmapInfo;
Packit Service fb6fa5
Packit Service fb6fa5
struct _ShmPixmapInfo
Packit Service fb6fa5
{
Packit Service fb6fa5
  Display  *display;
Packit Service fb6fa5
  Pixmap    pix;
Packit Service fb6fa5
  Picture   pict;
Packit Service fb6fa5
  Picture   mask;
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
shm_pixmap_info_destroy (gpointer data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  ShmPixmapInfo *info = data;
Packit Service fb6fa5
Packit Service fb6fa5
  if (info->pict != None)
Packit Service fb6fa5
    XRenderFreePicture (info->display, info->pict);
Packit Service fb6fa5
  if (info->mask != None)
Packit Service fb6fa5
    XRenderFreePicture (info->display, info->mask);
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (data);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef USE_SHM
Packit Service fb6fa5
/* Returns FALSE if we can't get a shm pixmap */
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
get_shm_pixmap_for_image (Display           *xdisplay,
Packit Service fb6fa5
			  GdkImage          *image,
Packit Service fb6fa5
			  XRenderPictFormat *format,
Packit Service fb6fa5
			  XRenderPictFormat *mask_format,
Packit Service fb6fa5
			  Pixmap            *pix,
Packit Service fb6fa5
			  Picture           *pict,
Packit Service fb6fa5
			  Picture           *mask)
Packit Service fb6fa5
{
Packit Service fb6fa5
  ShmPixmapInfo *info;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (image->type != GDK_IMAGE_SHARED)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
  
Packit Service fb6fa5
  info = g_object_get_data (G_OBJECT (image), "gdk-x11-shm-pixmap");
Packit Service fb6fa5
  if (!info)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      *pix = _gdk_x11_image_get_shm_pixmap (image);
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (!*pix)
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
      
Packit Service fb6fa5
      info = g_new (ShmPixmapInfo, 1);
Packit Service fb6fa5
      info->display = xdisplay;
Packit Service fb6fa5
      info->pix = *pix;
Packit Service fb6fa5
      
Packit Service fb6fa5
      info->pict = XRenderCreatePicture (xdisplay, info->pix,
Packit Service fb6fa5
					 format, 0, NULL);
Packit Service fb6fa5
      if (mask_format)
Packit Service fb6fa5
	info->mask = XRenderCreatePicture (xdisplay, info->pix,
Packit Service fb6fa5
					   mask_format, 0, NULL);
Packit Service fb6fa5
      else
Packit Service fb6fa5
	info->mask = None;
Packit Service fb6fa5
Packit Service fb6fa5
      g_object_set_data_full (G_OBJECT (image), "gdk-x11-shm-pixmap", info,
Packit Service fb6fa5
	  shm_pixmap_info_destroy);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  *pix = info->pix;
Packit Service fb6fa5
  *pict = info->pict;
Packit Service fb6fa5
  *mask = info->mask;
Packit Service fb6fa5
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* Returns FALSE if drawing with ShmPixmaps is not possible */
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
draw_with_pixmaps (GdkDrawable       *drawable,
Packit Service fb6fa5
		   GdkGC             *gc,
Packit Service fb6fa5
		   GdkX11FormatType   format_type,
Packit Service fb6fa5
		   XRenderPictFormat *format,
Packit Service fb6fa5
		   XRenderPictFormat *mask_format,
Packit Service fb6fa5
		   guchar            *src_rgb,
Packit Service fb6fa5
		   gint               src_rowstride,
Packit Service fb6fa5
		   gint               dest_x,
Packit Service fb6fa5
		   gint               dest_y,
Packit Service fb6fa5
		   gint               width,
Packit Service fb6fa5
		   gint               height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  Display *xdisplay = GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (drawable)->screen);
Packit Service fb6fa5
  GdkImage *image;
Packit Service fb6fa5
  Pixmap pix;
Packit Service fb6fa5
  Picture pict;
Packit Service fb6fa5
  Picture dest_pict;
Packit Service fb6fa5
  Picture mask = None;
Packit Service fb6fa5
  gint x0, y0;
Packit Service fb6fa5
Packit Service fb6fa5
  dest_pict = gdk_x11_drawable_get_picture (drawable);
Packit Service fb6fa5
  
Packit Service fb6fa5
  for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
Packit Service fb6fa5
      for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gint xs0, ys0;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  image = _gdk_image_get_scratch (GDK_DRAWABLE_IMPL_X11 (drawable)->screen,
Packit Service fb6fa5
					  width1, height1, 32, &xs0, &ys0;;
Packit Service fb6fa5
	  if (!get_shm_pixmap_for_image (xdisplay, image, format, mask_format, &pix, &pict, &mask))
Packit Service fb6fa5
	    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
	  _gdk_x11_convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
Packit Service fb6fa5
                                      (guchar *)image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl,
Packit Service fb6fa5
                                      format_type, image->byte_order, 
Packit Service fb6fa5
                                      width1, height1);
Packit Service fb6fa5
Packit Service fb6fa5
	  XRenderComposite (xdisplay, PictOpOver, pict, mask, dest_pict, 
Packit Service fb6fa5
			    xs0, ys0, xs0, ys0, x0 + dest_x, y0 + dest_y,
Packit Service fb6fa5
			    width1, height1);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_draw_pixbuf (GdkDrawable     *drawable,
Packit Service fb6fa5
		     GdkGC           *gc,
Packit Service fb6fa5
		     GdkPixbuf       *pixbuf,
Packit Service fb6fa5
		     gint             src_x,
Packit Service fb6fa5
		     gint             src_y,
Packit Service fb6fa5
		     gint             dest_x,
Packit Service fb6fa5
		     gint             dest_y,
Packit Service fb6fa5
		     gint             width,
Packit Service fb6fa5
		     gint             height,
Packit Service fb6fa5
		     GdkRgbDither     dither,
Packit Service fb6fa5
		     gint             x_dither,
Packit Service fb6fa5
		     gint             y_dither)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkX11FormatType format_type;
Packit Service fb6fa5
  XRenderPictFormat *format, *mask_format;
Packit Service fb6fa5
  gint rowstride;
Packit Service fb6fa5
#ifdef USE_SHM  
Packit Service fb6fa5
  gboolean use_pixmaps = TRUE;
Packit Service fb6fa5
#endif /* USE_SHM */
Packit Service fb6fa5
    
Packit Service fb6fa5
  format_type = select_format (gdk_drawable_get_display (drawable),
Packit Service fb6fa5
			       &format, &mask_format);
Packit Service fb6fa5
Packit Service fb6fa5
  if (format_type == GDK_X11_FORMAT_NONE ||
Packit Service fb6fa5
      !gdk_pixbuf_get_has_alpha (pixbuf) ||
Packit Service fb6fa5
      gdk_drawable_get_depth (drawable) == 1 ||
Packit Service fb6fa5
      (dither == GDK_RGB_DITHER_MAX && gdk_drawable_get_depth (drawable) != 24) ||
Packit Service fb6fa5
      gdk_x11_drawable_get_picture (drawable) == None)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GdkDrawable *wrapper = GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper;
Packit Service fb6fa5
      GDK_DRAWABLE_CLASS (_gdk_drawable_impl_x11_parent_class)->draw_pixbuf (wrapper, gc, pixbuf,
Packit Service fb6fa5
									     src_x, src_y, dest_x, dest_y,
Packit Service fb6fa5
									     width, height,
Packit Service fb6fa5
									     dither, x_dither, y_dither);
Packit Service fb6fa5
      return;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  gdk_x11_drawable_update_picture_clip (drawable, gc);
Packit Service fb6fa5
Packit Service fb6fa5
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef USE_SHM
Packit Service fb6fa5
  if (use_pixmaps)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (!draw_with_pixmaps (drawable, gc,
Packit Service fb6fa5
			      format_type, format, mask_format,
Packit Service fb6fa5
			      gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * 4,
Packit Service fb6fa5
			      rowstride,
Packit Service fb6fa5
			      dest_x, dest_y, width, height))
Packit Service fb6fa5
	use_pixmaps = FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (!use_pixmaps)
Packit Service fb6fa5
#endif /* USE_SHM */
Packit Service fb6fa5
    draw_with_images (drawable, gc,
Packit Service fb6fa5
		      format_type, format, mask_format,
Packit Service fb6fa5
		      gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * 4,
Packit Service fb6fa5
		      rowstride,
Packit Service fb6fa5
		      dest_x, dest_y, width, height);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_x11_cairo_surface_destroy (void *data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl = data;
Packit Service fb6fa5
Packit Service fb6fa5
  impl->cairo_surface = NULL;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface,
Packit Service fb6fa5
				       int width,
Packit Service fb6fa5
				       int height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  cairo_xlib_surface_set_size (surface, width, height);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
cairo_surface_t *
Packit Service fb6fa5
_gdk_windowing_create_cairo_surface (GdkDrawable *drawable,
Packit Service fb6fa5
				     int width,
Packit Service fb6fa5
				     int height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
  GdkVisual *visual;
Packit Service fb6fa5
    
Packit Service fb6fa5
  visual = gdk_drawable_get_visual (drawable);
Packit Service fb6fa5
  if (visual) 
Packit Service fb6fa5
    return cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (impl->screen),
Packit Service fb6fa5
				      impl->xid,
Packit Service fb6fa5
				      GDK_VISUAL_XVISUAL (visual),
Packit Service fb6fa5
				      width, height);
Packit Service fb6fa5
  else if (gdk_drawable_get_depth (drawable) == 1)
Packit Service fb6fa5
    return cairo_xlib_surface_create_for_bitmap (GDK_SCREEN_XDISPLAY (impl->screen),
Packit Service fb6fa5
						    impl->xid,
Packit Service fb6fa5
						    GDK_SCREEN_XSCREEN (impl->screen),
Packit Service fb6fa5
						    width, height);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_warning ("Using Cairo rendering requires the drawable argument to\n"
Packit Service fb6fa5
		 "have a specified colormap. All windows have a colormap,\n"
Packit Service fb6fa5
		 "however, pixmaps only have colormap by default if they\n"
Packit Service fb6fa5
		 "were created with a non-NULL window argument. Otherwise\n"
Packit Service fb6fa5
		 "a colormap must be set on them with gdk_drawable_set_colormap");
Packit Service fb6fa5
      return NULL;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static cairo_surface_t *
Packit Service fb6fa5
gdk_x11_ref_cairo_surface (GdkDrawable *drawable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
Packit Service fb6fa5
Packit Service fb6fa5
  if (GDK_IS_WINDOW_IMPL_X11 (drawable) &&
Packit Service fb6fa5
      GDK_WINDOW_DESTROYED (impl->wrapper))
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!impl->cairo_surface)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      int width, height;
Packit Service fb6fa5
  
Packit Service fb6fa5
      gdk_drawable_get_size (impl->wrapper, &width, &height);
Packit Service fb6fa5
Packit Service fb6fa5
      impl->cairo_surface = _gdk_windowing_create_cairo_surface (drawable, width, height);
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (impl->cairo_surface)
Packit Service fb6fa5
	cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key,
Packit Service fb6fa5
				     drawable, gdk_x11_cairo_surface_destroy);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    cairo_surface_reference (impl->cairo_surface);
Packit Service fb6fa5
Packit Service fb6fa5
  return impl->cairo_surface;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
#define __GDK_DRAWABLE_X11_C__
Packit Service fb6fa5
#include "gdkaliasdef.c"