Blame gdk/directfb/gdkdrawable-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
#include <assert.h>
Packit 98cdb6
Packit 98cdb6
#include <string.h>
Packit 98cdb6
Packit 98cdb6
#include "gdkdirectfb.h"
Packit 98cdb6
#include "gdkprivate-directfb.h"
Packit 98cdb6
Packit 98cdb6
#include <gdk-pixbuf/gdk-pixbuf.h>
Packit 98cdb6
Packit 98cdb6
#include "gdkinternals.h"
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
#include "gdkregion-generic.h"
Packit 98cdb6
#include "gdkalias.h"
Packit 98cdb6
Packit 98cdb6
#include "cairo-directfb.h"
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
#include <direct/debug.h>
Packit 98cdb6
#include <direct/messages.h>
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * There can be multiple domains in one file and one domain (same same) in multiple files.
Packit 98cdb6
 */
Packit 98cdb6
D_DEBUG_DOMAIN (GDKDFB_Drawable, "GDKDFB/Drawable", "GDK DirectFB Drawable");
Packit 98cdb6
D_DEBUG_DOMAIN (GDKDFB_DrawClip, "GDKDFB/DrawClip", "GDK DirectFB Drawable Clip Region");
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
/* From DirectFB's <gfx/generix/duffs_device.h> */
Packit 98cdb6
#define DUFF_1()                                \
Packit 98cdb6
  case 1:                                       \
Packit 98cdb6
  SET_PIXEL (D[0], S[0]);
Packit 98cdb6
Packit 98cdb6
#define DUFF_2()                                \
Packit 98cdb6
  case 3:                                       \
Packit 98cdb6
  SET_PIXEL (D[2], S[2]);                       \
Packit 98cdb6
 case 2:                                        \
Packit 98cdb6
 SET_PIXEL (D[1], S[1]);                        \
Packit 98cdb6
 DUFF_1 ()
Packit 98cdb6
Packit 98cdb6
#define DUFF_3()                                \
Packit 98cdb6
  case 7:                                       \
Packit 98cdb6
  SET_PIXEL (D[6], S[6]);                       \
Packit 98cdb6
 case 6:                                        \
Packit 98cdb6
 SET_PIXEL (D[5], S[5]);                        \
Packit 98cdb6
 case 5:                                        \
Packit 98cdb6
 SET_PIXEL (D[4], S[4]);                        \
Packit 98cdb6
 case 4:                                        \
Packit 98cdb6
 SET_PIXEL (D[3], S[3]);                        \
Packit 98cdb6
 DUFF_2 ()
Packit 98cdb6
Packit 98cdb6
#define DUFF_4()                                \
Packit 98cdb6
  case 15:                                      \
Packit 98cdb6
  SET_PIXEL (D[14], S[14]);                     \
Packit 98cdb6
 case 14:                                       \
Packit 98cdb6
 SET_PIXEL (D[13], S[13]);                      \
Packit 98cdb6
 case 13:                                       \
Packit 98cdb6
 SET_PIXEL (D[12], S[12]);                      \
Packit 98cdb6
 case 12:                                       \
Packit 98cdb6
 SET_PIXEL (D[11], S[11]);                      \
Packit 98cdb6
 case 11:                                       \
Packit 98cdb6
 SET_PIXEL (D[10], S[10]);                      \
Packit 98cdb6
 case 10:                                       \
Packit 98cdb6
 SET_PIXEL (D[9], S[9]);                        \
Packit 98cdb6
 case 9:                                        \
Packit 98cdb6
 SET_PIXEL (D[8], S[8]);                        \
Packit 98cdb6
 case 8:                                        \
Packit 98cdb6
 SET_PIXEL (D[7], S[7]);                        \
Packit 98cdb6
 DUFF_3 ()
Packit 98cdb6
Packit 98cdb6
#define SET_PIXEL_DUFFS_DEVICE_N(D, S, w, n)            \
Packit 98cdb6
  do {                                                  \
Packit 98cdb6
    while (w) {                                         \
Packit 98cdb6
      register int l = w & ((1 << n) - 1);              \
Packit 98cdb6
      switch (l) {                                      \
Packit 98cdb6
      default:                                          \
Packit 98cdb6
        l = (1 << n);                                   \
Packit 98cdb6
        SET_PIXEL (D[(1 << n) - 1], S[(1 << n) - 1]);   \
Packit 98cdb6
        DUFF_##n ()                                     \
Packit 98cdb6
          }                                             \
Packit 98cdb6
      D += l;                                           \
Packit 98cdb6
      S += l;                                           \
Packit 98cdb6
      w -= l;                                           \
Packit 98cdb6
    }                                                   \
Packit 98cdb6
  } while(0)
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static GdkScreen *gdk_directfb_get_screen (GdkDrawable *drawable);
Packit 98cdb6
static void gdk_drawable_impl_directfb_class_init (GdkDrawableImplDirectFBClass *klass);
Packit 98cdb6
static void gdk_directfb_draw_lines (GdkDrawable *drawable,
Packit 98cdb6
                                     GdkGC       *gc,
Packit 98cdb6
                                     GdkPoint    *points,
Packit 98cdb6
                                     gint         npoints);
Packit 98cdb6
Packit 98cdb6
static cairo_surface_t *gdk_directfb_ref_cairo_surface (GdkDrawable *drawable);
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static gboolean  accelerated_alpha_blending = FALSE;
Packit 98cdb6
static gpointer  parent_class               = NULL;
Packit 98cdb6
static const cairo_user_data_key_t gdk_directfb_cairo_key;
Packit 98cdb6
Packit 98cdb6
static void (*real_draw_pixbuf) (GdkDrawable *drawable,
Packit 98cdb6
                                 GdkGC       *gc,
Packit 98cdb6
                                 GdkPixbuf   *pixbuf,
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
                                 GdkRgbDither dither,
Packit 98cdb6
                                 gint         x_dither,
Packit 98cdb6
                                 gint         y_dither);
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
/**********************************************************
Packit 98cdb6
 * DirectFB specific implementations of generic functions *
Packit 98cdb6
 **********************************************************/
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_set_colormap (GdkDrawable *drawable,
Packit 98cdb6
                           GdkColormap *colormap)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p, %p ) <- old %p\n",
Packit 98cdb6
              G_STRFUNC, drawable, colormap, impl->colormap);
Packit 98cdb6
Packit 98cdb6
  if (impl->colormap == colormap)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (impl->colormap)
Packit 98cdb6
    g_object_unref (impl->colormap);
Packit 98cdb6
Packit 98cdb6
  impl->colormap = colormap;
Packit 98cdb6
Packit 98cdb6
  if (colormap)
Packit 98cdb6
    g_object_ref (colormap);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GdkColormap*
Packit 98cdb6
gdk_directfb_get_colormap (GdkDrawable *drawable)
Packit 98cdb6
{
Packit 98cdb6
  GdkColormap *retval;
Packit 98cdb6
Packit 98cdb6
  retval = GDK_DRAWABLE_IMPL_DIRECTFB (drawable)->colormap;
Packit 98cdb6
Packit 98cdb6
  if (!retval) {
Packit 98cdb6
    retval = gdk_colormap_get_system ();
Packit 98cdb6
    gdk_directfb_set_colormap (drawable, retval);
Packit 98cdb6
  }
Packit 98cdb6
Packit 98cdb6
  return retval;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gint
Packit 98cdb6
gdk_directfb_get_depth (GdkDrawable *drawable)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  return DFB_BITS_PER_PIXEL (impl->format);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_get_size (GdkDrawable *drawable,
Packit 98cdb6
                       gint        *width,
Packit 98cdb6
                       gint        *height)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  if (width)
Packit 98cdb6
    *width = impl->width;
Packit 98cdb6
Packit 98cdb6
  if (height)
Packit 98cdb6
    *height = impl->height;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GdkVisual*
Packit 98cdb6
gdk_directfb_get_visual (GdkDrawable *drawable)
Packit 98cdb6
{
Packit 98cdb6
  return gdk_visual_get_system ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Calculates the real clipping region for a drawable, taking into account
Packit 98cdb6
 * other windows and the gc clip region.
Packit 98cdb6
 */
Packit 98cdb6
void
Packit 98cdb6
gdk_directfb_clip_region (GdkDrawable  *drawable,
Packit 98cdb6
                          GdkGC        *gc,
Packit 98cdb6
                          GdkRectangle *draw_rect,
Packit 98cdb6
                          GdkRegion    *ret_clip)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *private;
Packit 98cdb6
  GdkRectangle             rect;
Packit 98cdb6
Packit 98cdb6
  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
Packit 98cdb6
  g_return_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable));
Packit 98cdb6
  g_return_if_fail (ret_clip != NULL);
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_DrawClip, "%s( %p, %p, %p )\n",
Packit 98cdb6
              G_STRFUNC, drawable, gc, draw_rect);
Packit 98cdb6
Packit 98cdb6
  private = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  if (!draw_rect)
Packit 98cdb6
    {
Packit 98cdb6
      rect.x      = 0;
Packit 98cdb6
      rect.y      = 0;
Packit 98cdb6
      rect.width  = private->width;
Packit 98cdb6
      rect.height = private->height;
Packit 98cdb6
Packit 98cdb6
      draw_rect = ▭
Packit 98cdb6
    }
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_DrawClip, "  -> draw rectangle   == %4d,%4d - %4dx%4d =\n",
Packit 98cdb6
              draw_rect->x, draw_rect->y, draw_rect->width, draw_rect->height);
Packit 98cdb6
Packit 98cdb6
  temp_region_init_rectangle (ret_clip, draw_rect);
