Blame gdk/quartz/gdkpixmap-quartz.c

Packit 98cdb6
/* gdkpixmap-quartz.c
Packit 98cdb6
 *
Packit 98cdb6
 * Copyright (C) 2005 Imendio AB
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
#include "config.h"
Packit 98cdb6
Packit 98cdb6
#include "gdkpixmap.h"
Packit 98cdb6
#include "gdkprivate-quartz.h"
Packit 98cdb6
Packit 98cdb6
static gpointer parent_class;
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pixmap_impl_quartz_init (GdkPixmapImplQuartz *impl)
Packit 98cdb6
{
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pixmap_impl_quartz_get_size (GdkDrawable *drawable,
Packit 98cdb6
				gint        *width,
Packit 98cdb6
				gint        *height)
Packit 98cdb6
{
Packit 98cdb6
  if (width)
Packit 98cdb6
    *width = GDK_PIXMAP_IMPL_QUARTZ (drawable)->width;
Packit 98cdb6
  if (height)
Packit 98cdb6
    *height = GDK_PIXMAP_IMPL_QUARTZ (drawable)->height;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pixmap_impl_quartz_get_image_parameters (GdkPixmap           *pixmap,
Packit 98cdb6
                                             gint                *bits_per_component,
Packit 98cdb6
                                             gint                *bits_per_pixel,
Packit 98cdb6
                                             gint                *bytes_per_row,
Packit 98cdb6
                                             CGColorSpaceRef     *colorspace,
Packit 98cdb6
                                             CGImageAlphaInfo    *alpha_info)
Packit 98cdb6
{
Packit 98cdb6
  GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit 98cdb6
  gint depth = GDK_PIXMAP_OBJECT (pixmap)->depth;
Packit 98cdb6
Packit 98cdb6
  switch (depth)
Packit 98cdb6
    {
Packit 98cdb6
      case 24:
Packit 98cdb6
        if (bits_per_component)
Packit 98cdb6
          *bits_per_component = 8;
Packit 98cdb6
Packit 98cdb6
        if (bits_per_pixel)
Packit 98cdb6
          *bits_per_pixel = 32;
Packit 98cdb6
Packit 98cdb6
        if (bytes_per_row)
Packit 98cdb6
          *bytes_per_row = impl->width * 4;
Packit 98cdb6
Packit 98cdb6
        if (colorspace)
Packit 98cdb6
          *colorspace = CGColorSpaceCreateDeviceRGB ();
Packit 98cdb6
Packit 98cdb6
        if (alpha_info)
Packit 98cdb6
          *alpha_info = kCGImageAlphaNoneSkipLast;
Packit 98cdb6
        break;
Packit 98cdb6
Packit 98cdb6
      case 32:
Packit 98cdb6
        if (bits_per_component)
Packit 98cdb6
          *bits_per_component = 8;
Packit 98cdb6
Packit 98cdb6
        if (bits_per_pixel)
Packit 98cdb6
          *bits_per_pixel = 32;
Packit 98cdb6
Packit 98cdb6
        if (bytes_per_row)
Packit 98cdb6
          *bytes_per_row = impl->width * 4;
Packit 98cdb6
Packit 98cdb6
        if (colorspace)
Packit 98cdb6
          *colorspace = CGColorSpaceCreateDeviceRGB ();
Packit 98cdb6
Packit 98cdb6
        if (alpha_info)
Packit 98cdb6
          *alpha_info = kCGImageAlphaPremultipliedFirst;
Packit 98cdb6
        break;
Packit 98cdb6
Packit 98cdb6
      case 1:
Packit 98cdb6
        if (bits_per_component)
Packit 98cdb6
          *bits_per_component = 8;
Packit 98cdb6
Packit 98cdb6
        if (bits_per_pixel)
Packit 98cdb6
          *bits_per_pixel = 8;
Packit 98cdb6
Packit 98cdb6
        if (bytes_per_row)
Packit 98cdb6
          *bytes_per_row = impl->width;
Packit 98cdb6
Packit 98cdb6
        if (colorspace)
Packit 98cdb6
          *colorspace = CGColorSpaceCreateWithName (kCGColorSpaceGenericGray);
Packit 98cdb6
Packit 98cdb6
        if (alpha_info)
Packit 98cdb6
          *alpha_info = kCGImageAlphaNone;
Packit 98cdb6
        break;
Packit 98cdb6
Packit 98cdb6
      default:
Packit 98cdb6
        g_assert_not_reached ();
Packit 98cdb6
        break;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static CGContextRef
Packit 98cdb6
gdk_pixmap_impl_quartz_get_context (GdkDrawable *drawable,
Packit 98cdb6
				    gboolean     antialias)
Packit 98cdb6
{
Packit 98cdb6
  GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (drawable);
Packit 98cdb6
  CGContextRef cg_context;
Packit 98cdb6
  gint bits_per_component, bytes_per_row;
Packit 98cdb6
  CGColorSpaceRef colorspace;
Packit 98cdb6
  CGImageAlphaInfo alpha_info;
Packit 98cdb6
Packit 98cdb6
  gdk_pixmap_impl_quartz_get_image_parameters (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper,
Packit 98cdb6
                                               &bits_per_component,
Packit 98cdb6
                                               NULL,
Packit 98cdb6
                                               &bytes_per_row,
Packit 98cdb6
                                               &colorspace,
Packit 98cdb6
                                               &alpha_info);
Packit 98cdb6
Packit 98cdb6
  cg_context = CGBitmapContextCreate (impl->data,
Packit 98cdb6
                                      impl->width, impl->height,
Packit 98cdb6
                                      bits_per_component,
Packit 98cdb6
                                      bytes_per_row,
Packit 98cdb6
                                      colorspace,
Packit 98cdb6
                                      alpha_info);
Packit 98cdb6
  CGContextSetAllowsAntialiasing (cg_context, antialias);
Packit 98cdb6
Packit 98cdb6
  CGColorSpaceRelease (colorspace);
Packit 98cdb6
Packit 98cdb6
  /* convert coordinates from core graphics to gtk+ */
