Blame gdk/directfb/gdkimage-directfb.c

Packit 98cdb6
/* GDK - The GIMP Drawing Kit
Packit 98cdb6
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Lesser General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 98cdb6
 * Lesser General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Lesser General Public
Packit 98cdb6
 * License along with this library; if not, write to the
Packit 98cdb6
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 98cdb6
 * Boston, MA 02111-1307, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit 98cdb6
 * file for a list of people on the GTK+ Team.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * GTK+ DirectFB backend
Packit 98cdb6
 * Copyright (C) 2001-2002  convergence integrated media GmbH
Packit 98cdb6
 * Copyright (C) 2002-2004  convergence GmbH
Packit 98cdb6
 * Written by Denis Oliver Kropp <dok@convergence.de> and
Packit 98cdb6
 *            Sven Neumann <sven@convergence.de>
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include "config.h"
Packit 98cdb6
#include "gdk.h"
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
#include "gdkdirectfb.h"
Packit 98cdb6
#include "gdkprivate-directfb.h"
Packit 98cdb6
Packit 98cdb6
#include "gdkinternals.h"
Packit 98cdb6
Packit 98cdb6
#include "gdkimage.h"
Packit 98cdb6
#include "gdkalias.h"
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static GList    *image_list   = NULL;
Packit 98cdb6
static gpointer  parent_class = NULL;
Packit 98cdb6
Packit 98cdb6
static void gdk_directfb_image_destroy (GdkImage      *image);
Packit 98cdb6
static void gdk_image_init             (GdkImage      *image);
Packit 98cdb6
static void gdk_image_class_init       (GdkImageClass *klass);
Packit 98cdb6
static void gdk_image_finalize         (GObject       *object);
Packit 98cdb6
Packit 98cdb6
G_DEFINE_TYPE (GdkImage, gdk_image, G_TYPE_OBJECT)
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_image_init (GdkImage *image)
Packit 98cdb6
{
Packit 98cdb6
  image->windowing_data = g_new0 (GdkImageDirectFB, 1);
Packit 98cdb6
  image->mem = NULL;
Packit 98cdb6
Packit 98cdb6
  image_list = g_list_prepend (image_list, image);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_image_class_init (GdkImageClass *klass)
Packit 98cdb6
{
Packit 98cdb6
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit 98cdb6
Packit 98cdb6
  parent_class = g_type_class_peek_parent (klass);
Packit 98cdb6
Packit 98cdb6
  object_class->finalize = gdk_image_finalize;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_image_finalize (GObject *object)
Packit 98cdb6
{
Packit 98cdb6
  GdkImage *image;
Packit 98cdb6
Packit 98cdb6
  image = GDK_IMAGE (object);
Packit 98cdb6
Packit 98cdb6
  image_list = g_list_remove (image_list, image);
Packit 98cdb6
Packit 98cdb6
  if (image->depth == 1)
Packit 98cdb6
    g_free (image->mem);
Packit 98cdb6
Packit 98cdb6
  gdk_directfb_image_destroy (image);
Packit 98cdb6
Packit 98cdb6
  if (G_OBJECT_CLASS (parent_class)->finalize)
Packit 98cdb6
    G_OBJECT_CLASS (parent_class)->finalize (object);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
/* this function is called from the atexit handler! */
Packit 98cdb6
void
Packit 98cdb6
_gdk_image_exit (void)
Packit 98cdb6
{
Packit 98cdb6
  GObject *image;
Packit 98cdb6
Packit 98cdb6
  while (image_list)
Packit 98cdb6
    {
Packit 98cdb6
      image = image_list->data;
Packit 98cdb6
Packit 98cdb6
      gdk_image_finalize (image);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkImage *
Packit 98cdb6
gdk_image_new_bitmap (GdkVisual *visual,
Packit 98cdb6
                      gpointer   data,
Packit 98cdb6
                      gint       w,
Packit 98cdb6
                      gint       h)
Packit 98cdb6
{
Packit 98cdb6
  GdkImage         *image;
Packit 98cdb6
  GdkImageDirectFB *private;
Packit 98cdb6
Packit 98cdb6
  image = g_object_new (gdk_image_get_type (), NULL);
Packit 98cdb6
  private = image->windowing_data;
Packit 98cdb6
Packit 98cdb6
  image->type   = GDK_IMAGE_SHARED;
Packit 98cdb6
  image->visual = visual;
Packit 98cdb6
  image->width  = w;
Packit 98cdb6
  image->height = h;
Packit 98cdb6
  image->depth  = 1;
Packit 98cdb6
Packit 98cdb6
  GDK_NOTE (MISC, g_print ("gdk_image_new_bitmap: %dx%d\n", w, h));
Packit 98cdb6
Packit 98cdb6
  g_message ("not fully implemented %s", G_STRFUNC);
Packit 98cdb6
Packit 98cdb6
  image->bpl = (w + 7) / 8;
Packit 98cdb6
  image->mem = g_malloc (image->bpl * h);
Packit 98cdb6
#if G_BYTE_ORDER == G_BIG_ENDIAN
Packit 98cdb6
  image->byte_order = GDK_MSB_FIRST;
Packit 98cdb6
#else
Packit 98cdb6
  image->byte_order = GDK_LSB_FIRST;
Packit 98cdb6
#endif
Packit 98cdb6
  image->bpp = 1;
Packit 98cdb6
Packit 98cdb6
  return image;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gdk_windowing_image_init (void)
Packit 98cdb6
{
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkImage*
Packit 98cdb6
_gdk_image_new_for_depth (GdkScreen    *screen,
Packit 98cdb6
                          GdkImageType  type,
Packit 98cdb6
                          GdkVisual    *visual,
Packit 98cdb6
                          gint          width,
Packit 98cdb6
                          gint          height,
Packit 98cdb6
                          gint          depth)
Packit 98cdb6
{
Packit 98cdb6
  GdkImage              *image;
Packit 98cdb6
  GdkImageDirectFB      *private;
Packit 98cdb6
  DFBResult              ret;
Packit 98cdb6
  gint                   pitch;
Packit 98cdb6
  DFBSurfacePixelFormat  format;
Packit 98cdb6
  IDirectFBSurface      *surface;
Packit 98cdb6
Packit 98cdb6
  if (type == GDK_IMAGE_FASTEST || type == GDK_IMAGE_NORMAL)
Packit 98cdb6
    type = GDK_IMAGE_SHARED;
Packit 98cdb6
Packit 98cdb6
  if (visual)
Packit 98cdb6
    depth = visual->depth;
Packit 98cdb6
Packit 98cdb6
  switch (depth)
Packit 98cdb6
    {
Packit 98cdb6
    case 8:
Packit 98cdb6
      format = DSPF_LUT8;
Packit 98cdb6
      break;
Packit 98cdb6
    case 15:
Packit 98cdb6
      format = DSPF_ARGB1555;
Packit 98cdb6
      break;
Packit 98cdb6
    case 16:
Packit 98cdb6
      format = DSPF_RGB16;
Packit 98cdb6
      break;
Packit 98cdb6
    case 24:
Packit 98cdb6
      format = DSPF_RGB32;
Packit 98cdb6
      break;
Packit 98cdb6
    case 32:
Packit 98cdb6
      format = DSPF_ARGB;
Packit 98cdb6
      break;
Packit 98cdb6
    default:
Packit 98cdb6
      g_message ("unimplemented %s for depth %d", G_STRFUNC, depth);
Packit 98cdb6
      return NULL;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  surface = gdk_display_dfb_create_surface (_gdk_display, format,
Packit 98cdb6
                                            width, height);
Packit 98cdb6
  if (!surface)
Packit 98cdb6
    {
Packit 98cdb6
      return NULL;
Packit 98cdb6
    }
Packit 98cdb6
  surface->GetPixelFormat (surface, &format);
Packit 98cdb6
Packit 98cdb6
  image = g_object_new (gdk_image_get_type (), NULL);
Packit 98cdb6
  private = image->windowing_data;
Packit 98cdb6
Packit 98cdb6
  private->surface = surface;
Packit 98cdb6
Packit 98cdb6
  ret = surface->Lock (surface, DSLF_WRITE, &image->mem, &pitch);
Packit 98cdb6
  if (ret)
Packit 98cdb6
    {
Packit 98cdb6
      DirectFBError ("IDirectFBSurface::Lock() for writing failed!\n", ret);
Packit 98cdb6
      g_object_unref (image);
Packit 98cdb6
      return NULL;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  image->type           = type;
Packit 98cdb6
  image->visual         = visual;
Packit 98cdb6
#if G_BYTE_ORDER == G_BIG_ENDIAN
Packit 98cdb6
  image->byte_order	= GDK_MSB_FIRST;
Packit 98cdb6
#else
Packit 98cdb6
  image->byte_order 	= GDK_LSB_FIRST;
Packit 98cdb6
#endif
Packit 98cdb6
  image->width          = width;
Packit 98cdb6
  image->height         = height;
Packit 98cdb6
  image->depth          = depth;
Packit 98cdb6
  image->bpp            = DFB_BYTES_PER_PIXEL (format);
Packit 98cdb6
  image->bpl            = pitch;
Packit 98cdb6
  image->bits_per_pixel = DFB_BITS_PER_PIXEL (format);
Packit 98cdb6
Packit 98cdb6
  image_list = g_list_prepend (image_list, image);
Packit 98cdb6
Packit 98cdb6
  return image;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
GdkImage*
Packit 98cdb6
_gdk_directfb_copy_to_image (GdkDrawable *drawable,
Packit 98cdb6
                             GdkImage    *image,
Packit 98cdb6
                             gint         src_x,
Packit 98cdb6
                             gint         src_y,
Packit 98cdb6
                             gint         dest_x,
Packit 98cdb6
                             gint         dest_y,
Packit 98cdb6
                             gint         width,
Packit 98cdb6
                             gint         height)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  GdkImageDirectFB        *private;
Packit 98cdb6
  int                      pitch;
Packit 98cdb6
  DFBRectangle             rect  = { src_x, src_y, width, height };
Packit 98cdb6
  IDirectFBDisplayLayer   *layer = _gdk_display->layer;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable), NULL);
Packit 98cdb6
  g_return_val_if_fail (image != NULL || (dest_x == 0 && dest_y == 0), NULL);
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  if (impl->wrapper == _gdk_parent_root)
Packit 98cdb6
    {
Packit 98cdb6
      DFBResult ret;
Packit 98cdb6
Packit 98cdb6
      ret = layer->SetCooperativeLevel (layer, DLSCL_ADMINISTRATIVE);
Packit 98cdb6
      if (ret)
Packit 98cdb6
        {
Packit 98cdb6
          DirectFBError ("_gdk_directfb_copy_to_image - SetCooperativeLevel",
Packit 98cdb6
                         ret);
Packit 98cdb6
          return NULL;
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      ret = layer->GetSurface (layer, &impl->surface);
Packit 98cdb6
      if (ret)
Packit 98cdb6
        {
Packit 98cdb6
          layer->SetCooperativeLevel (layer, DLSCL_SHARED);
Packit 98cdb6
          DirectFBError ("_gdk_directfb_copy_to_image - GetSurface", ret);
Packit 98cdb6
          return NULL;
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (!impl->surface)
Packit 98cdb6
    return NULL;
Packit 98cdb6
Packit 98cdb6
  if (!image)
Packit 98cdb6
    image =  gdk_image_new (GDK_IMAGE_NORMAL,
Packit 98cdb6
                            gdk_drawable_get_visual (drawable), width, height);
Packit 98cdb6
Packit 98cdb6
  private = image->windowing_data;
Packit 98cdb6
Packit 98cdb6
  private->surface->Unlock (private->surface);
Packit 98cdb6
Packit 98cdb6
  private->surface->Blit (private->surface,
Packit 98cdb6
                          impl->surface, &rect, dest_x, dest_y);
Packit 98cdb6
Packit 98cdb6
  private->surface->Lock (private->surface,
Packit 98cdb6
                          DSLF_READ | DSLF_WRITE,
Packit 98cdb6
                          &image->mem, &pitch);
Packit 98cdb6
  image->bpl = pitch;
Packit 98cdb6
Packit 98cdb6
  if (impl->wrapper == _gdk_parent_root)
Packit 98cdb6
    {
Packit 98cdb6
      impl->surface->Release (impl->surface);
Packit 98cdb6
      impl->surface = NULL;
Packit 98cdb6
      layer->SetCooperativeLevel (layer, DLSCL_SHARED);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return image;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
guint32
Packit 98cdb6
gdk_image_get_pixel (GdkImage *image,
Packit 98cdb6
                     gint      x,
Packit 98cdb6
                     gint      y)
Packit 98cdb6
{
Packit 98cdb6
  guint32 pixel = 0;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
Packit 98cdb6
Packit 98cdb6
  if (!(x >= 0 && x < image->width && y >= 0 && y < image->height))
Packit 98cdb6
    return 0;
Packit 98cdb6
Packit 98cdb6
  if (image->depth == 1)
Packit 98cdb6
    pixel = (((guchar *) image->mem)[y * image->bpl + (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0;
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      guchar *pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
Packit 98cdb6
Packit 98cdb6
      switch (image->bpp)
Packit 98cdb6
        {
Packit 98cdb6
        case 1:
Packit 98cdb6
          pixel = *pixelp;
Packit 98cdb6
          break;
Packit 98cdb6
Packit 98cdb6
        case 2:
Packit 98cdb6
          pixel = pixelp[0] | (pixelp[1] << 8);
Packit 98cdb6
          break;
Packit 98cdb6
Packit 98cdb6
        case 3:
Packit 98cdb6
          pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
Packit 98cdb6
          break;
Packit 98cdb6
Packit 98cdb6
        case 4:
Packit 98cdb6
          pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
Packit 98cdb6
          break;
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return pixel;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gdk_image_put_pixel (GdkImage *image,
Packit 98cdb6
                     gint       x,
Packit 98cdb6
                     gint       y,
Packit 98cdb6
                     guint32    pixel)
Packit 98cdb6
{
Packit 98cdb6
  g_return_if_fail (image != NULL);
Packit 98cdb6
Packit 98cdb6
  if (!(x >= 0 && x < image->width && y >= 0 && y < image->height))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (image->depth == 1)
Packit 98cdb6
    if (pixel & 1)
Packit 98cdb6
      ((guchar *) image->mem)[y * image->bpl + (x >> 3)] |= (1 << (7 - (x & 0x7)));
Packit 98cdb6
    else
Packit 98cdb6
      ((guchar *) image->mem)[y * image->bpl + (x >> 3)] &= ~(1 << (7 - (x & 0x7)));
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      guchar *pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
Packit 98cdb6
Packit 98cdb6
      switch (image->bpp)
Packit 98cdb6
        {
Packit 98cdb6
        case 4:
Packit 98cdb6
          pixelp[3] = 0xFF;
Packit 98cdb6
        case 3:
Packit 98cdb6
          pixelp[2] = ((pixel >> 16) & 0xFF);
Packit 98cdb6
        case 2:
Packit 98cdb6
          pixelp[1] = ((pixel >> 8) & 0xFF);
Packit 98cdb6
        case 1:
Packit 98cdb6
          pixelp[0] = (pixel & 0xFF);
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_image_destroy (GdkImage *image)
Packit 98cdb6
{
Packit 98cdb6
  GdkImageDirectFB *private;
Packit 98cdb6
Packit 98cdb6
  g_return_if_fail (GDK_IS_IMAGE (image));
Packit 98cdb6
Packit 98cdb6
  private = image->windowing_data;
Packit 98cdb6
Packit 98cdb6
  if (!private)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  GDK_NOTE (MISC, g_print ("gdk_directfb_image_destroy: %#lx\n",
Packit 98cdb6
                           (gulong) private->surface));
Packit 98cdb6
Packit 98cdb6
  private->surface->Unlock (private->surface);
Packit 98cdb6
  private->surface->Release (private->surface);
Packit 98cdb6
Packit 98cdb6
  g_free (private);
Packit 98cdb6
  image->windowing_data = NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gint
Packit 98cdb6
_gdk_windowing_get_bits_for_depth (GdkDisplay *display,
Packit 98cdb6
                                   gint        depth)
Packit 98cdb6
{
Packit 98cdb6
  switch (depth)
Packit 98cdb6
    {
Packit 98cdb6
    case 1:
Packit 98cdb6
    case 8:
Packit 98cdb6
      return 8;
Packit 98cdb6
    case 15:
Packit 98cdb6
    case 16:
Packit 98cdb6
      return 16;
Packit 98cdb6
    case 24:
Packit 98cdb6
    case 32:
Packit 98cdb6
      return 32;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return 0;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#define __GDK_IMAGE_X11_C__
Packit 98cdb6
#include "gdkaliasdef.c"