Blame gdk/gdkimage.c

Packit Service fb6fa5
/* GDK - The 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
#include <stdlib.h>
Packit Service fb6fa5
#include <sys/types.h>
Packit Service fb6fa5
Packit Service fb6fa5
#include "gdk.h"		/* For gdk_flush() */
Packit Service fb6fa5
#include "gdkimage.h"
Packit Service fb6fa5
#include "gdkprivate.h"
Packit Service fb6fa5
#include "gdkinternals.h"	/* For scratch_image code */
Packit Service fb6fa5
#include "gdkalias.h"
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_ref:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated function; use g_object_ref() instead.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: the image
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.0: Use g_object_ref() instead.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkImage *
Packit Service fb6fa5
gdk_image_ref (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return g_object_ref (image);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_unref:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated function; use g_object_unref() instead.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.0: Use g_object_unref() instead.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gdk_image_unref (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (GDK_IS_IMAGE (image));
Packit Service fb6fa5
Packit Service fb6fa5
  g_object_unref (image);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get:
Packit Service fb6fa5
 * @drawable: a #GdkDrawable
Packit Service fb6fa5
 * @x: x coordinate in @window
Packit Service fb6fa5
 * @y: y coordinate in @window
Packit Service fb6fa5
 * @width: width of area in @window
Packit Service fb6fa5
 * @height: height of area in @window
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * This is a deprecated wrapper for gdk_drawable_get_image();
Packit Service fb6fa5
 * gdk_drawable_get_image() should be used instead. Or even better: in
Packit Service fb6fa5
 * most cases gdk_pixbuf_get_from_drawable() is the most convenient
Packit Service fb6fa5
 * choice.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: a new #GdkImage or %NULL
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkImage*
Packit Service fb6fa5
gdk_image_get (GdkWindow *drawable,
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
  g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
Packit Service fb6fa5
  g_return_val_if_fail (x >= 0, NULL);
Packit Service fb6fa5
  g_return_val_if_fail (y >= 0, NULL);
Packit Service fb6fa5
  g_return_val_if_fail (width >= 0, NULL);
Packit Service fb6fa5
  g_return_val_if_fail (height >= 0, NULL);
Packit Service fb6fa5
  
Packit Service fb6fa5
  return gdk_drawable_get_image (drawable, x, y, width, height);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_set_colormap:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 * @colormap: a #GdkColormap
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Sets the colormap for the image to the given colormap.  Normally
Packit Service fb6fa5
 * there's no need to use this function, images are created with the
Packit Service fb6fa5
 * correct colormap if you get the image from a drawable. If you
Packit Service fb6fa5
 * create the image from scratch, use the colormap of the drawable you
Packit Service fb6fa5
 * intend to render the image to.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gdk_image_set_colormap (GdkImage       *image,
Packit Service fb6fa5
                        GdkColormap    *colormap)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (GDK_IS_IMAGE (image));
Packit Service fb6fa5
  g_return_if_fail (GDK_IS_COLORMAP (colormap));
Packit Service fb6fa5
Packit Service fb6fa5
  if (image->colormap != colormap)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (image->colormap)
Packit Service fb6fa5
	g_object_unref (image->colormap);
Packit Service fb6fa5
Packit Service fb6fa5
      image->colormap = colormap;
Packit Service fb6fa5
      g_object_ref (image->colormap);
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_colormap:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Retrieves the colormap for a given image, if it exists.  An image
Packit Service fb6fa5
 * will have a colormap if the drawable from which it was created has
Packit Service fb6fa5
 * a colormap, or if a colormap was set explicitely with
Packit Service fb6fa5
 * gdk_image_set_colormap().
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: colormap for the image
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkColormap *
Packit Service fb6fa5
gdk_image_get_colormap (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->colormap;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_image_type:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines the type of a given image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: the #GdkImageType of the image
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkImageType
Packit Service fb6fa5
gdk_image_get_image_type (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->type;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_visual:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines the visual that was used to create the image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: a #GdkVisual
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkVisual *
Packit Service fb6fa5
gdk_image_get_visual (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->visual;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_byte_order:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines the byte order of the image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: a #GdkVisual
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkByteOrder
Packit Service fb6fa5
gdk_image_get_byte_order (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->byte_order;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_width:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines the width of the image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: the width
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gint
Packit Service fb6fa5
gdk_image_get_width (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->width;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_height:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines the height of the image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: the height
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gint
Packit Service fb6fa5
gdk_image_get_height (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->height;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_depth:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines the depth of the image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: the depth
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
guint16
Packit Service fb6fa5
gdk_image_get_depth (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->depth;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_bytes_per_pixel:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines the number of bytes per pixel of the image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: the bytes per pixel
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
guint16
Packit Service fb6fa5
gdk_image_get_bytes_per_pixel (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->bpp;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_bytes_per_line:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines the number of bytes per line of the image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: the bytes per line
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
guint16
Packit Service fb6fa5
gdk_image_get_bytes_per_line (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->bpl;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_bits_per_pixel:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Determines the number of bits per pixel of the image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: the bits per pixel
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
guint16
Packit Service fb6fa5
gdk_image_get_bits_per_pixel (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->bits_per_pixel;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gdk_image_get_pixels:
Packit Service fb6fa5
 * @image: a #GdkImage
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns a pointer to the pixel data of the image.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns: the pixel data of the image
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.22
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Deprecated: 2.22: #GdkImage should not be used anymore.
Packit Service fb6fa5
 */
Packit Service fb6fa5
gpointer
Packit Service fb6fa5
gdk_image_get_pixels (GdkImage *image)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_IMAGE (image), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return image->mem;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* We have N_REGION GDK_SCRATCH_IMAGE_WIDTH x GDK_SCRATCH_IMAGE_HEIGHT regions divided
Packit Service fb6fa5
 * up between n_images different images. possible_n_images gives
Packit Service fb6fa5
 * various divisors of N_REGIONS. The reason for allowing this
Packit Service fb6fa5
 * flexibility is that we want to create as few images as possible,
Packit Service fb6fa5
 * but we want to deal with the abberant systems that have a SHMMAX
Packit Service fb6fa5
 * limit less than
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * GDK_SCRATCH_IMAGE_WIDTH * GDK_SCRATCH_IMAGE_HEIGHT * N_REGIONS * 4 (384k)
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * (Are there any such?)
Packit Service fb6fa5
 */
Packit Service fb6fa5
#define N_REGIONS 6
Packit Service fb6fa5
static const int possible_n_images[] = { 1, 2, 3, 6 };
Packit Service fb6fa5
Packit Service fb6fa5
/* We allocate one GdkScratchImageInfo structure for each
Packit Service fb6fa5
 * depth where we are allocating scratch images. (Future: one
Packit Service fb6fa5
 * per depth, per display)
Packit Service fb6fa5
 */
Packit Service fb6fa5
typedef struct _GdkScratchImageInfo GdkScratchImageInfo;
Packit Service fb6fa5
Packit Service fb6fa5
struct _GdkScratchImageInfo {
Packit Service fb6fa5
  gint depth;
Packit Service fb6fa5
  
Packit Service fb6fa5
  gint n_images;
Packit Service fb6fa5
  GdkImage *static_image[N_REGIONS];
Packit Service fb6fa5
  gint static_image_idx;
Packit Service fb6fa5
Packit Service fb6fa5
  /* In order to optimize filling fractions, we simultaneously fill in up
Packit Service fb6fa5
   * to three regions of size GDK_SCRATCH_IMAGE_WIDTH * GDK_SCRATCH_IMAGE_HEIGHT: one
Packit Service fb6fa5
   * for images that are taller than GDK_SCRATCH_IMAGE_HEIGHT / 2, and must
Packit Service fb6fa5
   * be tiled horizontally. One for images that are wider than
Packit Service fb6fa5
   * GDK_SCRATCH_IMAGE_WIDTH / 2 and must be tiled vertically, and a third
Packit Service fb6fa5
   * for images smaller than GDK_SCRATCH_IMAGE_HEIGHT / 2 x GDK_SCRATCH_IMAGE_WIDTH x 2
Packit Service fb6fa5
   * that we tile in horizontal rows.
Packit Service fb6fa5
   */
Packit Service fb6fa5
  gint horiz_idx;
Packit Service fb6fa5
  gint horiz_y;
Packit Service fb6fa5
  gint vert_idx;
Packit Service fb6fa5
  gint vert_x;
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* tile_y1 and tile_y2 define the horizontal band into
Packit Service fb6fa5
   * which we are tiling images. tile_x is the x extent to
Packit Service fb6fa5
   * which that is filled
Packit Service fb6fa5
   */
Packit Service fb6fa5
  gint tile_idx;
Packit Service fb6fa5
  gint tile_x;
Packit Service fb6fa5
  gint tile_y1;
Packit Service fb6fa5
  gint tile_y2;
Packit Service fb6fa5
Packit Service fb6fa5
  GdkScreen *screen;
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
static GSList *scratch_image_infos = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
allocate_scratch_images (GdkScratchImageInfo *info,
Packit Service fb6fa5
			 gint                 n_images,
Packit Service fb6fa5
			 gboolean             shared)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
  
Packit Service fb6fa5
  for (i = 0; i < n_images; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      info->static_image[i] = _gdk_image_new_for_depth (info->screen,
Packit Service fb6fa5
							shared ? GDK_IMAGE_SHARED : GDK_IMAGE_NORMAL,
Packit Service fb6fa5
							NULL,
Packit Service fb6fa5
							GDK_SCRATCH_IMAGE_WIDTH * (N_REGIONS / n_images), 
Packit Service fb6fa5
							GDK_SCRATCH_IMAGE_HEIGHT,
Packit Service fb6fa5
							info->depth);
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (!info->static_image[i])
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gint j;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  for (j = 0; j < i; j++)
Packit Service fb6fa5
	    g_object_unref (info->static_image[j]);
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  return FALSE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
scratch_image_info_display_closed (GdkDisplay          *display,
Packit Service fb6fa5
                                   gboolean             is_error,
Packit Service fb6fa5
                                   GdkScratchImageInfo *image_info)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  g_signal_handlers_disconnect_by_func (display,
Packit Service fb6fa5
                                        scratch_image_info_display_closed,
Packit Service fb6fa5
                                        image_info);
Packit Service fb6fa5
Packit Service fb6fa5
  scratch_image_infos = g_slist_remove (scratch_image_infos, image_info);
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < image_info->n_images; i++)
Packit Service fb6fa5
    g_object_unref (image_info->static_image[i]);
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (image_info);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static GdkScratchImageInfo *
Packit Service fb6fa5
scratch_image_info_for_depth (GdkScreen *screen,
Packit Service fb6fa5
			      gint       depth)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GSList *tmp_list;
Packit Service fb6fa5
  GdkScratchImageInfo *image_info;
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  tmp_list = scratch_image_infos;
Packit Service fb6fa5
  while (tmp_list)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      image_info = tmp_list->data;
Packit Service fb6fa5
      if (image_info->depth == depth && image_info->screen == screen)
Packit Service fb6fa5
	return image_info;
Packit Service fb6fa5
      
Packit Service fb6fa5
      tmp_list = tmp_list->next;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  image_info = g_new (GdkScratchImageInfo, 1);
Packit Service fb6fa5
Packit Service fb6fa5
  image_info->depth = depth;
Packit Service fb6fa5
  image_info->screen = screen;
Packit Service fb6fa5
Packit Service fb6fa5
  g_signal_connect (gdk_screen_get_display (screen), "closed",
Packit Service fb6fa5
                    G_CALLBACK (scratch_image_info_display_closed),
Packit Service fb6fa5
                    image_info);
Packit Service fb6fa5
Packit Service fb6fa5
  /* Try to allocate as few possible shared images */
Packit Service fb6fa5
  for (i=0; i < G_N_ELEMENTS (possible_n_images); i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (allocate_scratch_images (image_info, possible_n_images[i], TRUE))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  image_info->n_images = possible_n_images[i];
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  /* If that fails, just allocate N_REGIONS normal images */
Packit Service fb6fa5
  if (i == G_N_ELEMENTS (possible_n_images))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      allocate_scratch_images (image_info, N_REGIONS, FALSE);
Packit Service fb6fa5
      image_info->n_images = N_REGIONS;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  image_info->static_image_idx = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  image_info->horiz_y = GDK_SCRATCH_IMAGE_HEIGHT;
Packit Service fb6fa5
  image_info->vert_x = GDK_SCRATCH_IMAGE_WIDTH;
Packit Service fb6fa5
  image_info->tile_x = GDK_SCRATCH_IMAGE_WIDTH;
Packit Service fb6fa5
  image_info->tile_y1 = image_info->tile_y2 = GDK_SCRATCH_IMAGE_HEIGHT;
Packit Service fb6fa5
Packit Service fb6fa5
  scratch_image_infos = g_slist_prepend (scratch_image_infos, image_info);
Packit Service fb6fa5
Packit Service fb6fa5
  return image_info;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* Defining NO_FLUSH can cause inconsistent screen updates, but is useful
Packit Service fb6fa5
   for performance evaluation. */
Packit Service fb6fa5
Packit Service fb6fa5
#undef NO_FLUSH
Packit Service fb6fa5
Packit Service fb6fa5
#ifdef VERBOSE
Packit Service fb6fa5
static gint sincelast;
Packit Service fb6fa5
#endif
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
alloc_scratch_image (GdkScratchImageInfo *image_info)
Packit Service fb6fa5
{
Packit Service fb6fa5
  if (image_info->static_image_idx == N_REGIONS)
Packit Service fb6fa5
    {
Packit Service fb6fa5
#ifndef NO_FLUSH
Packit Service fb6fa5
      gdk_flush ();
Packit Service fb6fa5
#endif
Packit Service fb6fa5
#ifdef VERBOSE
Packit Service fb6fa5
      g_print ("flush, %d puts since last flush\n", sincelast);
Packit Service fb6fa5
      sincelast = 0;
Packit Service fb6fa5
#endif
Packit Service fb6fa5
      image_info->static_image_idx = 0;
Packit Service fb6fa5
Packit Service fb6fa5
      /* Mark all regions that we might be filling in as completely
Packit Service fb6fa5
       * full, to force new tiles to be allocated for subsequent
Packit Service fb6fa5
       * images
Packit Service fb6fa5
       */
Packit Service fb6fa5
      image_info->horiz_y = GDK_SCRATCH_IMAGE_HEIGHT;
Packit Service fb6fa5
      image_info->vert_x = GDK_SCRATCH_IMAGE_WIDTH;
Packit Service fb6fa5
      image_info->tile_x = GDK_SCRATCH_IMAGE_WIDTH;
Packit Service fb6fa5
      image_info->tile_y1 = image_info->tile_y2 = GDK_SCRATCH_IMAGE_HEIGHT;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return image_info->static_image_idx++;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * _gdk_image_get_scratch:
Packit Service fb6fa5
 * @screen: a #GdkScreen
Packit Service fb6fa5
 * @width: desired width
Packit Service fb6fa5
 * @height: desired height
Packit Service fb6fa5
 * @depth: depth of image 
Packit Service fb6fa5
 * @x: X location within returned image of scratch image
Packit Service fb6fa5
 * @y: Y location within returned image of scratch image
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Allocates an image of size width/height, up to a maximum
Packit Service fb6fa5
 * of GDK_SCRATCH_IMAGE_WIDTHxGDK_SCRATCH_IMAGE_HEIGHT that is
Packit Service fb6fa5
 * suitable to use on @screen.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: a scratch image. This must be used by a
Packit Service fb6fa5
 *  call to gdk_image_put() before any other calls to
Packit Service fb6fa5
 *  _gdk_image_get_scratch()
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GdkImage *
Packit Service fb6fa5
_gdk_image_get_scratch (GdkScreen   *screen,
Packit Service fb6fa5
			gint	     width,			
Packit Service fb6fa5
			gint	     height,
Packit Service fb6fa5
			gint	     depth,
Packit Service fb6fa5
			gint	    *x,
Packit Service fb6fa5
			gint	    *y)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkScratchImageInfo *image_info;
Packit Service fb6fa5
  GdkImage *image;
Packit Service fb6fa5
  gint idx;
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  image_info = scratch_image_info_for_depth (screen, depth);
Packit Service fb6fa5
Packit Service fb6fa5
  if (width >= (GDK_SCRATCH_IMAGE_WIDTH >> 1))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (height >= (GDK_SCRATCH_IMAGE_HEIGHT >> 1))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  idx = alloc_scratch_image (image_info);
Packit Service fb6fa5
	  *x = 0;
Packit Service fb6fa5
	  *y = 0;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (height + image_info->horiz_y > GDK_SCRATCH_IMAGE_HEIGHT)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      image_info->horiz_idx = alloc_scratch_image (image_info);
Packit Service fb6fa5
	      image_info->horiz_y = 0;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  idx = image_info->horiz_idx;
Packit Service fb6fa5
	  *x = 0;
Packit Service fb6fa5
	  *y = image_info->horiz_y;
Packit Service fb6fa5
	  image_info->horiz_y += height;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (height >= (GDK_SCRATCH_IMAGE_HEIGHT >> 1))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (width + image_info->vert_x > GDK_SCRATCH_IMAGE_WIDTH)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      image_info->vert_idx = alloc_scratch_image (image_info);
Packit Service fb6fa5
	      image_info->vert_x = 0;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  idx = image_info->vert_idx;
Packit Service fb6fa5
	  *x = image_info->vert_x;
Packit Service fb6fa5
	  *y = 0;
Packit Service fb6fa5
	  /* using 3 and -4 would be slightly more efficient on 32-bit machines
Packit Service fb6fa5
	     with > 1bpp displays */
Packit Service fb6fa5
	  image_info->vert_x += (width + 7) & -8;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (width + image_info->tile_x > GDK_SCRATCH_IMAGE_WIDTH)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      image_info->tile_y1 = image_info->tile_y2;
Packit Service fb6fa5
	      image_info->tile_x = 0;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  if (height + image_info->tile_y1 > GDK_SCRATCH_IMAGE_HEIGHT)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      image_info->tile_idx = alloc_scratch_image (image_info);
Packit Service fb6fa5
	      image_info->tile_x = 0;
Packit Service fb6fa5
	      image_info->tile_y1 = 0;
Packit Service fb6fa5
	      image_info->tile_y2 = 0;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  if (height + image_info->tile_y1 > image_info->tile_y2)
Packit Service fb6fa5
	    image_info->tile_y2 = height + image_info->tile_y1;
Packit Service fb6fa5
	  idx = image_info->tile_idx;
Packit Service fb6fa5
	  *x = image_info->tile_x;
Packit Service fb6fa5
	  *y = image_info->tile_y1;
Packit Service fb6fa5
	  image_info->tile_x += (width + 7) & -8;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  image = image_info->static_image[idx * image_info->n_images / N_REGIONS];
Packit Service fb6fa5
  *x += GDK_SCRATCH_IMAGE_WIDTH * (idx % (N_REGIONS / image_info->n_images));
Packit Service fb6fa5
#ifdef VERBOSE
Packit Service fb6fa5
  g_print ("index %d, x %d, y %d (%d x %d)\n", idx, *x, *y, width, height);
Packit Service fb6fa5
  sincelast++;
Packit Service fb6fa5
#endif
Packit Service fb6fa5
  return image;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkImage*
Packit Service fb6fa5
gdk_image_new (GdkImageType  type,
Packit Service fb6fa5
	       GdkVisual    *visual,
Packit Service fb6fa5
	       gint          width,
Packit Service fb6fa5
	       gint          height)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return _gdk_image_new_for_depth (gdk_visual_get_screen (visual), type,
Packit Service fb6fa5
				   visual, width, height, -1);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
#define __GDK_IMAGE_C__
Packit Service fb6fa5
#include "gdkaliasdef.c"