X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;ds=sidebyside;f=gdk%2Fgdkpixmap.c;h=06ae850caac1d31eca37b220b961f659ab54a91e;hb=b68801f168d9fef8efe1be4fe19ce1118d9ad041;hp=48b072b91c9427429203ac03c7b6c15d47bd6148;hpb=f734007af4cba93349a969b50ea1d44bfa0e95a3;p=~andy%2Fgtk diff --git a/gdk/gdkpixmap.c b/gdk/gdkpixmap.c index 48b072b91..06ae850ca 100644 --- a/gdk/gdkpixmap.c +++ b/gdk/gdkpixmap.c @@ -2,693 +2,775 @@ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public + * 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 - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * 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 -#include -#include -/* Needed for SEEK_END in SunOS */ -#include -#include -#include "gdk.h" -#include "gdkprivate.h" +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ -typedef struct +#include "config.h" +#include "gdkpixmap.h" +#include "gdkinternals.h" +#include "gdkpixbuf.h" +#include "gdkscreen.h" + + +static GdkGC *gdk_pixmap_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask mask); +static void gdk_pixmap_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height); +static void gdk_pixmap_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2); +static void gdk_pixmap_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints); +static void gdk_pixmap_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkPixmap *original_src); +static void gdk_pixmap_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); +static void gdk_pixmap_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs); +static void gdk_pixmap_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); + +static void gdk_pixmap_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs); +static void gdk_pixmap_draw_glyphs_transformed (GdkDrawable *drawable, + GdkGC *gc, + PangoMatrix *matrix, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs); + +static void gdk_pixmap_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); +static void gdk_pixmap_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither); +static void gdk_pixmap_draw_trapezoids (GdkDrawable *drawable, + GdkGC *gc, + GdkTrapezoid *trapezoids, + gint n_trapezoids); + +static void gdk_pixmap_real_get_size (GdkDrawable *drawable, + gint *width, + gint *height); + +static GdkImage* gdk_pixmap_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height); + +static cairo_surface_t *gdk_pixmap_ref_cairo_surface (GdkDrawable *drawable); +static cairo_surface_t *gdk_pixmap_create_cairo_surface (GdkDrawable *drawable, + int width, + int height); + +static GdkVisual* gdk_pixmap_real_get_visual (GdkDrawable *drawable); +static gint gdk_pixmap_real_get_depth (GdkDrawable *drawable); +static void gdk_pixmap_real_set_colormap (GdkDrawable *drawable, + GdkColormap *cmap); +static GdkColormap* gdk_pixmap_real_get_colormap (GdkDrawable *drawable); +static GdkScreen* gdk_pixmap_real_get_screen (GdkDrawable *drawable); + +static void gdk_pixmap_init (GdkPixmapObject *pixmap); +static void gdk_pixmap_class_init (GdkPixmapObjectClass *klass); +static void gdk_pixmap_finalize (GObject *object); + +static gpointer parent_class = NULL; + +GType +gdk_pixmap_get_type (void) { - gchar *color_string; - GdkColor color; - gint transparent; -} _GdkPixmapColor; + static GType object_type = 0; + + if (!object_type) + object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE, + "GdkPixmap", + sizeof (GdkPixmapObjectClass), + (GClassInitFunc) gdk_pixmap_class_init, + sizeof (GdkPixmapObject), + (GInstanceInitFunc) gdk_pixmap_init, + 0); + + return object_type; +} -GdkPixmap* -gdk_pixmap_new (GdkWindow *window, - gint width, - gint height, - gint depth) +static void +gdk_pixmap_init (GdkPixmapObject *pixmap) { - GdkPixmap *pixmap; - GdkWindowPrivate *private; - GdkWindowPrivate *window_private; - - if (!window) - window = (GdkWindow*) &gdk_root_parent; - - window_private = (GdkWindowPrivate*) window; - if (window_private->destroyed) - return NULL; + /* 0-initialization is good for all other fields. */ + pixmap->impl = g_object_new (_gdk_pixmap_impl_get_type (), NULL); +} - if (depth == -1) - gdk_window_get_geometry (window, NULL, NULL, NULL, NULL, &depth); +static void +gdk_pixmap_class_init (GdkPixmapObjectClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = gdk_pixmap_finalize; + + drawable_class->create_gc = gdk_pixmap_create_gc; + drawable_class->draw_rectangle = gdk_pixmap_draw_rectangle; + drawable_class->draw_arc = gdk_pixmap_draw_arc; + drawable_class->draw_polygon = gdk_pixmap_draw_polygon; + drawable_class->draw_drawable_with_src = gdk_pixmap_draw_drawable; + drawable_class->draw_points = gdk_pixmap_draw_points; + drawable_class->draw_segments = gdk_pixmap_draw_segments; + drawable_class->draw_lines = gdk_pixmap_draw_lines; + drawable_class->draw_glyphs = gdk_pixmap_draw_glyphs; + drawable_class->draw_glyphs_transformed = gdk_pixmap_draw_glyphs_transformed; + drawable_class->draw_image = gdk_pixmap_draw_image; + drawable_class->draw_pixbuf = gdk_pixmap_draw_pixbuf; + drawable_class->draw_trapezoids = gdk_pixmap_draw_trapezoids; + drawable_class->get_depth = gdk_pixmap_real_get_depth; + drawable_class->get_screen = gdk_pixmap_real_get_screen; + drawable_class->get_size = gdk_pixmap_real_get_size; + drawable_class->set_colormap = gdk_pixmap_real_set_colormap; + drawable_class->get_colormap = gdk_pixmap_real_get_colormap; + drawable_class->get_visual = gdk_pixmap_real_get_visual; + drawable_class->_copy_to_image = gdk_pixmap_copy_to_image; + drawable_class->ref_cairo_surface = gdk_pixmap_ref_cairo_surface; + drawable_class->create_cairo_surface = gdk_pixmap_create_cairo_surface; +} - private = g_new (GdkWindowPrivate, 1); - pixmap = (GdkPixmap*) private; +static void +gdk_pixmap_finalize (GObject *object) +{ + GdkPixmapObject *obj = (GdkPixmapObject *) object; - private->xdisplay = window_private->xdisplay; - private->window_type = GDK_WINDOW_PIXMAP; - private->xwindow = XCreatePixmap (private->xdisplay, window_private->xwindow, - width, height, depth); - private->parent = NULL; - private->x = 0; - private->y = 0; - private->width = width; - private->height = height; - private->resize_count = 0; - private->ref_count = 1; - private->destroyed = 0; + g_object_unref (obj->impl); + obj->impl = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} - gdk_xid_table_insert (&private->xwindow, pixmap); +GdkPixmap * +gdk_pixmap_new (GdkDrawable *drawable, + gint width, + gint height, + gint depth) +{ + GdkDrawable *source_drawable; - return pixmap; + if (drawable) + source_drawable = _gdk_drawable_get_source_drawable (drawable); + else + source_drawable = NULL; + return _gdk_pixmap_new (source_drawable, width, height, depth); } GdkPixmap * -gdk_bitmap_create_from_data (GdkWindow *window, - gchar *data, - gint width, - gint height) +gdk_bitmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height) { - GdkPixmap *pixmap; - GdkWindowPrivate *private; - GdkWindowPrivate *window_private; - - g_return_val_if_fail (data != NULL, NULL); + GdkDrawable *source_drawable; - if (!window) - window = (GdkWindow*) &gdk_root_parent; + if (drawable) + source_drawable = _gdk_drawable_get_source_drawable (drawable); + else + source_drawable = NULL; + return _gdk_bitmap_create_from_data (source_drawable, data, width, height); +} - window_private = (GdkWindowPrivate*) window; - if (window_private->destroyed) - return NULL; +GdkPixmap* +gdk_pixmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height, + gint depth, + const GdkColor *fg, + const GdkColor *bg) +{ + GdkDrawable *source_drawable; - private = g_new (GdkWindowPrivate, 1); - pixmap = (GdkPixmap*) private; + source_drawable = _gdk_drawable_get_source_drawable (drawable); + return _gdk_pixmap_create_from_data (source_drawable, + data, width, height, + depth, fg,bg); +} - private->parent = NULL; - private->xdisplay = window_private->xdisplay; - private->window_type = GDK_WINDOW_PIXMAP; - private->x = 0; - private->y = 0; - private->width = width; - private->height = height; - private->resize_count = 0; - private->ref_count = 1; - private->destroyed = FALSE; - private->xwindow = XCreateBitmapFromData (private->xdisplay, - window_private->xwindow, - data, width, height); +static GdkGC * +gdk_pixmap_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask mask) +{ + return gdk_gc_new_with_values (((GdkPixmapObject *) drawable)->impl, + values, mask); +} - gdk_xid_table_insert (&private->xwindow, pixmap); +static void +gdk_pixmap_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - return pixmap; + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_rectangle (private->impl, gc, filled, + x, y, width, height); } -GdkPixmap* -gdk_pixmap_create_from_data (GdkWindow *window, - gchar *data, - gint width, - gint height, - gint depth, - GdkColor *fg, - GdkColor *bg) +static void +gdk_pixmap_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) { - GdkPixmap *pixmap; - GdkWindowPrivate *private; - GdkWindowPrivate *window_private; - - g_return_val_if_fail (data != NULL, NULL); - g_return_val_if_fail (fg != NULL, NULL); - g_return_val_if_fail (bg != NULL, NULL); + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - if (!window) - window = (GdkWindow*) &gdk_root_parent; + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_arc (private->impl, gc, filled, + x, y, + width, height, angle1, angle2); +} - window_private = (GdkWindowPrivate*) window; - if (window_private->destroyed) - return NULL; +static void +gdk_pixmap_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - if (depth == -1) - gdk_window_get_geometry (window, NULL, NULL, NULL, NULL, &depth); + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_polygon (private->impl, gc, filled, points, npoints); +} - private = g_new (GdkWindowPrivate, 1); - pixmap = (GdkPixmap*) private; +static void +gdk_pixmap_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkPixmap *original_src) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + /* Call the method directly to avoid getting the composite drawable again */ + GDK_DRAWABLE_GET_CLASS (private->impl)->draw_drawable_with_src (private->impl, gc, + src, + xsrc, ysrc, + xdest, ydest, + width, height, + original_src); +} - private->parent = NULL; - private->xdisplay = window_private->xdisplay; - private->window_type = GDK_WINDOW_PIXMAP; - private->x = 0; - private->y = 0; - private->width = width; - private->height = height; - private->resize_count = 0; - private->ref_count = 1; - private->destroyed = FALSE; +static void +gdk_pixmap_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - private->xwindow = XCreatePixmapFromBitmapData (private->xdisplay, - window_private->xwindow, - data, width, height, - fg->pixel, bg->pixel, depth); + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_points (private->impl, gc, points, npoints); +} - gdk_xid_table_insert (&private->xwindow, pixmap); +static void +gdk_pixmap_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - return pixmap; + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_segments (private->impl, gc, segs, nsegs); } -gint -gdk_pixmap_seek_string (FILE *infile, - const gchar *str, - gint skip_comments) +static void +gdk_pixmap_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) { - char instr[1024]; - - while (!feof (infile)) - { - fscanf (infile, "%s", instr); - if (skip_comments == TRUE && strcmp (instr, "/*") == 0) - { - fscanf (infile, "%s", instr); - while (!feof (infile) && strcmp (instr, "*/") != 0) - fscanf (infile, "%s", instr); - fscanf(infile, "%s", instr); - } - if (strcmp (instr, str)==0) - return TRUE; - } + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - return FALSE; + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_lines (private->impl, gc, points, npoints); } -gint -gdk_pixmap_seek_char (FILE *infile, - gchar c) +static void +gdk_pixmap_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs) { - gchar b, oldb; + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - while (!feof (infile)) - { - fscanf(infile, "%c", &b); - if (c != b && b == '/') - { - fscanf (infile, "%c", &b); - if (b == '*') - { - oldb = b; - while (!feof (infile) && !(oldb == '*' && b == '/')) - { - oldb = b; - fscanf (infile, "%c", &b); - } - fscanf (infile, "%c", &b); - } - } - if (c == b) - return TRUE; - } - - return FALSE; + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_glyphs (private->impl, gc, font, x, y, glyphs); } -gint -gdk_pixmap_read_string (FILE *infile, - gchar **buffer, - guint *buffer_size) +static void +gdk_pixmap_draw_glyphs_transformed (GdkDrawable *drawable, + GdkGC *gc, + PangoMatrix *matrix, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs) { - gchar c; - guint cnt = 0; + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - if ((*buffer) == NULL) - { - (*buffer_size) = 10 * sizeof (gchar); - (*buffer) = (gchar *) malloc (*buffer_size); - } + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_glyphs_transformed (private->impl, gc, matrix, font, x, y, glyphs); +} - do - fscanf (infile, "%c", &c); - while (!feof (infile) && c != '"'); +static void +gdk_pixmap_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - if (c != '"') - return FALSE; + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_image (private->impl, gc, image, xsrc, ysrc, xdest, ydest, + width, height); +} - while (!feof (infile)) - { - fscanf (infile, "%c", &c); - - if (cnt == (*buffer_size)) - { - (*buffer_size) *= 2; - (*buffer) = (gchar *) realloc ((*buffer), *buffer_size); - } - - if (c != '"') - (*buffer)[cnt++] = c; - else - { - (*buffer)[cnt++] = 0; - return TRUE; - } - } +static void +gdk_pixmap_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - return FALSE; + if (gc) + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_pixbuf (private->impl, gc, pixbuf, + src_x, src_y, dest_x, dest_y, width, height, + dither, x_dither, y_dither); } -gchar* -gdk_pixmap_skip_whitespaces (gchar *buffer) +static void +gdk_pixmap_draw_trapezoids (GdkDrawable *drawable, + GdkGC *gc, + GdkTrapezoid *trapezoids, + gint n_trapezoids) { - gint32 index = 0; - - while (buffer[index] != 0 && (buffer[index] == 0x20 || buffer[index] == 0x09)) - index++; + GdkPixmapObject *private = (GdkPixmapObject *)drawable; - return &buffer[index]; + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_trapezoids (private->impl, gc, trapezoids, n_trapezoids); } -gchar* -gdk_pixmap_skip_string (gchar *buffer) +static void +gdk_pixmap_real_get_size (GdkDrawable *drawable, + gint *width, + gint *height) { - gint32 index = 0; + g_return_if_fail (GDK_IS_PIXMAP (drawable)); - while (buffer[index] != 0 && buffer[index] != 0x20 && buffer[index] != 0x09) - index++; - - return &buffer[index]; + gdk_drawable_get_size (GDK_DRAWABLE (((GdkPixmapObject*)drawable)->impl), + width, height); } -gchar* -gdk_pixmap_extract_color (gchar *buffer) +static GdkVisual* +gdk_pixmap_real_get_visual (GdkDrawable *drawable) { - gint counter, finished = FALSE, numnames; - gchar *ptr = NULL, ch, temp[128]; - gchar color[128], *retcol; - - counter = 0; - while (ptr == NULL) - { - if (buffer[counter] == 'c') - { - ch = buffer[counter + 1]; - if (ch == 0x20 || ch == 0x09) - ptr = &buffer[counter + 1]; - } - else if (buffer[counter] == 0) - return NULL; - - counter++; - } + GdkColormap *colormap; - if (ptr == NULL) - return NULL; + g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL); - ptr = gdk_pixmap_skip_whitespaces (ptr); + colormap = gdk_drawable_get_colormap (drawable); + return colormap ? gdk_colormap_get_visual (colormap) : NULL; +} - if (ptr[0] == 0) - return NULL; - else if (ptr[0] == '#') - { - retcol = g_new(gchar, strlen (ptr) + 1); - strcpy (retcol, ptr); - return retcol; - } +static gint +gdk_pixmap_real_get_depth (GdkDrawable *drawable) +{ + gint depth; + + g_return_val_if_fail (GDK_IS_PIXMAP (drawable), 0); - color[0] = 0; - numnames = 0; + depth = GDK_PIXMAP_OBJECT (drawable)->depth; - while (finished == FALSE) - { - sscanf (ptr, "%s", temp); - - if ((gint)ptr[0] == 0 || strcmp ("s", temp) == 0 || strcmp ("m", temp) == 0 || - strcmp ("g", temp) == 0 || strcmp ("g4", temp) == 0) - finished = TRUE; - else - { - if (numnames > 0) - strcat (color, " "); - strcat (color, temp); - ptr = gdk_pixmap_skip_string (ptr); - ptr = gdk_pixmap_skip_whitespaces (ptr); - numnames++; - } - } + return depth; +} - retcol = g_new(gchar, strlen (color) + 1); - strcpy (retcol, color); - return retcol; +static void +gdk_pixmap_real_set_colormap (GdkDrawable *drawable, + GdkColormap *cmap) +{ + g_return_if_fail (GDK_IS_PIXMAP (drawable)); + + gdk_drawable_set_colormap (((GdkPixmapObject*)drawable)->impl, cmap); } +static GdkColormap* +gdk_pixmap_real_get_colormap (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL); + + return gdk_drawable_get_colormap (((GdkPixmapObject*)drawable)->impl); +} -GdkPixmap* -gdk_pixmap_create_from_xpm (GdkWindow *window, - GdkBitmap **mask, - GdkColor *transparent_color, - const gchar *filename) -{ - FILE *infile = NULL; - GdkPixmap *pixmap = NULL; - GdkImage *image = NULL; - GdkColormap *colormap; - GdkVisual *visual; - GdkGC *gc; - GdkColor tmp_color; - gint width, height, num_cols, cpp, cnt, n, ns, xcnt, ycnt; - gchar *buffer = NULL, *color_name = NULL, pixel_str[32]; - guint buffer_size = 0; - _GdkPixmapColor *colors = NULL, *color = NULL; - gulong index; - - if (!window) - window = (GdkWindow*) &gdk_root_parent; - - infile = fopen (filename, "rb"); - if (infile != NULL) - { - if (gdk_pixmap_seek_string (infile, "XPM", FALSE) == TRUE) - { - if (gdk_pixmap_seek_char (infile,'{') == TRUE) - { - gdk_pixmap_seek_char (infile, '"'); - fseek (infile, -1, SEEK_CUR); - gdk_pixmap_read_string (infile, &buffer, &buffer_size); - - sscanf (buffer,"%d %d %d %d", &width, &height, &num_cols, &cpp); - - colors = g_new(_GdkPixmapColor, num_cols); - - colormap = gdk_window_get_colormap (window); - visual = gdk_window_get_visual (window); - - if (transparent_color == NULL) - { - gdk_color_white (colormap, &tmp_color); - transparent_color = &tmp_color; - } - - for (cnt = 0; cnt < num_cols; cnt++) - { - gdk_pixmap_seek_char (infile, '"'); - fseek (infile, -1, SEEK_CUR); - gdk_pixmap_read_string (infile, &buffer, &buffer_size); - - colors[cnt].color_string = g_new(gchar, cpp + 1); - for (n = 0; n < cpp; n++) - colors[cnt].color_string[n] = buffer[n]; - colors[cnt].color_string[n] = 0; - colors[cnt].transparent = FALSE; - - if (color_name != NULL) - g_free (color_name); - - color_name = gdk_pixmap_extract_color (&buffer[cpp]); - - if (color_name != NULL) - { - if (gdk_color_parse (color_name, &colors[cnt].color) == FALSE) - { - colors[cnt].color = *transparent_color; - colors[cnt].transparent = TRUE; - } - } - else - { - colors[cnt].color = *transparent_color; - colors[cnt].transparent = TRUE; - } - - gdk_color_alloc (colormap, &colors[cnt].color); - } - - index = 0; - image = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height); - - gc = NULL; - if (mask) - { - /* The pixmap mask is just a bits pattern. - * Color 0 is used for background and 1 for foreground. - * We don't care about the colormap, we just need 0 and 1. - */ - GdkColor mask_pattern; - - *mask = gdk_pixmap_new (window, width, height, 1); - gc = gdk_gc_new (*mask); - - mask_pattern.pixel = 0; - gdk_gc_set_foreground (gc, &mask_pattern); - gdk_draw_rectangle (*mask, gc, TRUE, 0, 0, -1, -1); - - mask_pattern.pixel = 1; - gdk_gc_set_foreground (gc, &mask_pattern); - } - - for (ycnt = 0; ycnt < height; ycnt++) - { - gdk_pixmap_read_string (infile, &buffer, &buffer_size); - - for (n = 0, cnt = 0, xcnt = 0; n < (width * cpp); n += cpp, xcnt++) - { - strncpy (pixel_str, &buffer[n], cpp); - pixel_str[cpp] = 0; - color = NULL; - ns = 0; - - while (color == NULL) - { - if (strcmp (pixel_str, colors[ns].color_string) == 0) - color = &colors[ns]; - else - ns++; - } - - gdk_image_put_pixel (image, xcnt, ycnt, color->color.pixel); - - if (mask && color->transparent) - { - if (cnt < xcnt) - gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt); - cnt = xcnt + 1; - } - } - - if (mask && (cnt < xcnt)) - gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt); - } - - if (mask) - gdk_gc_destroy (gc); - - pixmap = gdk_pixmap_new (window, width, height, visual->depth); - - gc = gdk_gc_new (pixmap); - gdk_gc_set_foreground (gc, transparent_color); - gdk_draw_image (pixmap, gc, image, 0, 0, 0, 0, image->width, image->height); - gdk_gc_destroy (gc); - gdk_image_destroy (image); - } - } - - fclose (infile); - free (buffer); - - if (colors != NULL) - { - for (cnt = 0; cnt < num_cols; cnt++) - g_free (colors[cnt].color_string); - g_free (colors); - } - } +static GdkImage* +gdk_pixmap_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height) +{ + g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL); + + return gdk_drawable_copy_to_image (((GdkPixmapObject*)drawable)->impl, + image, + src_x, src_y, dest_x, dest_y, + width, height); +} - return pixmap; +static cairo_surface_t * +gdk_pixmap_ref_cairo_surface (GdkDrawable *drawable) +{ + return _gdk_drawable_ref_cairo_surface (((GdkPixmapObject*)drawable)->impl); } -GdkPixmap* -gdk_pixmap_create_from_xpm_d (GdkWindow *window, - GdkBitmap **mask, - GdkColor *transparent_color, - gchar **data) +static cairo_surface_t * +gdk_pixmap_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) { - GdkPixmap *pixmap = NULL; - GdkImage *image = NULL; - GdkColormap *colormap; - GdkVisual *visual; - GdkGC *gc; - GdkColor tmp_color; - gint width, height, num_cols, cpp, cnt, n, ns, xcnt, ycnt, i; - gchar *buffer, *color_name = NULL, pixel_str[32]; - _GdkPixmapColor *colors = NULL, *color = NULL; - gulong index; + return _gdk_windowing_create_cairo_surface (GDK_PIXMAP_OBJECT(drawable)->impl, + width, height); +} - if (!window) - window = (GdkWindow*) &gdk_root_parent; - i = 0; - buffer = data[i++]; - sscanf (buffer,"%d %d %d %d", &width, &height, &num_cols, &cpp); - colors = g_new(_GdkPixmapColor, num_cols); +static GdkBitmap * +make_solid_mask (GdkScreen *screen, gint width, gint height) +{ + GdkBitmap *bitmap; + GdkGC *gc; + GdkGCValues gc_values; + + bitmap = gdk_pixmap_new (gdk_screen_get_root_window (screen), + width, height, 1); + + gc_values.foreground.pixel = 1; + gc = gdk_gc_new_with_values (bitmap, &gc_values, GDK_GC_FOREGROUND); + + gdk_draw_rectangle (bitmap, gc, TRUE, 0, 0, width, height); + + g_object_unref (gc); + + return bitmap; +} - colormap = gdk_window_get_colormap (window); - visual = gdk_window_get_visual (window); +#define PACKED_COLOR(c) ((((c)->red & 0xff00) << 8) | \ + ((c)->green & 0xff00) | \ + ((c)->blue >> 8)) - if (transparent_color == NULL) +static GdkPixmap * +gdk_pixmap_colormap_new_from_pixbuf (GdkColormap *colormap, + GdkBitmap **mask, + const GdkColor *transparent_color, + GdkPixbuf *pixbuf) +{ + GdkPixmap *pixmap; + GdkPixbuf *render_pixbuf; + GdkGC *tmp_gc; + GdkScreen *screen = gdk_colormap_get_screen (colormap); + + pixmap = gdk_pixmap_new (gdk_screen_get_root_window (screen), + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + gdk_colormap_get_visual (colormap)->depth); + gdk_drawable_set_colormap (pixmap, colormap); + + if (transparent_color) { - gdk_color_white (colormap, &tmp_color); - transparent_color = &tmp_color; + guint32 packed_color = PACKED_COLOR (transparent_color); + render_pixbuf = gdk_pixbuf_composite_color_simple (pixbuf, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + GDK_INTERP_NEAREST, + 255, 16, packed_color, packed_color); } + else + render_pixbuf = pixbuf; - for (cnt = 0; cnt < num_cols; cnt++) - { - buffer = data[i++]; - - colors[cnt].color_string = g_new(gchar, cpp + 1); - for (n = 0; n < cpp; n++) - colors[cnt].color_string[n] = buffer[n]; - colors[cnt].color_string[n] = 0; - colors[cnt].transparent = FALSE; - - if (color_name != NULL) - g_free (color_name); - - color_name = gdk_pixmap_extract_color (&buffer[cpp]); - - if (color_name != NULL) - { - if (gdk_color_parse (color_name, &colors[cnt].color) == FALSE) - { - colors[cnt].color = *transparent_color; - colors[cnt].transparent = TRUE; - } - } - else - { - colors[cnt].color = *transparent_color; - colors[cnt].transparent = TRUE; - } - - gdk_color_alloc (colormap, &colors[cnt].color); - } + tmp_gc = _gdk_drawable_get_scratch_gc (pixmap, FALSE); + gdk_draw_pixbuf (pixmap, tmp_gc, render_pixbuf, 0, 0, 0, 0, + gdk_pixbuf_get_width (render_pixbuf), + gdk_pixbuf_get_height (render_pixbuf), + GDK_RGB_DITHER_NORMAL, 0, 0); - index = 0; - image = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height); + if (render_pixbuf != pixbuf) + g_object_unref (render_pixbuf); - gc = NULL; if (mask) - { - /* The pixmap mask is just a bits pattern. - * Color 0 is used for background and 1 for foreground. - * We don't care about the colormap, we just need 0 and 1. - */ - GdkColor mask_pattern; - - *mask = gdk_pixmap_new (window, width, height, 1); - gc = gdk_gc_new (*mask); + gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, colormap, NULL, mask, 128); - mask_pattern.pixel = 0; - gdk_gc_set_foreground (gc, &mask_pattern); - gdk_draw_rectangle (*mask, gc, TRUE, 0, 0, -1, -1); - - mask_pattern.pixel = 1; - gdk_gc_set_foreground (gc, &mask_pattern); - } + if (mask && !*mask) + *mask = make_solid_mask (screen, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); - for (ycnt = 0; ycnt < height; ycnt++) - { - buffer = data[i++]; - - for (n = 0, cnt = 0, xcnt = 0; n < (width * cpp); n += cpp, xcnt++) - { - strncpy (pixel_str, &buffer[n], cpp); - pixel_str[cpp] = 0; - color = NULL; - ns = 0; - - while (color == NULL) - { - if (strcmp (pixel_str, colors[ns].color_string) == 0) - color = &colors[ns]; - else - ns++; - } - - gdk_image_put_pixel (image, xcnt, ycnt, color->color.pixel); - - if (mask && color->transparent) - { - if (cnt < xcnt) - gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt); - cnt = xcnt + 1; - } - } - - if (mask && (cnt < xcnt)) - gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt); - } + return pixmap; +} - if (mask) - gdk_gc_destroy (gc); +/** + * gdk_pixmap_colormap_create_from_xpm: + * @drawable: a #GdkDrawable, used to determine default values + * for the new pixmap. Can be %NULL if @colormap is given. + * @colormap: the #GdkColormap that the new pixmap will be use. + * If omitted, the colormap for @window will be used. + * @mask: a pointer to a place to store a bitmap representing + * the transparency mask of the XPM file. Can be %NULL, + * in which case transparency will be ignored. + * @transparent_color: the color to be used for the pixels + * that are transparent in the input file. Can be %NULL, + * in which case a default color will be used. + * @filename: the filename of a file containing XPM data. + * + * Create a pixmap from a XPM file using a particular colormap. + * + * Returns: (transfer none): the #GdkPixmap. + */ +GdkPixmap* +gdk_pixmap_colormap_create_from_xpm (GdkDrawable *drawable, + GdkColormap *colormap, + GdkBitmap **mask, + const GdkColor *transparent_color, + const gchar *filename) +{ + GdkPixbuf *pixbuf; + GdkPixmap *pixmap; - pixmap = gdk_pixmap_new (window, width, height, visual->depth); + g_return_val_if_fail (drawable != NULL || colormap != NULL, NULL); + g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (colormap == NULL || GDK_IS_COLORMAP (colormap), NULL); - gc = gdk_gc_new (pixmap); - gdk_gc_set_foreground (gc, transparent_color); - gdk_draw_image (pixmap, gc, image, 0, 0, 0, 0, image->width, image->height); - gdk_gc_destroy (gc); - gdk_image_destroy (image); + if (colormap == NULL) + colormap = gdk_drawable_get_colormap (drawable); + + pixbuf = gdk_pixbuf_new_from_file (filename, NULL); + if (!pixbuf) + return NULL; - if (colors != NULL) - { - for (cnt = 0; cnt < num_cols; cnt++) - g_free (colors[cnt].color_string); - g_free (colors); - } + pixmap = gdk_pixmap_colormap_new_from_pixbuf (colormap, mask, transparent_color, pixbuf); + g_object_unref (pixbuf); + return pixmap; } +/** + * gdk_pixmap_create_from_xpm: + * @drawable: a #GdkDrawable, used to determine default values + * for the new pixmap. + * @mask: (out) a pointer to a place to store a bitmap representing + * the transparency mask of the XPM file. Can be %NULL, + * in which case transparency will be ignored. + * @transparent_color: the color to be used for the pixels + * that are transparent in the input file. Can be %NULL, + * in which case a default color will be used. + * @filename: the filename of a file containing XPM data. + * + * Create a pixmap from a XPM file. + * + * Returns: (transfer none): the #GdkPixmap + */ GdkPixmap* -gdk_pixmap_ref (GdkPixmap *pixmap) +gdk_pixmap_create_from_xpm (GdkDrawable *drawable, + GdkBitmap **mask, + const GdkColor *transparent_color, + const gchar *filename) { - GdkWindowPrivate *private = (GdkWindowPrivate *)pixmap; - g_return_val_if_fail (pixmap != NULL, NULL); - - private->ref_count += 1; - return pixmap; + return gdk_pixmap_colormap_create_from_xpm (drawable, NULL, mask, + transparent_color, filename); } -void -gdk_pixmap_unref (GdkPixmap *pixmap) +/** + * gdk_pixmap_colormap_create_from_xpm_d: + * @drawable: a #GdkDrawable, used to determine default values + * for the new pixmap. Can be %NULL if @colormap is given. + * @colormap: the #GdkColormap that the new pixmap will be use. + * If omitted, the colormap for @window will be used. + * @mask: a pointer to a place to store a bitmap representing + * the transparency mask of the XPM file. Can be %NULL, + * in which case transparency will be ignored. + * @transparent_color: the color to be used for the pixels + * that are transparent in the input file. Can be %NULL, + * in which case a default color will be used. + * @data: Pointer to a string containing the XPM data. + * + * Create a pixmap from data in XPM format using a particular + * colormap. + * + * Returns: (transfer none): the #GdkPixmap. + */ +GdkPixmap* +gdk_pixmap_colormap_create_from_xpm_d (GdkDrawable *drawable, + GdkColormap *colormap, + GdkBitmap **mask, + const GdkColor *transparent_color, + gchar **data) { - GdkWindowPrivate *private = (GdkWindowPrivate *)pixmap; - g_return_if_fail(pixmap != NULL); + GdkPixbuf *pixbuf; + GdkPixmap *pixmap; - private->ref_count -= 1; - if (private->ref_count == 0) - { - XFreePixmap (private->xdisplay, private->xwindow); - gdk_xid_table_remove (private->xwindow); - g_free (private); - } + g_return_val_if_fail (drawable != NULL || colormap != NULL, NULL); + g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (colormap == NULL || GDK_IS_COLORMAP (colormap), NULL); + + if (colormap == NULL) + colormap = gdk_drawable_get_colormap (drawable); + + pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **)data); + if (!pixbuf) + return NULL; + + pixmap = gdk_pixmap_colormap_new_from_pixbuf (colormap, mask, transparent_color, pixbuf); + + g_object_unref (pixbuf); + + return pixmap; } -GdkBitmap * -gdk_bitmap_ref (GdkBitmap *bitmap) +/** + * gdk_pixmap_create_from_xpm_d: + * @drawable: a #GdkDrawable, used to determine default values + * for the new pixmap. + * @mask: (out): Pointer to a place to store a bitmap representing + * the transparency mask of the XPM file. Can be %NULL, + * in which case transparency will be ignored. + * @transparent_color: This color will be used for the pixels + * that are transparent in the input file. Can be %NULL + * in which case a default color will be used. + * @data: Pointer to a string containing the XPM data. + * + * Create a pixmap from data in XPM format. + * + * Returns: (transfer none): the #GdkPixmap. + */ +GdkPixmap* +gdk_pixmap_create_from_xpm_d (GdkDrawable *drawable, + GdkBitmap **mask, + const GdkColor *transparent_color, + gchar **data) { - return (GdkBitmap *)gdk_pixmap_ref ((GdkPixmap *)bitmap); + return gdk_pixmap_colormap_create_from_xpm_d (drawable, NULL, mask, + transparent_color, data); } -void -gdk_bitmap_unref (GdkBitmap *bitmap) +static GdkScreen* +gdk_pixmap_real_get_screen (GdkDrawable *drawable) { - gdk_pixmap_unref ((GdkPixmap *)bitmap); + return gdk_drawable_get_screen (GDK_PIXMAP_OBJECT (drawable)->impl); }