Packit 98cdb6
  CGContextTranslateCTM (cg_context, 0, impl->height);
Packit 98cdb6
  CGContextScaleCTM (cg_context, 1.0, -1.0);
Packit 98cdb6
Packit 98cdb6
  return cg_context;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pixmap_impl_quartz_finalize (GObject *object)
Packit 98cdb6
{
Packit 98cdb6
  GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (object);
Packit 98cdb6
Packit 98cdb6
  CGDataProviderRelease (impl->data_provider);
Packit 98cdb6
Packit 98cdb6
  _gdk_quartz_drawable_finish (GDK_DRAWABLE (impl));
Packit 98cdb6
Packit 98cdb6
  G_OBJECT_CLASS (parent_class)->finalize (object);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pixmap_impl_quartz_class_init (GdkPixmapImplQuartzClass *klass)
Packit 98cdb6
{
Packit 98cdb6
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit 98cdb6
  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
Packit 98cdb6
  GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass);
Packit 98cdb6
  
Packit 98cdb6
  parent_class = g_type_class_peek_parent (klass);
Packit 98cdb6
Packit 98cdb6
  object_class->finalize = gdk_pixmap_impl_quartz_finalize;
Packit 98cdb6
Packit 98cdb6
  drawable_class->get_size = gdk_pixmap_impl_quartz_get_size;
Packit 98cdb6
Packit 98cdb6
  drawable_quartz_class->get_context = gdk_pixmap_impl_quartz_get_context;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GType
Packit 98cdb6
_gdk_pixmap_impl_quartz_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 (GdkPixmapImplQuartzClass),
Packit 98cdb6
        (GBaseInitFunc) NULL,
Packit 98cdb6
        (GBaseFinalizeFunc) NULL,
Packit 98cdb6
        (GClassInitFunc) gdk_pixmap_impl_quartz_class_init,
Packit 98cdb6
        NULL,           /* class_finalize */
Packit 98cdb6
        NULL,           /* class_data */
Packit 98cdb6
        sizeof (GdkPixmapImplQuartz),
Packit 98cdb6
        0,              /* n_preallocs */
Packit 98cdb6
        (GInstanceInitFunc) gdk_pixmap_impl_quartz_init
Packit 98cdb6
      };
Packit 98cdb6
      
Packit 98cdb6
      object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
Packit 98cdb6
                                            "GdkPixmapImplQuartz",
Packit 98cdb6
                                            &object_info,