Packit 98cdb6
Packit 98cdb6
  if (private->buffered) {
Packit 98cdb6
    D_DEBUG_AT (GDKDFB_DrawClip, "  -> buffered region   > %4d,%4d - %4dx%4d <  (%ld boxes)\n",
Packit 98cdb6
                GDKDFB_RECTANGLE_VALS_FROM_BOX (&private->paint_region.extents),
Packit 98cdb6
                private->paint_region.numRects);
Packit 98cdb6
Packit 98cdb6
    gdk_region_intersect (ret_clip, &private->paint_region);
Packit 98cdb6
  }
Packit 98cdb6
Packit 98cdb6
  if (gc)
Packit 98cdb6
    {
Packit 98cdb6
      GdkGCDirectFB *gc_private = GDK_GC_DIRECTFB (gc);
Packit 98cdb6
      GdkRegion     *region     = &gc_private->clip_region;
Packit 98cdb6
Packit 98cdb6
      if (region->numRects)
Packit 98cdb6
        {
Packit 98cdb6
          D_DEBUG_AT (GDKDFB_DrawClip, "  -> clipping region   > %4d,%4d - %4dx%4d <  (%ld boxes)\n",
Packit 98cdb6
                      GDKDFB_RECTANGLE_VALS_FROM_BOX (&region->extents), region->numRects);
Packit 98cdb6
Packit 98cdb6
          if (gc->clip_x_origin || gc->clip_y_origin)
Packit 98cdb6
            {
Packit 98cdb6
              gdk_region_offset (ret_clip, -gc->clip_x_origin, -gc->clip_y_origin);
Packit 98cdb6
              gdk_region_intersect (ret_clip, region);
Packit 98cdb6
              gdk_region_offset (ret_clip, gc->clip_x_origin, gc->clip_y_origin);
Packit 98cdb6
            }
Packit 98cdb6
          else
Packit 98cdb6
            {
Packit 98cdb6
              gdk_region_intersect (ret_clip, region);
Packit 98cdb6
            }
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      if (gc_private->values_mask & GDK_GC_SUBWINDOW &&
Packit 98cdb6
          gc_private->values.subwindow_mode == GDK_INCLUDE_INFERIORS)
Packit 98cdb6
        return;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (private->buffered) {
Packit 98cdb6
    D_DEBUG_AT (GDKDFB_DrawClip, "  => returning clip   >> %4d,%4d - %4dx%4d << (%ld boxes)\n",
Packit 98cdb6
                GDKDFB_RECTANGLE_VALS_FROM_BOX (&ret_clip->extents), ret_clip->numRects);
Packit 98cdb6
    return;
Packit 98cdb6
  }
Packit 98cdb6
Packit 98cdb6
  if (GDK_IS_WINDOW (private->wrapper) &&
Packit 98cdb6
      GDK_WINDOW_IS_MAPPED (private->wrapper) &&
Packit 98cdb6
      !GDK_WINDOW_OBJECT (private->wrapper)->input_only)
Packit 98cdb6
    {
Packit 98cdb6
      GList     *cur;
Packit 98cdb6
      GdkRegion  temp;
Packit 98cdb6
Packit 98cdb6
      temp.numRects = 1;
Packit 98cdb6
      temp.rects = &temp.extents;
Packit 98cdb6
      temp.size = 1;
Packit 98cdb6
Packit 98cdb6
      for (cur = GDK_WINDOW_OBJECT (private->wrapper)->children;
Packit 98cdb6
           cur;
Packit 98cdb6
           cur = cur->next)
Packit 98cdb6
        {
Packit 98cdb6
          GdkWindowObject         *cur_private;
Packit 98cdb6
          GdkDrawableImplDirectFB *cur_impl;
Packit 98cdb6
Packit 98cdb6
          cur_private = GDK_WINDOW_OBJECT (cur->data);
Packit 98cdb6
Packit 98cdb6
          if (!GDK_WINDOW_IS_MAPPED (cur_private) || cur_private->input_only)
Packit 98cdb6
            continue;
Packit 98cdb6
Packit 98cdb6
          cur_impl = GDK_DRAWABLE_IMPL_DIRECTFB (cur_private->impl);
Packit 98cdb6
Packit 98cdb6
          temp.extents.x1 = cur_private->x;
Packit 98cdb6
          temp.extents.y1 = cur_private->y;
Packit 98cdb6
          temp.extents.x2 = cur_private->x + cur_impl->width;
Packit 98cdb6
          temp.extents.y2 = cur_private->y + cur_impl->height;
Packit 98cdb6
Packit 98cdb6
          D_DEBUG_AT (GDKDFB_DrawClip, "  -> clipping child    [ %4d,%4d - %4dx%4d ]  (%ld boxes)\n",
Packit 98cdb6
                      GDKDFB_RECTANGLE_VALS_FROM_BOX (&temp.extents), temp.numRects);
Packit 98cdb6
Packit 98cdb6
          gdk_region_subtract (ret_clip, &temp);
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_DrawClip, "  => returning clip   >> %4d,%4d - %4dx%4d << (%ld boxes)\n",
Packit 98cdb6
              GDKDFB_RECTANGLE_VALS_FROM_BOX (&ret_clip->extents), ret_clip->numRects);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Drawing
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
static inline void
Packit 98cdb6
gdk_directfb_set_color (GdkDrawableImplDirectFB *impl,
Packit 98cdb6
                        GdkColor                *color,
Packit 98cdb6
                        guchar                   alpha)
Packit 98cdb6
{
Packit 98cdb6
  if (DFB_PIXELFORMAT_IS_INDEXED (impl->format))
Packit 98cdb6
    {
Packit 98cdb6
      impl->surface->SetColorIndex (impl->surface, color->pixel);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      impl->surface->SetColor (impl->surface,
Packit 98cdb6
                               color->red   >> 8,
Packit 98cdb6
                               color->green >> 8,
Packit 98cdb6
                               color->blue  >> 8,
Packit 98cdb6
                               alpha);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gdk_directfb_setup_for_drawing (GdkDrawableImplDirectFB *impl,
Packit 98cdb6
                                GdkGCDirectFB           *gc_private)
Packit 98cdb6
{
Packit 98cdb6
  DFBSurfaceDrawingFlags flags = DSDRAW_NOFX;
Packit 98cdb6
  GdkColor               color = { 0, 0, 0, 0 };
Packit 98cdb6
  guchar                 alpha = 0xFF;
Packit 98cdb6
Packit 98cdb6
  if (!impl->surface)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
Packit 98cdb6
  if (gc_private && gc_private->values_mask & GDK_GC_FOREGROUND)
Packit 98cdb6
    color = gc_private->values.foreground;
Packit 98cdb6
Packit 98cdb6
  if (gc_private && gc_private->values_mask & GDK_GC_FUNCTION)
Packit 98cdb6
    {
Packit 98cdb6
      switch (gc_private->values.function)
Packit 98cdb6
        {
Packit 98cdb6
        case GDK_COPY:
Packit 98cdb6
          flags = DSDRAW_NOFX;
Packit 98cdb6
          break;
Packit 98cdb6
Packit 98cdb6
        case GDK_INVERT:
Packit 98cdb6
          color.red = color.green = color.blue = 0xFFFF;
Packit 98cdb6
          alpha = 0x0;
Packit 98cdb6
          flags = DSDRAW_XOR;
Packit 98cdb6
          break;
Packit 98cdb6
Packit 98cdb6
        case GDK_XOR:
Packit 98cdb6
          alpha = 0x0;
Packit 98cdb6
          flags = DSDRAW_XOR;
Packit 98cdb6
          break;
Packit 98cdb6
Packit 98cdb6
        case GDK_CLEAR:
Packit 98cdb6
          color.red = color.green = color.blue = 0x0;
Packit 98cdb6
          flags = DSDRAW_NOFX;
Packit 98cdb6
          break;
Packit 98cdb6
Packit 98cdb6
        case GDK_NOOP:
Packit 98cdb6
          return FALSE;
Packit 98cdb6
Packit 98cdb6
        case GDK_SET:
Packit 98cdb6
          color.red = color.green = color.blue = 0xFFFF;
Packit 98cdb6
          flags = DSDRAW_NOFX;
Packit 98cdb6
          break;
Packit 98cdb6
Packit 98cdb6
        default:
Packit 98cdb6
          g_message ("unsupported GC function %d",
Packit 98cdb6
                     gc_private->values.function);
Packit 98cdb6
          flags = DSDRAW_NOFX;
Packit 98cdb6
          break;
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  gdk_directfb_set_color (impl, &color, alpha);
Packit 98cdb6
Packit 98cdb6
  impl->surface->SetDrawingFlags (impl->surface, flags);
Packit 98cdb6
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_rectangle (GdkDrawable *drawable,
Packit 98cdb6
                             GdkGC       *gc,
Packit 98cdb6
                             gint         filled,
Packit 98cdb6
                             gint         x,
Packit 98cdb6
                             gint         y,
Packit 98cdb6
                             gint         width,
Packit 98cdb6
                             gint         height)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  GdkRegion                clip;
Packit 98cdb6
  GdkGCDirectFB           *gc_private = NULL;
Packit 98cdb6
  IDirectFBSurface        *surface    = NULL;
Packit 98cdb6
  gint  i;
Packit 98cdb6
Packit 98cdb6
  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p, %p, %s, %4d,%4d - %4dx%4d )\n", G_STRFUNC,
Packit 98cdb6
              drawable, gc, filled ? " filled" : "outline", x, y, width, height);
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  if (!impl->surface)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (gc)
Packit 98cdb6
    gc_private = GDK_GC_DIRECTFB (gc);
Packit 98cdb6
Packit 98cdb6
  if (gc_private)
Packit 98cdb6
    {
Packit 98cdb6
      if (gdk_directfb_enable_color_keying &&
Packit 98cdb6
	  (gc_private->values.foreground.red   >> 8) == gdk_directfb_bg_color_key.r &&
Packit 98cdb6
	  (gc_private->values.foreground.green >> 8) == gdk_directfb_bg_color_key.g &&
Packit 98cdb6
	  (gc_private->values.foreground.blue  >> 8) == gdk_directfb_bg_color_key.b)
Packit 98cdb6
	{
Packit 98cdb6
          if (DFB_PIXELFORMAT_IS_INDEXED (impl->format))
Packit 98cdb6
            impl->surface->SetColorIndex (impl->surface, 255);
Packit 98cdb6
          else
Packit 98cdb6
            impl->surface->SetColor (impl->surface,
Packit 98cdb6
                                     gdk_directfb_bg_color.r,
Packit 98cdb6
                                     gdk_directfb_bg_color.g,
Packit 98cdb6
                                     gdk_directfb_bg_color.b,
Packit 98cdb6
                                     gdk_directfb_bg_color.a);
Packit 98cdb6
	}
Packit 98cdb6
      else
Packit 98cdb6
	{
Packit 98cdb6
          if (!gdk_directfb_setup_for_drawing (impl, gc_private)) {
Packit 98cdb6
            return;
Packit 98cdb6
          }
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      GdkWindowObject *win = GDK_WINDOW_OBJECT (impl->wrapper);
Packit 98cdb6
Packit 98cdb6
      if (gdk_directfb_enable_color_keying)
Packit 98cdb6
	{
Packit 98cdb6
          if (DFB_PIXELFORMAT_IS_INDEXED (impl->format))
Packit 98cdb6
            impl->surface->SetColorIndex (impl->surface, 255);
Packit 98cdb6
          else
Packit 98cdb6
            impl->surface->SetColor (impl->surface,
Packit 98cdb6
                                     gdk_directfb_bg_color.r,
Packit 98cdb6
                                     gdk_directfb_bg_color.b,
Packit 98cdb6
                                     gdk_directfb_bg_color.g,
Packit 98cdb6
                                     gdk_directfb_bg_color.a);
Packit 98cdb6
	}
Packit 98cdb6
      else
Packit 98cdb6
	{
Packit 98cdb6
          gdk_directfb_set_color (impl, &win->bg_color, 0xFF);
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (filled)
Packit 98cdb6
    {
Packit 98cdb6
      GdkRectangle  rect = { x, y, width, height };
Packit 98cdb6
Packit 98cdb6
      gdk_directfb_clip_region (drawable, gc, &rect, &clip);
Packit 98cdb6
Packit 98cdb6
      if (gc_private && gc_private->values_mask & GDK_GC_FILL)
Packit 98cdb6
        {
Packit 98cdb6
          if (gc_private->values.fill == GDK_STIPPLED  &&
Packit 98cdb6
              gc_private->values_mask & GDK_GC_STIPPLE &&
Packit 98cdb6
              gc_private->values.stipple)
Packit 98cdb6
            {
Packit 98cdb6
              surface =
Packit 98cdb6
                GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (gc_private->values.stipple)->impl)->surface;
Packit 98cdb6
Packit 98cdb6
              if (surface)
Packit 98cdb6
                impl->surface->SetBlittingFlags (impl->surface,
Packit 98cdb6
                                                 (DSBLIT_BLEND_ALPHACHANNEL |
Packit 98cdb6
                                                  DSBLIT_COLORIZE));
Packit 98cdb6
            }
Packit 98cdb6
          else if (gc_private->values.fill == GDK_TILED  &&
Packit 98cdb6
                   gc_private->values_mask & GDK_GC_TILE &&
Packit 98cdb6
                   gc_private->values.tile)
Packit 98cdb6
            {
Packit 98cdb6
              surface = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (gc_private->values.tile)->impl)->surface;
Packit 98cdb6
Packit 98cdb6
              impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
Packit 98cdb6
            }
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      if (surface)
Packit 98cdb6
        {
Packit 98cdb6
          if (gc_private->values_mask & GDK_GC_TS_X_ORIGIN)
Packit 98cdb6
            x = gc_private->values.ts_x_origin;
Packit 98cdb6
          if (gc_private->values_mask & GDK_GC_TS_Y_ORIGIN)
Packit 98cdb6
            y = gc_private->values.ts_y_origin;
Packit 98cdb6
Packit 98cdb6
          for (i = 0; i < clip.numRects; i++)
Packit 98cdb6
            {
Packit 98cdb6
              DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
Packit 98cdb6
                                clip.rects[i].x2, clip.rects[i].y2 };
Packit 98cdb6
Packit 98cdb6
              impl->surface->SetClip (impl->surface, ®);
Packit 98cdb6
              impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
Packit 98cdb6
            }
Packit 98cdb6
        }
Packit 98cdb6
      else  /* normal rectangle filling */
Packit 98cdb6
        {
Packit 98cdb6
          DFBRectangle rects[clip.numRects];
Packit 98cdb6
Packit 98cdb6
          impl->surface->SetClip (impl->surface, NULL);
Packit 98cdb6
Packit 98cdb6
          for (i = 0; i < clip.numRects; i++)
Packit 98cdb6
            {
Packit 98cdb6
              GdkRegionBox *box = &clip.rects[i];
Packit 98cdb6
Packit 98cdb6
              rects[i].x = box->x1;
Packit 98cdb6
              rects[i].y = box->y1;
Packit 98cdb6
              rects[i].w = box->x2 - box->x1;
Packit 98cdb6
              rects[i].h = box->y2 - box->y1;
Packit 98cdb6
            }
Packit 98cdb6
Packit 98cdb6
          impl->surface->FillRectangles (impl->surface, rects, clip.numRects);
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      temp_region_deinit (&clip);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
Packit 98cdb6
      DFBRegion region = { x, y, x + width, y + height };
Packit 98cdb6
Packit 98cdb6
      impl->surface->SetClip (impl->surface, &region);
Packit 98cdb6
Packit 98cdb6
      /*  DirectFB does not draw rectangles the X way. Using DirectFB,
Packit 98cdb6
          a filled Rectangle has the same size as a drawn one, while
Packit 98cdb6
          X draws the rectangle one pixel taller and wider.  */
Packit 98cdb6
      impl->surface->DrawRectangle (impl->surface,
Packit 98cdb6
                                    x, y, width, height);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_arc (GdkDrawable *drawable,
Packit 98cdb6
                       GdkGC       *gc,
Packit 98cdb6
                       gint         filled,
Packit 98cdb6
                       gint         x,
Packit 98cdb6
                       gint         y,
Packit 98cdb6
                       gint         width,
Packit 98cdb6
                       gint         height,
Packit 98cdb6
                       gint         angle1,
Packit 98cdb6
                       gint         angle2)
Packit 98cdb6
{
Packit 98cdb6
  D_UNIMPLEMENTED ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_polygon (GdkDrawable *drawable,
Packit 98cdb6
                           GdkGC       *gc,
Packit 98cdb6
                           gint         filled,
Packit 98cdb6
                           GdkPoint    *points,
Packit 98cdb6
                           gint         npoints)
Packit 98cdb6
{
Packit 98cdb6
  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p, %p, %s, %p, %d )\n", G_STRFUNC,
Packit 98cdb6
              drawable, gc, filled ? " filled" : "outline", points, npoints);
Packit 98cdb6
Packit 98cdb6
  if (npoints < 3)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (filled)
Packit 98cdb6
    {
Packit 98cdb6
      if (npoints == 3 || (npoints == 4 &&
Packit 98cdb6
                           points[0].x == points[npoints - 1].x &&
Packit 98cdb6
                           points[0].y == points[npoints - 1].y))
Packit 98cdb6
        {
Packit 98cdb6
          GdkDrawableImplDirectFB *impl;
Packit 98cdb6
          GdkRegion                clip;
Packit 98cdb6
          gint                     i;
Packit 98cdb6
Packit 98cdb6
          impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
          if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
Packit 98cdb6
            return;
Packit 98cdb6
Packit 98cdb6
          gdk_directfb_clip_region (drawable, gc, NULL, &clip);
Packit 98cdb6
Packit 98cdb6
          for (i = 0; i < clip.numRects; i++)
Packit 98cdb6
            {
Packit 98cdb6
              DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
Packit 98cdb6
                                clip.rects[i].x2, clip.rects[i].y2 };
Packit 98cdb6
Packit 98cdb6
              impl->surface->SetClip (impl->surface, ®);
Packit 98cdb6
              impl->surface->FillTriangle (impl->surface,
Packit 98cdb6
                                           points[0].x, points[0].y,
Packit 98cdb6
                                           points[1].x, points[1].y,
Packit 98cdb6
                                           points[2].x, points[2].y);
Packit 98cdb6
Packit 98cdb6
            }
Packit 98cdb6
Packit 98cdb6
          temp_region_deinit (&clip);
Packit 98cdb6
Packit 98cdb6
          return;
Packit 98cdb6
        }
Packit 98cdb6
      else
Packit 98cdb6
        g_message ("filled polygons with n > 3 are not yet supported, "
Packit 98cdb6
                   "drawing outlines");
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (points[0].x != points[npoints - 1].x ||
Packit 98cdb6
      points[0].y != points[npoints - 1].y)
Packit 98cdb6
    {
Packit 98cdb6
      GdkPoint *tmp_points;
Packit 98cdb6
Packit 98cdb6
      tmp_points = g_new (GdkPoint, npoints + 1);
Packit 98cdb6
      memcpy (tmp_points, points, npoints * sizeof (GdkPoint));
Packit 98cdb6
      tmp_points[npoints].x = points[0].x;
Packit 98cdb6
      tmp_points[npoints].y = points[0].y;
Packit 98cdb6
Packit 98cdb6
      gdk_directfb_draw_lines (drawable, gc, tmp_points, npoints + 1);
Packit 98cdb6
Packit 98cdb6
      g_free (tmp_points);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      gdk_directfb_draw_lines (drawable, gc, points, npoints);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_text (GdkDrawable *drawable,
Packit 98cdb6
                        GdkFont     *font,
Packit 98cdb6
                        GdkGC       *gc,
Packit 98cdb6
                        gint         x,
Packit 98cdb6
                        gint         y,
Packit 98cdb6
                        const gchar *text,
Packit 98cdb6
                        gint         text_length)
Packit 98cdb6
{
Packit 98cdb6
  D_UNIMPLEMENTED ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_text_wc (GdkDrawable    *drawable,
Packit 98cdb6
                           GdkFont        *font,
Packit 98cdb6
                           GdkGC          *gc,
Packit 98cdb6
                           gint            x,
Packit 98cdb6
                           gint            y,
Packit 98cdb6
                           const GdkWChar *text,
Packit 98cdb6
                           gint            text_length)
Packit 98cdb6
{
Packit 98cdb6
  D_UNIMPLEMENTED ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_drawable (GdkDrawable *drawable,
Packit 98cdb6
                            GdkGC       *gc,
Packit 98cdb6
                            GdkDrawable *src,
Packit 98cdb6
                            gint         xsrc,
Packit 98cdb6
                            gint         ysrc,
Packit 98cdb6
                            gint         xdest,
Packit 98cdb6
                            gint         ydest,
Packit 98cdb6
                            gint         width,
Packit 98cdb6
                            gint         height,
Packit 98cdb6
                            GdkDrawable *original_src)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  GdkDrawableImplDirectFB *src_impl;
Packit 98cdb6
  GdkRegion                clip;
Packit 98cdb6
  GdkRectangle             dest_rect = { xdest,
Packit 98cdb6
                                         ydest,
Packit 98cdb6
                                         xdest + width ,
Packit 98cdb6
                                         ydest + height};
Packit 98cdb6
Packit 98cdb6
  DFBRectangle rect = { xsrc, ysrc, width, height };
Packit 98cdb6
  gint i;
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p, %p, %p, %4d,%4d -> %4d,%4d - %dx%d )\n", G_STRFUNC,
Packit 98cdb6
              drawable, gc, src, xsrc, ysrc, xdest, ydest, width, height);
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  if (!impl->surface)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (GDK_IS_PIXMAP (src))
Packit 98cdb6
    src_impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (src)->impl);
Packit 98cdb6
  else if (GDK_IS_WINDOW (src))
Packit 98cdb6
    src_impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (src)->impl);
Packit 98cdb6
  else if (GDK_IS_DRAWABLE_IMPL_DIRECTFB (src))
Packit 98cdb6
    src_impl = GDK_DRAWABLE_IMPL_DIRECTFB (src);
Packit 98cdb6
  else
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  gdk_directfb_clip_region (drawable, gc, &dest_rect, &clip);
Packit 98cdb6
Packit 98cdb6
  impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
Packit 98cdb6
Packit 98cdb6
  for (i = 0; i < clip.numRects; i++)
Packit 98cdb6
    {
Packit 98cdb6
      DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
Packit 98cdb6
                        clip.rects[i].x2, clip.rects[i].y2 };
Packit 98cdb6
Packit 98cdb6
      impl->surface->SetClip (impl->surface, ®);
Packit 98cdb6
      impl->surface->Blit (impl->surface,
Packit 98cdb6
                           src_impl->surface,
Packit 98cdb6
                           &rect,
Packit 98cdb6
                           xdest, ydest);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  temp_region_deinit (&clip);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_points (GdkDrawable *drawable,
Packit 98cdb6
                          GdkGC       *gc,
Packit 98cdb6
                          GdkPoint    *points,
Packit 98cdb6
                          gint         npoints)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  GdkRegion                clip;
Packit 98cdb6
Packit 98cdb6
  DFBRegion region = { points->x, points->y, points->x, points->y };
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p, %p, %p, %d )\n",
Packit 98cdb6
              G_STRFUNC, drawable, gc, points, npoints);
Packit 98cdb6
Packit 98cdb6
  if (npoints < 1)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  gdk_directfb_clip_region (drawable, gc, NULL, &clip);
Packit 98cdb6
Packit 98cdb6
  while (npoints > 0)
Packit 98cdb6
    {
Packit 98cdb6
      if (gdk_region_point_in (&clip, points->x, points->y))
Packit 98cdb6
        {
Packit 98cdb6
          impl->surface->FillRectangle (impl->surface,
Packit 98cdb6
                                        points->x, points->y, 1, 1);
Packit 98cdb6
Packit 98cdb6
          if (points->x < region.x1)
Packit 98cdb6
            region.x1 = points->x;
Packit 98cdb6
          if (points->x > region.x2)
Packit 98cdb6
            region.x2 = points->x;
Packit 98cdb6
Packit 98cdb6
          if (points->y < region.y1)
Packit 98cdb6
            region.y1 = points->y;
Packit 98cdb6
          if (points->y > region.y2)
Packit 98cdb6
            region.y2 = points->y;
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      npoints--;
Packit 98cdb6
      points++;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  temp_region_deinit (&clip);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_segments (GdkDrawable *drawable,
Packit 98cdb6
                            GdkGC       *gc,
Packit 98cdb6
                            GdkSegment  *segs,
Packit 98cdb6
                            gint         nsegs)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  GdkRegion                clip;
Packit 98cdb6
  gint                     i;
Packit 98cdb6
Packit 98cdb6
  //  DFBRegion region = { segs->x1, segs->y1, segs->x2, segs->y2 };
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p, %p, %p, %d )\n",
Packit 98cdb6
              G_STRFUNC, drawable, gc, segs, nsegs);
Packit 98cdb6
Packit 98cdb6
  if (nsegs < 1)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  gdk_directfb_clip_region (drawable, gc, NULL, &clip);
Packit 98cdb6
Packit 98cdb6
  for (i = 0; i < clip.numRects; i++)
Packit 98cdb6
    {
Packit 98cdb6
      DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
Packit 98cdb6
                        clip.rects[i].x2, clip.rects[i].y2 };
Packit 98cdb6
Packit 98cdb6
      impl->surface->SetClip (impl->surface, ®);
Packit 98cdb6
Packit 98cdb6
      impl->surface->DrawLines (impl->surface, (DFBRegion *)segs, nsegs);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  temp_region_deinit (&clip);
Packit 98cdb6
Packit 98cdb6
  /* everything below can be omitted if the drawing is buffered */
Packit 98cdb6
  /*  if (impl->buffered)
Packit 98cdb6
      return;
Packit 98cdb6
Packit 98cdb6
      if (region.x1 > region.x2)
Packit 98cdb6
      {
Packit 98cdb6
      region.x1 = segs->x2;
Packit 98cdb6
      region.x2 = segs->x1;
Packit 98cdb6
      }
Packit 98cdb6
      if (region.y1 > region.y2)
Packit 98cdb6
      {
Packit 98cdb6
      region.y1 = segs->y2;
Packit 98cdb6
      region.y2 = segs->y1;
Packit 98cdb6
      }
Packit 98cdb6
Packit 98cdb6
      while (nsegs > 1)
Packit 98cdb6
      {
Packit 98cdb6
      nsegs--;
Packit 98cdb6
      segs++;
Packit 98cdb6
Packit 98cdb6
      if (segs->x1 < region.x1)
Packit 98cdb6
      region.x1 = segs->x1;
Packit 98cdb6
      if (segs->x2 < region.x1)
Packit 98cdb6
      region.x1 = segs->x2;
Packit 98cdb6
Packit 98cdb6
      if (segs->y1 < region.y1)
Packit 98cdb6
      region.y1 = segs->y1;
Packit 98cdb6
      if (segs->y2 < region.y1)
Packit 98cdb6
      region.y1 = segs->y2;
Packit 98cdb6
Packit 98cdb6
      if (segs->x1 > region.x2)
Packit 98cdb6
      region.x2 = segs->x1;
Packit 98cdb6
      if (segs->x2 > region.x2)
Packit 98cdb6
      region.x2 = segs->x2;
Packit 98cdb6
Packit 98cdb6
      if (segs->y1 > region.y2)
Packit 98cdb6
      region.y2 = segs->y1;
Packit 98cdb6
      if (segs->y2 > region.y2)
Packit 98cdb6
      region.y2 = segs->y2;
Packit 98cdb6
      }*/
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_lines (GdkDrawable *drawable,
Packit 98cdb6
                         GdkGC       *gc,
Packit 98cdb6
                         GdkPoint    *points,
Packit 98cdb6
                         gint         npoints)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  GdkRegion                clip;
Packit 98cdb6
  gint                     i;
Packit 98cdb6
Packit 98cdb6
  DFBRegion lines[npoints > 1 ? npoints - 1 : 1];
Packit 98cdb6
Packit 98cdb6
  DFBRegion region = { points->x, points->y, points->x, points->y };
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p, %p, %p, %d )\n", G_STRFUNC,
Packit 98cdb6
              drawable, gc, points, npoints);
Packit 98cdb6
Packit 98cdb6
  if (npoints < 2)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  /* create an array of DFBRegions so we can use DrawLines */
Packit 98cdb6
Packit 98cdb6
  lines[0].x1 = points->x;
Packit 98cdb6
  lines[0].y1 = points->y;
Packit 98cdb6
Packit 98cdb6
  for (i = 0; i < npoints - 2; i++)
Packit 98cdb6
    {
Packit 98cdb6
      points++;
Packit 98cdb6
Packit 98cdb6
      lines[i].x2 = lines[i+1].x1 = points->x;
Packit 98cdb6
      lines[i].y2 = lines[i+1].y1 = points->y;
Packit 98cdb6
Packit 98cdb6
      if (points->x < region.x1)
Packit 98cdb6
        region.x1 = points->x;
Packit 98cdb6
Packit 98cdb6
      if (points->y < region.y1)
Packit 98cdb6
        region.y1 = points->y;
Packit 98cdb6
Packit 98cdb6
      if (points->x > region.x2)
Packit 98cdb6
        region.x2 = points->x;
Packit 98cdb6
Packit 98cdb6
      if (points->y > region.y2)
Packit 98cdb6
        region.y2 = points->y;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  points++;
Packit 98cdb6
  lines[i].x2 = points->x;
Packit 98cdb6
  lines[i].y2 = points->y;
Packit 98cdb6
Packit 98cdb6
  gdk_directfb_clip_region (drawable, gc, NULL, &clip);
Packit 98cdb6
Packit 98cdb6
  for (i = 0; i < clip.numRects; i++)
Packit 98cdb6
    {
Packit 98cdb6
      DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
Packit 98cdb6
                        clip.rects[i].x2, clip.rects[i].y2 };
Packit 98cdb6
Packit 98cdb6
      impl->surface->SetClip (impl->surface, ®);
Packit 98cdb6
      impl->surface->DrawLines (impl->surface, lines, npoints - 1);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  temp_region_deinit (&clip);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_image (GdkDrawable *drawable,
Packit 98cdb6
                         GdkGC       *gc,
Packit 98cdb6
                         GdkImage    *image,
Packit 98cdb6
                         gint         xsrc,
Packit 98cdb6
                         gint         ysrc,
Packit 98cdb6
                         gint         xdest,
Packit 98cdb6
                         gint         ydest,
Packit 98cdb6
                         gint         width,
Packit 98cdb6
                         gint         height)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  GdkImageDirectFB        *image_private;
Packit 98cdb6
  GdkRegion                clip;
Packit 98cdb6
  GdkRectangle             dest_rect = { xdest, ydest, width, height };
Packit 98cdb6
Packit 98cdb6
  gint pitch = 0;
Packit 98cdb6
  gint i;
Packit 98cdb6
Packit 98cdb6
  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
Packit 98cdb6
  g_return_if_fail (image != NULL);
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p, %p, %p, %4d,%4d -> %4d,%4d - %dx%d )\n",
Packit 98cdb6
              G_STRFUNC,
Packit 98cdb6
              drawable, gc, image, xsrc, ysrc, xdest, ydest, width, height);
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
  image_private = image->windowing_data;
Packit 98cdb6
Packit 98cdb6
  if (!impl->surface)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  gdk_directfb_clip_region (drawable, gc, &dest_rect, &clip);
Packit 98cdb6
Packit 98cdb6
  if (!gdk_region_empty (&clip))
Packit 98cdb6
    {
Packit 98cdb6
      DFBRectangle  src_rect = { xsrc, ysrc, width, height };
Packit 98cdb6
Packit 98cdb6
      image_private->surface->Unlock (image_private->surface);
Packit 98cdb6
Packit 98cdb6
      impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
Packit 98cdb6
Packit 98cdb6
      for (i = 0; i < clip.numRects; i++)
Packit 98cdb6
        {
Packit 98cdb6
          DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
Packit 98cdb6
                            clip.rects[i].x2, clip.rects[i].y2 };
Packit 98cdb6
Packit 98cdb6
          impl->surface->SetClip (impl->surface, ®);
Packit 98cdb6
          impl->surface->Blit (impl->surface,
Packit 98cdb6
                               image_private->surface, &src_rect,
Packit 98cdb6
                               xdest, ydest);
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      image_private->surface->Lock (image_private->surface, DSLF_WRITE,
Packit 98cdb6
                                    &image->mem, &pitch);
Packit 98cdb6
      image->bpl = pitch;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  temp_region_deinit (&clip);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
composite (guchar *src_buf,
Packit 98cdb6
           gint    src_rowstride,
Packit 98cdb6
           guchar *dest_buf,
Packit 98cdb6
           gint    dest_rowstride,
Packit 98cdb6
           gint    width,
Packit 98cdb6
           gint    height)
Packit 98cdb6
{
Packit 98cdb6
  guchar *src = src_buf;
Packit 98cdb6
  guchar *dest = dest_buf;
Packit 98cdb6
Packit 98cdb6
  while (height--)
Packit 98cdb6
    {
Packit 98cdb6
      gint twidth = width;
Packit 98cdb6
      guchar *p = src;
Packit 98cdb6
      guchar *q = dest;
Packit 98cdb6
Packit 98cdb6
      while (twidth--)
Packit 98cdb6
        {
Packit 98cdb6
          guchar a = p[3];
Packit 98cdb6
          guint t;
Packit 98cdb6
Packit 98cdb6
          t = a * p[0] + (255 - a) * q[0] + 0x80;
Packit 98cdb6
          q[0] = (t + (t >> 8)) >> 8;
Packit 98cdb6
          t = a * p[1] + (255 - a) * q[1] + 0x80;
Packit 98cdb6
          q[1] = (t + (t >> 8)) >> 8;
Packit 98cdb6
          t = a * p[2] + (255 - a) * q[2] + 0x80;
Packit 98cdb6
          q[2] = (t + (t >> 8)) >> 8;
Packit 98cdb6
Packit 98cdb6
          p += 4;
Packit 98cdb6
          q += 3;
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      src += src_rowstride;
Packit 98cdb6
      dest += dest_rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
composite_0888 (guchar      *src_buf,
Packit 98cdb6
                gint         src_rowstride,
Packit 98cdb6
                guchar      *dest_buf,
Packit 98cdb6
                gint         dest_rowstride,
Packit 98cdb6
                GdkByteOrder dest_byte_order,
Packit 98cdb6
                gint         width,
Packit 98cdb6
                gint         height)
Packit 98cdb6
{
Packit 98cdb6
  guchar *src = src_buf;
Packit 98cdb6
  guchar *dest = dest_buf;
Packit 98cdb6
Packit 98cdb6
  while (height--)
Packit 98cdb6
    {
Packit 98cdb6
      gint twidth = width;
Packit 98cdb6
      guchar *p = src;
Packit 98cdb6
      guchar *q = dest;
Packit 98cdb6
Packit 98cdb6
      if (dest_byte_order == GDK_LSB_FIRST)
Packit 98cdb6
        {
Packit 98cdb6
          while (twidth--)
Packit 98cdb6
            {
Packit 98cdb6
              guint t;
Packit 98cdb6
Packit 98cdb6
              t = p[3] * p[2] + (255 - p[3]) * q[0] + 0x80;
Packit 98cdb6
              q[0] = (t + (t >> 8)) >> 8;
Packit 98cdb6
              t = p[3] * p[1] + (255 - p[3]) * q[1] + 0x80;
Packit 98cdb6
              q[1] = (t + (t >> 8)) >> 8;
Packit 98cdb6
              t = p[3] * p[0] + (255 - p[3]) * q[2] + 0x80;
Packit 98cdb6
              q[2] = (t + (t >> 8)) >> 8;
Packit 98cdb6
              p += 4;
Packit 98cdb6
              q += 4;
Packit 98cdb6
            }
Packit 98cdb6
        }
Packit 98cdb6
      else
Packit 98cdb6
        {
Packit 98cdb6
          while (twidth--)
Packit 98cdb6
            {
Packit 98cdb6
              guint t;
Packit 98cdb6
Packit 98cdb6
              t = p[3] * p[0] + (255 - p[3]) * q[1] + 0x80;
Packit 98cdb6
              q[1] = (t + (t >> 8)) >> 8;
Packit 98cdb6
              t = p[3] * p[1] + (255 - p[3]) * q[2] + 0x80;
Packit 98cdb6
              q[2] = (t + (t >> 8)) >> 8;
Packit 98cdb6
              t = p[3] * p[2] + (255 - p[3]) * q[3] + 0x80;
Packit 98cdb6
              q[3] = (t + (t >> 8)) >> 8;
Packit 98cdb6
              p += 4;
Packit 98cdb6
              q += 4;
Packit 98cdb6
            }
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      src += src_rowstride;
Packit 98cdb6
      dest += dest_rowstride;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* change the last value to adjust the size of the device (1-4) */
Packit 98cdb6
#define SET_PIXEL_DUFFS_DEVICE(D, S, w)         \
Packit 98cdb6
  SET_PIXEL_DUFFS_DEVICE_N (D, S, w, 2)
Packit 98cdb6
Packit 98cdb6
/* From DirectFB's gfx/generic/generic.c" */
Packit 98cdb6
#define SET_PIXEL(D, S)                                                 \
Packit 98cdb6
        switch (S >> 26) {                                              \
Packit 98cdb6
  case 0:                                                               \
Packit 98cdb6
    break;                                                              \
Packit 98cdb6
  case 0x3f:                                                            \
Packit 98cdb6
    D = ((S <<  8) & 0xF800) |                                          \
Packit 98cdb6
      ((S >>  5) & 0x07E0) |                                            \
Packit 98cdb6
      ((S >> 19) & 0x001F);                                             \
Packit 98cdb6
    break;                                                              \
Packit 98cdb6
  default:                                                              \
Packit 98cdb6
    D = (((( (((S<<8) & 0xf800) | ((S>>19) & 0x001f))                   \
Packit 98cdb6
             - (D & 0xf81f)) * ((S>>26)+1) + ((D & 0xf81f)<<6)) & 0x003e07c0) \
Packit 98cdb6
         +                                                              \
Packit 98cdb6
         ((( ((S>>5) & 0x07e0)                                          \
Packit 98cdb6
             - (D & 0x07e0)) * ((S>>26)+1) + ((D & 0x07e0)<<6)) & 0x0001f800)) >> 6; \
Packit 98cdb6
  }
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
composite_565 (guchar      *src_buf,
Packit 98cdb6
               gint         src_rowstride,
Packit 98cdb6
               guchar      *dest_buf,
Packit 98cdb6
               gint         dest_rowstride,
Packit 98cdb6
               GdkByteOrder dest_byte_order,
Packit 98cdb6
               gint         width,
Packit 98cdb6
               gint         height)
Packit 98cdb6
{
Packit 98cdb6
  while (height--) {
Packit 98cdb6
    int  w = width;
Packit 98cdb6
    u16 *D = (u16*) dest_buf;
Packit 98cdb6
    u32 *S = (u32*) src_buf;
Packit 98cdb6
#if 1
Packit 98cdb6
    if ((unsigned long)D & 2) {
Packit 98cdb6
      SET_PIXEL (D[0], S[0]);
Packit 98cdb6
      w--;
Packit 98cdb6
      D++;
Packit 98cdb6
      S++;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
    int  i;
Packit 98cdb6
    int  w2  = w / 2;
Packit 98cdb6
    u32 *D32 = (u32*) D;
Packit 98cdb6
Packit 98cdb6
    for (i=0; i
Packit 98cdb6
      register u32 S0 = S[(i << 1) + 0];
Packit 98cdb6
      register u32 S1 = S[(i << 1) + 1];
Packit 98cdb6
Packit 98cdb6
      if ((S0 >> 26) == 0x3f && (S1 >> 26) == 0x3f) {
Packit 98cdb6
        D32[i] = ((S0 <<  8) & 0x0000F800) |
Packit 98cdb6
          ((S0 >>  5) & 0x000007E0) |
Packit 98cdb6
          ((S0 >> 19) & 0x0000001F) |
Packit 98cdb6
          ((S1 << 24) & 0xF8000000) |
Packit 98cdb6
          ((S1 << 11) & 0x07E00000) |
Packit 98cdb6
          ((S1 >>  3) & 0x001F0000);
Packit 98cdb6
      }
Packit 98cdb6
      else {
Packit 98cdb6
        SET_PIXEL (D[(i << 1) + 0], S0);
Packit 98cdb6
        SET_PIXEL (D[(i << 1) + 1], S1);
Packit 98cdb6
      }
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
    if (w & 1)
Packit 98cdb6
      SET_PIXEL (D[w - 1], S[w - 1]);
Packit 98cdb6
#else
Packit 98cdb6
    SET_PIXEL_DUFFS_DEVICE (D, S, w);
Packit 98cdb6
#endif
Packit 98cdb6
Packit 98cdb6
    dest_buf += dest_rowstride;
Packit 98cdb6
    src_buf += src_rowstride;
Packit 98cdb6
  }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#undef SET_PIXEL
Packit 98cdb6
#undef SET_PIXEL_DUFFS_DEVICE
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_draw_pixbuf (GdkDrawable  *drawable,
Packit 98cdb6
                          GdkGC        *gc,
Packit 98cdb6
                          GdkPixbuf    *pixbuf,
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
                          GdkRgbDither  dither,
Packit 98cdb6
                          gint          x_dither,
Packit 98cdb6
                          gint          y_dither)
Packit 98cdb6
{
Packit 98cdb6
  GdkPixbuf *composited = NULL;
Packit 98cdb6
  guchar *pb_pixels = NULL;
Packit 98cdb6
  gint pb_n_channels, pb_bits_per_sample, pb_rowstride;
Packit 98cdb6
  gint pb_width, pb_height;
Packit 98cdb6
#if 0
Packit 98cdb6
  GdkRegion *clip;
Packit 98cdb6
  GdkRegion *drect;
Packit 98cdb6
  GdkRectangle tmp_rect;
Packit 98cdb6
#endif
Packit 98cdb6
  GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
Packit 98cdb6
  g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
Packit 98cdb6
  
Packit 98cdb6
  pb_n_channels = gdk_pixbuf_get_n_channels (pixbuf);
Packit 98cdb6
  pb_bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
Packit 98cdb6
  g_return_if_fail (pb_n_channels == 3 || pb_n_channels == 4);
Packit 98cdb6
  g_return_if_fail (pb_bits_per_sample == 8);
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (drawable != NULL);
Packit 98cdb6
Packit 98cdb6
  pb_width = gdk_pixbuf_get_width (pixbuf);
Packit 98cdb6
  pb_height = gdk_pixbuf_get_height (pixbuf);
Packit 98cdb6
  pb_pixels = gdk_pixbuf_get_pixels (pixbuf);
Packit 98cdb6
  pb_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
Packit 98cdb6
Packit 98cdb6
  if (width == -1) 
Packit 98cdb6
    width = pb_width;
Packit 98cdb6
  if (height == -1)
Packit 98cdb6
    height = pb_height;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (width >= 0 && height >= 0);
Packit 98cdb6
  g_return_if_fail (src_x >= 0 && src_x + width <= pb_width);
Packit 98cdb6
  g_return_if_fail (src_y >= 0 && src_y + height <= pb_height);
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p, %p, %p, %4d,%4d -> %4d,%4d - %dx%d )\n",
Packit 98cdb6
              G_STRFUNC,
Packit 98cdb6
              drawable, gc, pixbuf, src_x, src_y, dest_x, dest_y, width, height);
Packit 98cdb6
Packit 98cdb6
  /* Clip to the drawable; this is required for get_from_drawable() so
Packit 98cdb6
   * can't be done implicitly
Packit 98cdb6
   */
Packit 98cdb6
Packit 98cdb6
  if (dest_x < 0)
Packit 98cdb6
    {
Packit 98cdb6
      src_x -= dest_x;
Packit 98cdb6
      width += dest_x;
Packit 98cdb6
      dest_x = 0;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (dest_y < 0)
Packit 98cdb6
    {
Packit 98cdb6
      src_y -= dest_y;
Packit 98cdb6
      height += dest_y;
Packit 98cdb6
      dest_y = 0;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if ((dest_x + width) > impl->width)
Packit 98cdb6
    width = impl->width - dest_x;
Packit 98cdb6
Packit 98cdb6
  if ((dest_y + height) > impl->height)
Packit 98cdb6
    height = impl->height - dest_y;
Packit 98cdb6
Packit 98cdb6
  if (width <= 0 || height <= 0)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
#if 0
Packit 98cdb6
  /* Clip to the clip region; this avoids getting more
Packit 98cdb6
   * image data from the server than we need to.
Packit 98cdb6
   */
Packit 98cdb6
Packit 98cdb6
  tmp_rect.x = dest_x;
Packit 98cdb6
  tmp_rect.y = dest_y;
Packit 98cdb6
  tmp_rect.width = width;
Packit 98cdb6
  tmp_rect.height = height;
Packit 98cdb6
Packit 98cdb6
  drect = gdk_region_rectangle (&tmp_rect);
Packit 98cdb6
  clip = gdk_drawable_get_clip_region (drawable);
Packit 98cdb6
Packit 98cdb6
  gdk_region_intersect (drect, clip);
Packit 98cdb6
Packit 98cdb6
  gdk_region_get_clipbox (drect, &tmp_rect);
Packit 98cdb6
Packit 98cdb6
  gdk_region_destroy (drect);
Packit 98cdb6
  gdk_region_destroy (clip);
Packit 98cdb6
Packit 98cdb6
  if (tmp_rect.width == 0 ||
Packit 98cdb6
      tmp_rect.height == 0)
Packit 98cdb6
    return;
Packit 98cdb6
#endif
Packit 98cdb6
Packit 98cdb6
  if (gdk_pixbuf_get_has_alpha (pixbuf) && impl->format == DSPF_RGB16) {
Packit 98cdb6
    void *data;
Packit 98cdb6
    int   pitch;
Packit 98cdb6
Packit 98cdb6
    if (impl->surface->Lock (impl->surface, DSLF_READ | DSLF_WRITE, &data, &pitch) == DFB_OK) {
Packit 98cdb6
      composite_565 (pb_pixels + src_y * pb_rowstride + src_x * 4,
Packit 98cdb6
                     pb_rowstride,
Packit 98cdb6
                     data + dest_y * pitch + dest_x * 2,
Packit 98cdb6
                     pitch,
Packit 98cdb6
#if G_BYTE_ORDER == G_BIG_ENDIAN
Packit 98cdb6
                     GDK_MSB_FIRST,
Packit 98cdb6
#else
Packit 98cdb6
                     GDK_LSB_FIRST,
Packit 98cdb6
#endif
Packit 98cdb6
                     width, height);
Packit 98cdb6
Packit 98cdb6
      impl->surface->Unlock (impl->surface);
Packit 98cdb6
Packit 98cdb6
      return;
Packit 98cdb6
    }
Packit 98cdb6
  }
Packit 98cdb6
Packit 98cdb6
  /* Actually draw */
Packit 98cdb6
  if (!gc)
Packit 98cdb6
    gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
Packit 98cdb6
Packit 98cdb6
  if (gdk_pixbuf_get_has_alpha (pixbuf))
Packit 98cdb6
    {
Packit 98cdb6
      GdkVisual *visual = gdk_drawable_get_visual (drawable);
Packit 98cdb6
      void (*composite_func) (guchar       *src_buf,
Packit 98cdb6
                              gint          src_rowstride,
Packit 98cdb6
                              guchar       *dest_buf,
Packit 98cdb6
                              gint          dest_rowstride,
Packit 98cdb6
                              GdkByteOrder  dest_byte_order,
Packit 98cdb6
                              gint          width,
Packit 98cdb6
                              gint          height) = NULL;
Packit 98cdb6
Packit 98cdb6
      /* First we see if we have a visual-specific composition function that can composite
Packit 98cdb6
       * the pixbuf data directly onto the image
Packit 98cdb6
       */
Packit 98cdb6
      if (visual)
Packit 98cdb6
        {
Packit 98cdb6
          gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (gdk_drawable_get_display (drawable),
Packit 98cdb6
                                                                   visual->depth);
Packit 98cdb6
Packit 98cdb6
          if (visual->byte_order == (G_BYTE_ORDER == G_BIG_ENDIAN ? GDK_MSB_FIRST : GDK_LSB_FIRST) &&
Packit 98cdb6
              visual->depth == 16 &&
Packit 98cdb6
              visual->red_mask   == 0xf800 &&
Packit 98cdb6
              visual->green_mask == 0x07e0 &&
Packit 98cdb6
              visual->blue_mask  == 0x001f)
Packit 98cdb6
            composite_func = composite_565;
Packit 98cdb6
          else if (visual->depth == 24 && bits_per_pixel == 32 &&
Packit 98cdb6
                   visual->red_mask   == 0xff0000 &&
Packit 98cdb6
                   visual->green_mask == 0x00ff00 &&
Packit 98cdb6
                   visual->blue_mask  == 0x0000ff)
Packit 98cdb6
            composite_func = composite_0888;
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      /* We can't use our composite func if we are required to dither
Packit 98cdb6
       */
Packit 98cdb6
      if (composite_func && !(dither == GDK_RGB_DITHER_MAX && visual->depth != 24))
Packit 98cdb6
        {
Packit 98cdb6
#if 0
Packit 98cdb6
          gint x0, y0;
Packit 98cdb6
          for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
Packit 98cdb6
            {
Packit 98cdb6
              gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
Packit 98cdb6
              for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
Packit 98cdb6
                {
Packit 98cdb6
                  gint xs0, ys0;
Packit 98cdb6
Packit 98cdb6
                  gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
Packit 98cdb6
Packit 98cdb6
                  GdkImage *image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable),
Packit 98cdb6
                                                            width1, height1,
Packit 98cdb6
                                                            gdk_drawable_get_depth (drawable), &xs0, &ys0;;
Packit 98cdb6
Packit 98cdb6
                  gdk_drawable_copy_to_image (drawable, image,
Packit 98cdb6
                                              dest_x + x0, dest_y + y0,
Packit 98cdb6
                                              xs0, ys0,
Packit 98cdb6
                                              width1, height1);
Packit 98cdb6
                  (*composite_func) (pb_pixels + (src_y + y0) * pb_rowstride + (src_x + x0) * 4,
Packit 98cdb6
                                     pb_rowstride,
Packit 98cdb6
                                     (guchar*)image->mem + ys0 * image->bpl + xs0 * image->bpp,
Packit 98cdb6
                                     image->bpl,
Packit 98cdb6
                                     visual->byte_order,
Packit 98cdb6
                                     width1, height1);
Packit 98cdb6
                  gdk_draw_image (drawable, gc, image,
Packit 98cdb6
                                  xs0, ys0,
Packit 98cdb6
                                  dest_x + x0, dest_y + y0,
Packit 98cdb6
                                  width1, height1);
Packit 98cdb6
                }
Packit 98cdb6
            }
Packit 98cdb6
#else
Packit 98cdb6
          void *data;
Packit 98cdb6
          int   pitch;
Packit 98cdb6
Packit 98cdb6
          if (impl->surface->Lock (impl->surface,
Packit 98cdb6
                                   DSLF_READ | DSLF_WRITE,
Packit 98cdb6
                                   &data, &pitch) == DFB_OK) {
Packit 98cdb6
            (*composite_func) (pb_pixels + src_y * pb_rowstride + src_x * 4,
Packit 98cdb6
                               pb_rowstride,
Packit 98cdb6
                               data + dest_y * pitch + DFB_BYTES_PER_LINE (impl->format, dest_x),
Packit 98cdb6
                               pitch,
Packit 98cdb6
                               visual->byte_order,
Packit 98cdb6
                               width, height);
Packit 98cdb6
Packit 98cdb6
            impl->surface->Unlock (impl->surface);
Packit 98cdb6
          }
Packit 98cdb6
#endif
Packit 98cdb6
          goto out;
Packit 98cdb6
        }
Packit 98cdb6
      else
Packit 98cdb6
        {
Packit 98cdb6
          /* No special composition func, convert dest to 24 bit RGB data, composite against
Packit 98cdb6
           * that, and convert back.
Packit 98cdb6
           */
Packit 98cdb6
          composited = gdk_pixbuf_get_from_drawable (NULL,
Packit 98cdb6
                                                     drawable,
Packit 98cdb6
                                                     NULL,
Packit 98cdb6
                                                     dest_x, dest_y,
Packit 98cdb6
                                                     0, 0,
Packit 98cdb6
                                                     width, height);
Packit 98cdb6
Packit 98cdb6
          if (composited)
Packit 98cdb6
            composite (pb_pixels + src_y * pb_rowstride + src_x * 4,
Packit 98cdb6
                       pb_rowstride,
Packit 98cdb6
                       gdk_pixbuf_get_pixels (composited),
Packit 98cdb6
                       gdk_pixbuf_get_rowstride (composited),
Packit 98cdb6
                       width, height);
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (composited)
Packit 98cdb6
    {
Packit 98cdb6
      src_x = 0;
Packit 98cdb6
      src_y = 0;
Packit 98cdb6
      pixbuf = composited;
Packit 98cdb6
      pb_pixels = gdk_pixbuf_get_pixels (pixbuf);
Packit 98cdb6
      pb_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  if (pb_n_channels == 4)
Packit 98cdb6
    {
Packit 98cdb6
      guchar *buf = pb_pixels + src_y * pb_rowstride + src_x * 4;
Packit 98cdb6
Packit 98cdb6
      gdk_draw_rgb_32_image_dithalign (drawable, gc,
Packit 98cdb6
                                       dest_x, dest_y,
Packit 98cdb6
                                       width, height,
Packit 98cdb6
                                       dither,
Packit 98cdb6
                                       buf, pb_rowstride,
Packit 98cdb6
                                       x_dither, y_dither);
Packit 98cdb6
    }
Packit 98cdb6
  else                                /* n_channels == 3 */
Packit 98cdb6
    {
Packit 98cdb6
      guchar *buf = pb_pixels + src_y * pb_rowstride + src_x * 3;
Packit 98cdb6
Packit 98cdb6
      gdk_draw_rgb_image_dithalign (drawable, gc,
Packit 98cdb6
                                    dest_x, dest_y,
Packit 98cdb6
                                    width, height,
Packit 98cdb6
                                    dither,
Packit 98cdb6
                                    buf, pb_rowstride,
Packit 98cdb6
                                    x_dither, y_dither);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
 out:
Packit 98cdb6
  if (composited)
Packit 98cdb6
    g_object_unref (composited);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static inline void
Packit 98cdb6
convert_rgba_pixbuf_to_image (guint32 *src,
Packit 98cdb6
                              guint    src_pitch,
Packit 98cdb6
                              guint32 *dest,
Packit 98cdb6
                              guint    dest_pitch,
Packit 98cdb6
                              guint    width,
Packit 98cdb6
                              guint    height)
Packit 98cdb6
{
Packit 98cdb6
  guint i;
Packit 98cdb6
Packit 98cdb6
  while (height--)
Packit 98cdb6
    {
Packit 98cdb6
      for (i = 0; i < width; i++)
Packit 98cdb6
        {
Packit 98cdb6
          guint32 pixel = GUINT32_FROM_BE (src[i]);
Packit 98cdb6
          dest[i] = (pixel >> 8) | (pixel << 24);
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      src  += src_pitch;
Packit 98cdb6
      dest += dest_pitch;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static inline void
Packit 98cdb6
convert_rgb_pixbuf_to_image (guchar  *src,
Packit 98cdb6
                             guint    src_pitch,
Packit 98cdb6
                             guint32 *dest,
Packit 98cdb6
                             guint    dest_pitch,
Packit 98cdb6
                             guint    width,
Packit 98cdb6
                             guint    height)
Packit 98cdb6
{
Packit 98cdb6
  guint   i;
Packit 98cdb6
  guchar *s;
Packit 98cdb6
Packit 98cdb6
  while (height--)
Packit 98cdb6
    {
Packit 98cdb6
      s = src;
Packit 98cdb6
Packit 98cdb6
      for (i = 0; i < width; i++, s += 3)
Packit 98cdb6
        dest[i] = 0xFF000000 | (s[0] << 16) | (s[1] << 8) | s[2];
Packit 98cdb6
Packit 98cdb6
      src  += src_pitch;
Packit 98cdb6
      dest += dest_pitch;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * Object stuff
Packit 98cdb6
 */
Packit 98cdb6
static inline const char *
Packit 98cdb6
drawable_impl_type_name (GObject *object)
Packit 98cdb6
{
Packit 98cdb6
  if (GDK_IS_PIXMAP (object))
Packit 98cdb6
    return "PIXMAP";
Packit 98cdb6
Packit 98cdb6
  if (GDK_IS_WINDOW (object))
Packit 98cdb6
    return "WINDOW";
Packit 98cdb6
Packit 98cdb6
  if (GDK_IS_DRAWABLE_IMPL_DIRECTFB (object))
Packit 98cdb6
    return "DRAWABLE";
Packit 98cdb6
Packit 98cdb6
  return "unknown";
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_drawable_impl_directfb_finalize (GObject *object)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (object);
Packit 98cdb6
Packit 98cdb6
  D_DEBUG_AT (GDKDFB_Drawable, "%s( %p ) <- %dx%d (%s at %4d,%4d)\n",
Packit 98cdb6
              G_STRFUNC,
Packit 98cdb6
              object, impl->width, impl->height,
Packit 98cdb6
              drawable_impl_type_name (object),
Packit 98cdb6
              impl->abs_x, impl->abs_y);
Packit 98cdb6
Packit 98cdb6
  gdk_directfb_set_colormap (GDK_DRAWABLE (object), NULL);
Packit 98cdb6
  if (impl->cairo_surface) {
Packit 98cdb6
    cairo_surface_finish (impl->cairo_surface);
Packit 98cdb6
  }
Packit 98cdb6
  if (impl->surface)
Packit 98cdb6
    impl->surface->Release (impl->surface);
Packit 98cdb6
Packit 98cdb6
  G_OBJECT_CLASS (parent_class)->finalize (object);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_drawable_impl_directfb_class_init (GdkDrawableImplDirectFBClass *klass)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
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_drawable_impl_directfb_finalize;
Packit 98cdb6
Packit 98cdb6
  drawable_class->create_gc              = _gdk_directfb_gc_new;
Packit 98cdb6
  drawable_class->draw_rectangle         = gdk_directfb_draw_rectangle;
Packit 98cdb6
  drawable_class->draw_arc               = gdk_directfb_draw_arc;
Packit 98cdb6
  drawable_class->draw_polygon           = gdk_directfb_draw_polygon;
Packit 98cdb6
  drawable_class->draw_text              = gdk_directfb_draw_text;
Packit 98cdb6
  drawable_class->draw_text_wc           = gdk_directfb_draw_text_wc;
Packit 98cdb6
  drawable_class->draw_drawable_with_src = gdk_directfb_draw_drawable;
Packit 98cdb6
  drawable_class->draw_points            = gdk_directfb_draw_points;
Packit 98cdb6
  drawable_class->draw_segments          = gdk_directfb_draw_segments;
Packit 98cdb6
  drawable_class->draw_lines             = gdk_directfb_draw_lines;
Packit 98cdb6
#if 0
Packit 98cdb6
  drawable_class->draw_glyphs             = NULL;
Packit 98cdb6
  drawable_class->draw_glyphs_transformed = NULL;
Packit 98cdb6
#endif
Packit 98cdb6
  drawable_class->draw_image     = gdk_directfb_draw_image;
Packit 98cdb6
Packit 98cdb6
  drawable_class->ref_cairo_surface = gdk_directfb_ref_cairo_surface;
Packit 98cdb6
  drawable_class->set_colormap      = gdk_directfb_set_colormap;
Packit 98cdb6
  drawable_class->get_colormap      = gdk_directfb_get_colormap;
Packit 98cdb6
Packit 98cdb6
  drawable_class->get_depth  = gdk_directfb_get_depth;
Packit 98cdb6
  drawable_class->get_visual = gdk_directfb_get_visual;
Packit 98cdb6
Packit 98cdb6
  drawable_class->get_size = gdk_directfb_get_size;
Packit 98cdb6
Packit 98cdb6
  drawable_class->_copy_to_image = _gdk_directfb_copy_to_image;
Packit 98cdb6
  drawable_class->get_screen     = gdk_directfb_get_screen;
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
  real_draw_pixbuf            = drawable_class->draw_pixbuf;
Packit 98cdb6
  drawable_class->draw_pixbuf = gdk_directfb_draw_pixbuf;
Packit 98cdb6
Packit 98cdb6
  /* check for hardware-accelerated alpha-blending */
Packit 98cdb6
  {
Packit 98cdb6
    DFBGraphicsDeviceDescription desc;
Packit 98cdb6
    _gdk_display->directfb->GetDeviceDescription (_gdk_display->directfb, &desc);
Packit 98cdb6
Packit 98cdb6
    accelerated_alpha_blending =
Packit 98cdb6
      ((desc.acceleration_mask & DFXL_BLIT) &&
Packit 98cdb6
       (desc.blitting_flags & DSBLIT_BLEND_ALPHACHANNEL));
Packit 98cdb6
  }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GType
Packit 98cdb6
gdk_drawable_impl_directfb_get_type (void)
Packit 98cdb6
{
Packit 98cdb6
  static GType object_type = 0;
Packit 98cdb6
Packit 98cdb6
  if (!object_type)
Packit 98cdb6
    {
Packit 98cdb6
      const GTypeInfo object_info =
Packit 98cdb6
        {
Packit 98cdb6
          sizeof (GdkDrawableImplDirectFBClass),
Packit 98cdb6
          (GBaseInitFunc) NULL,
Packit 98cdb6
          (GBaseFinalizeFunc) NULL,
Packit 98cdb6
          (GClassInitFunc) gdk_drawable_impl_directfb_class_init,
Packit 98cdb6
          NULL,           /* class_finalize */
Packit 98cdb6
          NULL,           /* class_data */
Packit 98cdb6
          sizeof (GdkDrawableImplDirectFB),
Packit 98cdb6
          0,              /* n_preallocs */
Packit 98cdb6
          (GInstanceInitFunc) NULL,
Packit 98cdb6
        };
Packit 98cdb6
Packit 98cdb6
      object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
Packit 98cdb6
                                            "GdkDrawableImplDirectFB",
Packit 98cdb6
                                            &object_info, 0);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return object_type;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GdkScreen *
Packit 98cdb6
gdk_directfb_get_screen (GdkDrawable *drawable)
Packit 98cdb6
{
Packit 98cdb6
  return gdk_screen_get_default ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_directfb_cairo_surface_destroy (void *data)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl = data;
Packit 98cdb6
  impl->cairo_surface = NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface,
Packit 98cdb6
                                       int width,
Packit 98cdb6
                                       int height)
Packit 98cdb6
{
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
cairo_surface_t *
Packit 98cdb6
_gdk_windowing_create_cairo_surface (GdkDrawable *drawable,
Packit 98cdb6
                                     int width,
Packit 98cdb6
                                     int height)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  IDirectFB *dfb;
Packit 98cdb6
  cairo_surface_t *ret;
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
  dfb = GDK_DISPLAY_DFB (gdk_drawable_get_display (drawable))->directfb;
Packit 98cdb6
Packit 98cdb6
  ret = cairo_directfb_surface_create (dfb, impl->surface);
Packit 98cdb6
  cairo_surface_set_user_data (ret,
Packit 98cdb6
                               &gdk_directfb_cairo_key, drawable,
Packit 98cdb6
                               gdk_directfb_cairo_surface_destroy);
Packit 98cdb6
Packit 98cdb6
  return ret;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static cairo_surface_t *
Packit 98cdb6
gdk_directfb_ref_cairo_surface (GdkDrawable *drawable)
Packit 98cdb6
{
Packit 98cdb6
  GdkDrawableImplDirectFB *impl;
Packit 98cdb6
  IDirectFB               *dfb;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable), NULL);
Packit 98cdb6
Packit 98cdb6
  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
Packit 98cdb6
  dfb = GDK_DISPLAY_DFB (gdk_drawable_get_display (drawable))->directfb;
Packit 98cdb6
Packit 98cdb6
  if (!impl->cairo_surface) {
Packit 98cdb6
    IDirectFBSurface *surface;
Packit 98cdb6
    g_assert (impl->surface != NULL);
Packit 98cdb6
    impl->surface->GetSubSurface (impl->surface, NULL, &surface);
Packit 98cdb6
    if (surface) {
Packit 98cdb6
      impl->cairo_surface = cairo_directfb_surface_create (dfb, surface);
Packit 98cdb6
      if (impl->cairo_surface) {
Packit 98cdb6
        cairo_surface_set_user_data (impl->cairo_surface,
Packit 98cdb6
                                     &gdk_directfb_cairo_key, drawable,
Packit 98cdb6
                                     gdk_directfb_cairo_surface_destroy);
Packit 98cdb6
      }
Packit 98cdb6
      surface->Release (surface);
Packit 98cdb6
    }
Packit 98cdb6
  } else {
Packit 98cdb6
    cairo_surface_reference (impl->cairo_surface);
Packit 98cdb6
  }
Packit 98cdb6
Packit 98cdb6
  g_assert (impl->cairo_surface != NULL);
Packit 98cdb6
  return impl->cairo_surface;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#define __GDK_DRAWABLE_X11_C__
Packit 98cdb6
#include "gdkaliasdef.c"