261 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			261 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* gdkpixmap-quartz.c
 | 
						|
 *
 | 
						|
 * Copyright (C) 2005 Imendio AB
 | 
						|
 *
 | 
						|
 * This library is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU Lesser General Public
 | 
						|
 * License as published by the Free Software Foundation; either
 | 
						|
 * version 2 of the License, or (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This library is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
 * Lesser General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU Lesser General Public
 | 
						|
 * License along with this library; if not, write to the
 | 
						|
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
						|
 * Boston, MA 02111-1307, USA.
 | 
						|
 */
 | 
						|
 | 
						|
#include "config.h"
 | 
						|
 | 
						|
#include "gdkpixmap.h"
 | 
						|
#include "gdkprivate-quartz.h"
 | 
						|
 | 
						|
static gpointer parent_class;
 | 
						|
 | 
						|
static void
 | 
						|
gdk_pixmap_impl_quartz_init (GdkPixmapImplQuartz *impl)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
gdk_pixmap_impl_quartz_get_size (GdkDrawable *drawable,
 | 
						|
				gint        *width,
 | 
						|
				gint        *height)
 | 
						|
{
 | 
						|
  if (width)
 | 
						|
    *width = GDK_PIXMAP_IMPL_QUARTZ (drawable)->width;
 | 
						|
  if (height)
 | 
						|
    *height = GDK_PIXMAP_IMPL_QUARTZ (drawable)->height;
 | 
						|
}
 | 
						|
 | 
						|
static CGContextRef
 | 
						|
gdk_pixmap_impl_quartz_get_context (GdkDrawable *drawable,
 | 
						|
				    gboolean     antialias)
 | 
						|
{
 | 
						|
  GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (drawable);
 | 
						|
  CGContextRef cg_context;
 | 
						|
  size_t height;
 | 
						|
 | 
						|
  cg_context = CGBitmapContextCreate (impl->data,
 | 
						|
                                      CGImageGetWidth (impl->image),
 | 
						|
                                      CGImageGetHeight (impl->image),
 | 
						|
                                      CGImageGetBitsPerComponent (impl->image),
 | 
						|
                                      CGImageGetBytesPerRow (impl->image),
 | 
						|
                                      CGImageGetColorSpace (impl->image),
 | 
						|
                                      CGImageGetBitmapInfo (impl->image));
 | 
						|
  CGContextSetAllowsAntialiasing (cg_context, antialias);
 | 
						|
 | 
						|
  /* convert coordinates from core graphics to gtk+ */
 | 
						|
  height = CGImageGetHeight (impl->image);
 | 
						|
 | 
						|
  CGContextTranslateCTM (cg_context, 0, height);
 | 
						|
  CGContextScaleCTM (cg_context, 1.0, -1.0);
 | 
						|
 | 
						|
  return cg_context;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
gdk_pixmap_impl_quartz_finalize (GObject *object)
 | 
						|
{
 | 
						|
  GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (object);
 | 
						|
 | 
						|
  CGImageRelease (impl->image);
 | 
						|
 | 
						|
  _gdk_quartz_drawable_finish (GDK_DRAWABLE (impl));
 | 
						|
 | 
						|
  G_OBJECT_CLASS (parent_class)->finalize (object);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
gdk_pixmap_impl_quartz_class_init (GdkPixmapImplQuartzClass *klass)
 | 
						|
{
 | 
						|
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
						|
  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
 | 
						|
  GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass);
 | 
						|
  
 | 
						|
  parent_class = g_type_class_peek_parent (klass);
 | 
						|
 | 
						|
  object_class->finalize = gdk_pixmap_impl_quartz_finalize;
 | 
						|
 | 
						|
  drawable_class->get_size = gdk_pixmap_impl_quartz_get_size;
 | 
						|
 | 
						|
  drawable_quartz_class->get_context = gdk_pixmap_impl_quartz_get_context;
 | 
						|
}
 | 
						|
 | 
						|
GType
 | 
						|
_gdk_pixmap_impl_quartz_get_type (void)
 | 
						|
{
 | 
						|
  static GType object_type = 0;
 | 
						|
 | 
						|
  if (!object_type)
 | 
						|
    {
 | 
						|
      const GTypeInfo object_info =
 | 
						|
      {
 | 
						|
        sizeof (GdkPixmapImplQuartzClass),
 | 
						|
        (GBaseInitFunc) NULL,
 | 
						|
        (GBaseFinalizeFunc) NULL,
 | 
						|
        (GClassInitFunc) gdk_pixmap_impl_quartz_class_init,
 | 
						|
        NULL,           /* class_finalize */
 | 
						|
        NULL,           /* class_data */
 | 
						|
        sizeof (GdkPixmapImplQuartz),
 | 
						|
        0,              /* n_preallocs */
 | 
						|
        (GInstanceInitFunc) gdk_pixmap_impl_quartz_init
 | 
						|
      };
 | 
						|
      
 | 
						|
      object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
 | 
						|
                                            "GdkPixmapImplQuartz",
 | 
						|
                                            &object_info,
 | 
						|
					    0);
 | 
						|
    }
 | 
						|
  
 | 
						|
  return object_type;
 | 
						|
}
 | 
						|
 | 
						|
GType
 | 
						|
_gdk_pixmap_impl_get_type (void)
 | 
						|
{
 | 
						|
  return _gdk_pixmap_impl_quartz_get_type ();
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
data_provider_release (void *info, const void *data, size_t size)
 | 
						|
{
 | 
						|
  g_free (info);
 | 
						|
}
 | 
						|
 | 
						|
GdkPixmap*
 | 
						|
_gdk_pixmap_new (GdkDrawable *drawable,
 | 
						|
                 gint         width,
 | 
						|
                 gint         height,
 | 
						|
                 gint         depth)
 | 
						|
{
 | 
						|
  GdkPixmap *pixmap;
 | 
						|
  GdkDrawableImplQuartz *draw_impl;
 | 
						|
  GdkPixmapImplQuartz *pix_impl;
 | 
						|
  gint window_depth;
 | 
						|
  CGColorSpaceRef colorspace;
 | 
						|
  CGDataProviderRef data_provider;
 | 
						|
  CGImageAlphaInfo alpha_info;
 | 
						|
  gint bytes_per_row, bits_per_pixel;
 | 
						|
 | 
						|
  g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
 | 
						|
  g_return_val_if_fail ((drawable != NULL) || (depth != -1), NULL);
 | 
						|
  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
 | 
						|
 | 
						|
  if (GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  if (!drawable)
 | 
						|
    drawable = gdk_screen_get_root_window (gdk_screen_get_default ());
 | 
						|
 | 
						|
  window_depth = gdk_drawable_get_depth (GDK_DRAWABLE (drawable));
 | 
						|
 | 
						|
  if (depth == -1)
 | 
						|
    depth = window_depth;
 | 
						|
 | 
						|
  switch (depth)
 | 
						|
    {
 | 
						|
    case 24:
 | 
						|
      alpha_info = kCGImageAlphaNoneSkipLast;
 | 
						|
      bytes_per_row = width * 4;
 | 
						|
      bits_per_pixel = 32;
 | 
						|
      colorspace = CGColorSpaceCreateDeviceRGB ();
 | 
						|
      break;
 | 
						|
    case 32:
 | 
						|
      alpha_info = kCGImageAlphaPremultipliedFirst;
 | 
						|
      bytes_per_row = width * 4;
 | 
						|
      bits_per_pixel = 32;
 | 
						|
      colorspace = CGColorSpaceCreateDeviceRGB ();
 | 
						|
      break;
 | 
						|
    case 1:
 | 
						|
      alpha_info = kCGImageAlphaNone;
 | 
						|
      bytes_per_row = width;
 | 
						|
      bits_per_pixel = 8;
 | 
						|
      colorspace = CGColorSpaceCreateDeviceGray ();
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      g_warning ("Unsupported bit depth %d\n", depth);
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
 | 
						|
  draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
 | 
						|
  pix_impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
 | 
						|
  draw_impl->wrapper = GDK_DRAWABLE (pixmap);
 | 
						|
 | 
						|
  g_assert (depth == 24 || depth == 32 || depth == 1);
 | 
						|
 | 
						|
  pix_impl->data = g_malloc (height * bytes_per_row);
 | 
						|
  data_provider = CGDataProviderCreateWithData (pix_impl->data, pix_impl->data, 
 | 
						|
						height * bytes_per_row, data_provider_release);
 | 
						|
  pix_impl->image = CGImageCreate (width, height, 8, bits_per_pixel, 
 | 
						|
				   bytes_per_row, colorspace,
 | 
						|
				   alpha_info,
 | 
						|
				   data_provider, NULL, FALSE, 
 | 
						|
				   kCGRenderingIntentDefault);
 | 
						|
  CGDataProviderRelease (data_provider);
 | 
						|
  CGColorSpaceRelease (colorspace);
 | 
						|
 | 
						|
  pix_impl->width = width;
 | 
						|
  pix_impl->height = height;
 | 
						|
  GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
 | 
						|
 | 
						|
  if (depth == window_depth) {
 | 
						|
    GdkColormap *colormap = gdk_drawable_get_colormap (drawable);
 | 
						|
 | 
						|
    if (colormap)
 | 
						|
      gdk_drawable_set_colormap (pixmap, colormap);
 | 
						|
  }
 | 
						|
 | 
						|
  return pixmap;
 | 
						|
}
 | 
						|
 | 
						|
GdkPixmap *
 | 
						|
gdk_pixmap_foreign_new_for_display (GdkDisplay      *display,
 | 
						|
				    GdkNativeWindow  anid)
 | 
						|
{
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
GdkPixmap*
 | 
						|
gdk_pixmap_foreign_new (GdkNativeWindow anid)
 | 
						|
{
 | 
						|
   return NULL;
 | 
						|
}
 | 
						|
 | 
						|
GdkPixmap *
 | 
						|
gdk_pixmap_foreign_new_for_screen (GdkScreen       *screen,
 | 
						|
				   GdkNativeWindow  anid,
 | 
						|
				   gint             width,
 | 
						|
				   gint             height,
 | 
						|
				   gint             depth)
 | 
						|
{
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
GdkPixmap*
 | 
						|
gdk_pixmap_lookup (GdkNativeWindow anid)
 | 
						|
{
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
GdkPixmap*
 | 
						|
gdk_pixmap_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
 | 
						|
{
 | 
						|
  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
 | 
						|
  return NULL;
 | 
						|
}
 |