Packit 98cdb6
					    0);
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return object_type;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GType
Packit 98cdb6
_gdk_pixmap_impl_get_type (void)
Packit 98cdb6
{
Packit 98cdb6
  return _gdk_pixmap_impl_quartz_get_type ();
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static inline gboolean
Packit 98cdb6
depth_supported (int depth)
Packit 98cdb6
{
Packit 98cdb6
  if (depth != 24 && depth != 32 && depth != 1)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("Unsupported bit depth %d\n", depth);
Packit 98cdb6
      return FALSE;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
CGImageRef
Packit 98cdb6
_gdk_pixmap_get_cgimage (GdkPixmap *pixmap)
Packit 98cdb6
{
Packit 98cdb6
  GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit 98cdb6
  gint bits_per_component, bits_per_pixel, bytes_per_row;
Packit 98cdb6
  CGColorSpaceRef colorspace;
Packit 98cdb6
  CGImageAlphaInfo alpha_info;
Packit 98cdb6
  CGImageRef image;
Packit 98cdb6
Packit 98cdb6
  gdk_pixmap_impl_quartz_get_image_parameters (pixmap,
Packit 98cdb6
                                               &bits_per_component,
Packit 98cdb6
                                               &bits_per_pixel,
Packit 98cdb6
                                               &bytes_per_row,
Packit 98cdb6
                                               &colorspace,
Packit 98cdb6
                                               &alpha_info);
Packit 98cdb6
Packit 98cdb6
  image = CGImageCreate (impl->width, impl->height,
Packit 98cdb6
                         bits_per_component, bits_per_pixel,
Packit 98cdb6
                         bytes_per_row, colorspace,
Packit 98cdb6
                         alpha_info,
Packit 98cdb6
                         impl->data_provider, NULL, FALSE, 
Packit 98cdb6
                         kCGRenderingIntentDefault);
Packit 98cdb6
  CGColorSpaceRelease (colorspace);
Packit 98cdb6
Packit 98cdb6
  return image;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
data_provider_release (void *info, const void *data, size_t size)
Packit 98cdb6
{
Packit 98cdb6
  g_free (info);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkPixmap*
Packit 98cdb6
_gdk_pixmap_new (GdkDrawable *drawable,
Packit 98cdb6
                 gint         width,
Packit 98cdb6
                 gint         height,
Packit 98cdb6
                 gint         depth)
Packit 98cdb6
{
Packit 98cdb6
  GdkPixmap *pixmap;
Packit 98cdb6
  GdkDrawableImplQuartz *draw_impl;
Packit 98cdb6
  GdkPixmapImplQuartz *pix_impl;
Packit 98cdb6
  gint window_depth;
Packit 98cdb6
  gint bytes_per_row;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
Packit 98cdb6
  g_return_val_if_fail ((drawable != NULL) || (depth != -1), NULL);
Packit 98cdb6
  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
Packit 98cdb6
Packit 98cdb6
  if (GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
Packit 98cdb6
    return NULL;
Packit 98cdb6
Packit 98cdb6
  if (!drawable)
Packit 98cdb6
    drawable = gdk_screen_get_root_window (gdk_screen_get_default ());
Packit 98cdb6
Packit 98cdb6
  window_depth = gdk_drawable_get_depth (GDK_DRAWABLE (drawable));
Packit 98cdb6
Packit 98cdb6
  if (depth == -1)
Packit 98cdb6
    depth = window_depth;
Packit 98cdb6
Packit 98cdb6
  if (!depth_supported (depth))
Packit 98cdb6
    return NULL;
Packit 98cdb6
Packit 98cdb6
  pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
Packit 98cdb6
  draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit 98cdb6
  pix_impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit 98cdb6
  draw_impl->wrapper = GDK_DRAWABLE (pixmap);
Packit 98cdb6
Packit 98cdb6
  g_assert (depth == 24 || depth == 32 || depth == 1);
Packit 98cdb6
Packit 98cdb6
  pix_impl->width = width;
Packit 98cdb6
  pix_impl->height = height;
Packit 98cdb6
  GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
Packit 98cdb6
Packit 98cdb6
  gdk_pixmap_impl_quartz_get_image_parameters (pixmap,
Packit 98cdb6
                                               NULL, NULL,
Packit 98cdb6
                                               &bytes_per_row,
Packit 98cdb6
                                               NULL, NULL);
Packit 98cdb6
Packit 98cdb6
  pix_impl->data = g_malloc (height * bytes_per_row);
Packit 98cdb6
  pix_impl->data_provider = CGDataProviderCreateWithData (pix_impl->data,
Packit 98cdb6
                                                          pix_impl->data,
Packit 98cdb6
                                                          height * bytes_per_row,
Packit 98cdb6
                                                          data_provider_release);
Packit 98cdb6
Packit 98cdb6
  if (depth == window_depth) {
Packit 98cdb6
    GdkColormap *colormap = gdk_drawable_get_colormap (drawable);
Packit 98cdb6
Packit 98cdb6
    if (colormap)
Packit 98cdb6
      gdk_drawable_set_colormap (pixmap, colormap);
Packit 98cdb6
  }
Packit 98cdb6
Packit 98cdb6
  return pixmap;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkPixmap *
Packit 98cdb6
_gdk_bitmap_create_from_data (GdkDrawable *window,
Packit 98cdb6
                              const gchar *data,
Packit 98cdb6
                              gint         width,
Packit 98cdb6
                              gint         height)
Packit 98cdb6
{
Packit 98cdb6
  GdkPixmap *pixmap;
Packit 98cdb6
  GdkPixmapImplQuartz *impl;
Packit 98cdb6
  int x, y, bpl;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (data != NULL, NULL);
Packit 98cdb6
  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
Packit 98cdb6
  g_return_val_if_fail (window == NULL || GDK_IS_DRAWABLE (window), NULL);
Packit 98cdb6
Packit 98cdb6
  pixmap = gdk_pixmap_new (window, width, height, 1);
Packit 98cdb6
  impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
Packit 98cdb6
Packit 98cdb6
  /* Bytes per line: Each line consumes an integer number of bytes, possibly
Packit 98cdb6
   * ignoring any excess bits. */
Packit 98cdb6
  bpl = (width + 7) / 8;
Packit 98cdb6
  for (y = 0; y < height; y++)
Packit 98cdb6
    {
Packit 98cdb6
      guchar *dst = impl->data + y * width;
Packit 98cdb6
      const gchar *src = data + (y * bpl);   
Packit 98cdb6
      for (x = 0; x < width; x++)
Packit 98cdb6
	{
Packit 98cdb6
	  if ((src[x / 8] >> x % 8) & 1)
Packit 98cdb6
	    *dst = 0xff;
Packit 98cdb6
	  else
Packit 98cdb6
	    *dst = 0;
Packit 98cdb6
Packit 98cdb6
	  dst++;
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return pixmap;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkPixmap*
Packit 98cdb6
_gdk_pixmap_create_from_data (GdkDrawable    *drawable,
Packit 98cdb6
                              const gchar    *data,
Packit 98cdb6
                              gint            width,
Packit 98cdb6
                              gint            height,
Packit 98cdb6
                              gint            depth,
Packit 98cdb6
                              const GdkColor *fg,
Packit 98cdb6
                              const GdkColor *bg)
Packit 98cdb6
{	
Packit 98cdb6
  /* FIXME: Implement */
Packit 98cdb6
  return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkPixmap *
Packit 98cdb6
gdk_pixmap_foreign_new_for_display (GdkDisplay      *display,
Packit 98cdb6
				    GdkNativeWindow  anid)
Packit 98cdb6
{
Packit 98cdb6
  return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkPixmap*
Packit 98cdb6
gdk_pixmap_foreign_new (GdkNativeWindow anid)
Packit 98cdb6
{
Packit 98cdb6
   return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkPixmap *
Packit 98cdb6
gdk_pixmap_foreign_new_for_screen (GdkScreen       *screen,
Packit 98cdb6
				   GdkNativeWindow  anid,
Packit 98cdb6
				   gint             width,
Packit 98cdb6
				   gint             height,
Packit 98cdb6
				   gint             depth)
Packit 98cdb6
{
Packit 98cdb6
  return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkPixmap*
Packit 98cdb6
gdk_pixmap_lookup (GdkNativeWindow anid)
Packit 98cdb6
{
Packit 98cdb6
  return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkPixmap*
Packit 98cdb6
gdk_pixmap_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
Packit 98cdb6
{
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
Packit 98cdb6
  return NULL;
Packit 98cdb6
}