* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
-#include "../config.h"
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999. 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/.
+ */
+
+#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
-#include "gdk.h"
+#include "gdkpixmap.h"
#include "gdkprivate.h"
+#include "gdkx.h"
typedef struct
{
gint transparent;
} _GdkPixmapColor;
+typedef struct
+{
+ guint ncolors;
+ GdkColormap *colormap;
+ gulong pixels[1];
+} _GdkPixmapInfo;
+
+GdkDrawableClass _gdk_x11_pixmap_class;
+
+static void
+gdk_x11_pixmap_destroy (GdkPixmap *pixmap)
+{
+ XFreePixmap (GDK_DRAWABLE_XDISPLAY (pixmap), GDK_DRAWABLE_XID (pixmap));
+ gdk_xid_table_remove (GDK_DRAWABLE_XID (pixmap));
+
+ g_free (GDK_DRAWABLE_XDATA (pixmap));
+}
+
+static GdkDrawable *
+gdk_x11_pixmap_alloc (void)
+{
+ GdkDrawable *drawable;
+ GdkDrawablePrivate *private;
+
+ static GdkDrawableClass klass;
+ static gboolean initialized = FALSE;
+
+ if (!initialized)
+ {
+ initialized = TRUE;
+
+ klass = _gdk_x11_drawable_class;
+ klass.destroy = gdk_x11_pixmap_destroy;
+ }
+
+ drawable = gdk_drawable_alloc ();
+ private = (GdkDrawablePrivate *)drawable;
+
+ private->klass = &klass;
+ private->klass_data = g_new (GdkDrawableXData, 1);
+ private->window_type = GDK_DRAWABLE_PIXMAP;
+
+ return drawable;
+}
+
GdkPixmap*
gdk_pixmap_new (GdkWindow *window,
gint width,
gint depth)
{
GdkPixmap *pixmap;
- GdkWindowPrivate *private;
- GdkWindowPrivate *window_private;
+ GdkDrawablePrivate *private;
+ g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
g_return_val_if_fail ((window != NULL) || (depth != -1), NULL);
g_return_val_if_fail ((width != 0) && (height != 0), NULL);
-
+
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = gdk_parent_root;
- window_private = (GdkWindowPrivate*) window;
- if (window_private->destroyed)
+ if (GDK_DRAWABLE_DESTROYED (window))
return NULL;
if (depth == -1)
- depth = gdk_window_get_visual (window)->depth;
-
- private = g_new (GdkWindowPrivate, 1);
- pixmap = (GdkPixmap*) private;
-
- private->xdisplay = window_private->xdisplay;
- private->window_type = GDK_WINDOW_PIXMAP;
- private->xwindow = XCreatePixmap (private->xdisplay, window_private->xwindow,
- width, height, depth);
- private->colormap = NULL;
- private->parent = NULL;
- private->x = 0;
- private->y = 0;
+ depth = gdk_drawable_get_visual (window)->depth;
+
+ pixmap = gdk_x11_pixmap_alloc ();
+ private = (GdkDrawablePrivate *)pixmap;
+
+ GDK_DRAWABLE_XDATA (private)->xdisplay = GDK_DRAWABLE_XDISPLAY (window);
+ GDK_DRAWABLE_XDATA (private)->xid = XCreatePixmap (GDK_DRAWABLE_XDISPLAY (pixmap),
+ GDK_DRAWABLE_XID (window),
+ width, height, depth);
private->width = width;
private->height = height;
- private->resize_count = 0;
- private->ref_count = 1;
- private->destroyed = 0;
- gdk_xid_table_insert (&private->xwindow, pixmap);
+ gdk_xid_table_insert (&GDK_DRAWABLE_XID (pixmap), pixmap);
return pixmap;
}
GdkPixmap *
-gdk_bitmap_create_from_data (GdkWindow *window,
- gchar *data,
- gint width,
- gint height)
+gdk_bitmap_create_from_data (GdkWindow *window,
+ const gchar *data,
+ gint width,
+ gint height)
{
GdkPixmap *pixmap;
- GdkWindowPrivate *private;
- GdkWindowPrivate *window_private;
+ GdkDrawablePrivate *private;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail ((width != 0) && (height != 0), NULL);
+ g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = gdk_parent_root;
- window_private = (GdkWindowPrivate*) window;
- if (window_private->destroyed)
+ if (GDK_DRAWABLE_DESTROYED (window))
return NULL;
- private = g_new (GdkWindowPrivate, 1);
- pixmap = (GdkPixmap*) private;
+ pixmap = gdk_x11_pixmap_alloc ();
+ private = (GdkDrawablePrivate *)pixmap;
- 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);
+ GDK_DRAWABLE_XDATA (private)->xdisplay = GDK_DRAWABLE_XDISPLAY (window);
+ GDK_DRAWABLE_XDATA (private)->xid = XCreateBitmapFromData (GDK_DRAWABLE_XDISPLAY (window),
+ GDK_DRAWABLE_XID (window),
+ (char *)data, width, height);
- gdk_xid_table_insert (&private->xwindow, pixmap);
+ gdk_xid_table_insert (&GDK_DRAWABLE_XID (pixmap), pixmap);
return pixmap;
}
GdkPixmap*
-gdk_pixmap_create_from_data (GdkWindow *window,
- gchar *data,
- gint width,
- gint height,
- gint depth,
- GdkColor *fg,
- GdkColor *bg)
+gdk_pixmap_create_from_data (GdkWindow *window,
+ const gchar *data,
+ gint width,
+ gint height,
+ gint depth,
+ GdkColor *fg,
+ GdkColor *bg)
{
GdkPixmap *pixmap;
- GdkWindowPrivate *private;
- GdkWindowPrivate *window_private;
+ GdkDrawablePrivate *private;
+ g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (fg != NULL, NULL);
g_return_val_if_fail (bg != NULL, NULL);
g_return_val_if_fail ((width != 0) && (height != 0), NULL);
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = gdk_parent_root;
- window_private = (GdkWindowPrivate*) window;
- if (window_private->destroyed)
+ if (GDK_DRAWABLE_DESTROYED (window))
return NULL;
if (depth == -1)
- depth = gdk_window_get_visual (window)->depth;
+ depth = gdk_drawable_get_visual (window)->depth;
- private = g_new (GdkWindowPrivate, 1);
- pixmap = (GdkPixmap*) private;
+ pixmap = gdk_x11_pixmap_alloc ();
+ private = (GdkDrawablePrivate *)pixmap;
- 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 = XCreatePixmapFromBitmapData (private->xdisplay,
- window_private->xwindow,
- data, width, height,
- fg->pixel, bg->pixel, depth);
+ GDK_DRAWABLE_XDATA (private)->xdisplay = GDK_DRAWABLE_XDISPLAY (window);
+ GDK_DRAWABLE_XDATA (private)->xid = XCreatePixmapFromBitmapData (GDK_DRAWABLE_XDISPLAY (window),
+ GDK_DRAWABLE_XID (window),
+ (char *)data, width, height,
+ fg->pixel, bg->pixel, depth);
- gdk_xid_table_insert (&private->xwindow, pixmap);
+ gdk_xid_table_insert (&GDK_DRAWABLE_XID (pixmap), pixmap);
return pixmap;
}
{
char instr[1024];
- while (!feof (infile))
+ while (1)
{
- fscanf (infile, "%1023s", instr);
+ if (fscanf (infile, "%1023s", instr) != 1)
+ return FALSE;
+
if (skip_comments == TRUE && strcmp (instr, "/*") == 0)
{
- fscanf (infile, "%1023s", instr);
- while (!feof (infile) && strcmp (instr, "*/") != 0)
- fscanf (infile, "%1023s", instr);
- fscanf(infile, "%1023s", instr);
+ do
+ {
+ if (fscanf (infile, "%1023s", instr) != 1)
+ return FALSE;
+ }
+ while (strcmp (instr, "*/") != 0);
}
- if (strcmp (instr, str)==0)
+ else if (strcmp (instr, str) == 0)
return TRUE;
}
-
- return FALSE;
}
static gint
return retcol;
}
-static void
-free_color (gpointer key, gpointer value, gpointer user_data)
-{
- g_free (key);
- g_free (value);
-}
-
enum buffer_op
{
op_body
};
+
+static void
+gdk_xpm_destroy_notify (gpointer data)
+{
+ _GdkPixmapInfo *info = (_GdkPixmapInfo *)data;
+ GdkColor color;
+ int i;
+
+ for (i=0; i<info->ncolors; i++)
+ {
+ color.pixel = info->pixels[i];
+ gdk_colormap_free_colors (info->colormap, &color, 1);
+ }
+
+ gdk_colormap_unref (info->colormap);
+ g_free (info);
+}
static GdkPixmap *
_gdk_pixmap_create_from_xpm (GdkWindow *window,
GdkColor tmp_color;
gint width, height, num_cols, cpp, n, ns, cnt, xcnt, ycnt, wbytes;
gchar *buffer, pixel_str[32];
+ gchar *name_buf;
_GdkPixmapColor *color = NULL, *fallbackcolor = NULL;
+ _GdkPixmapColor *colors = NULL;
gulong index;
- GHashTable *colors = NULL;
+ GHashTable *color_hash = NULL;
+ _GdkPixmapInfo *color_info = NULL;
if ((window == NULL) && (colormap == NULL))
g_warning ("Creating pixmap from xpm with NULL window and colormap");
if (window == NULL)
- window = (GdkWindow *)&gdk_root_parent;
+ window = gdk_parent_root;
if (colormap == NULL)
{
- colormap = gdk_window_get_colormap (window);
- visual = gdk_window_get_visual (window);
+ colormap = gdk_drawable_get_colormap (window);
+ visual = gdk_drawable_get_visual (window);
}
else
visual = ((GdkColormapPrivate *)colormap)->visual;
return NULL;
}
- colors = g_hash_table_new (g_str_hash, g_str_equal);
+ color_hash = g_hash_table_new (g_str_hash, g_str_equal);
if (transparent_color == NULL)
{
gdk_color_white (colormap, &tmp_color);
transparent_color = &tmp_color;
}
-
+
+ /* For pseudo-color and grayscale visuals, we have to remember
+ * the colors we allocated, so we can free them later.
+ */
+ if ((visual->type == GDK_VISUAL_PSEUDO_COLOR) ||
+ (visual->type == GDK_VISUAL_GRAYSCALE))
+ {
+ color_info = g_malloc (sizeof (_GdkPixmapInfo) +
+ sizeof(gulong) * (num_cols - 1));
+ color_info->ncolors = num_cols;
+ color_info->colormap = colormap;
+ gdk_colormap_ref (colormap);
+ }
+
+ name_buf = g_new (gchar, num_cols * (cpp+1));
+ colors = g_new (_GdkPixmapColor, num_cols);
+
for (cnt = 0; cnt < num_cols; cnt++)
{
gchar *color_name;
if (buffer == NULL)
goto error;
- color = g_new (_GdkPixmapColor, 1);
- color->color_string = g_new (gchar, cpp + 1);
+ color = &colors[cnt];
+ color->color_string = &name_buf [cnt * (cpp + 1)];
strncpy (color->color_string, buffer, cpp);
color->color_string[cpp] = 0;
buffer += strlen (color->color_string);
color_name = gdk_pixmap_extract_color (buffer);
- if (color_name == NULL ||
+ if (color_name == NULL || g_strcasecmp (color_name, "None") == 0 ||
gdk_color_parse (color_name, &color->color) == FALSE)
{
color->color = *transparent_color;
/* FIXME: The remaining slowness appears to happen in this
function. */
gdk_color_alloc (colormap, &color->color);
- g_hash_table_insert (colors, color->color_string, color);
+
+ if (color_info)
+ color_info->pixels[cnt] = color->color.pixel;
+
+ g_hash_table_insert (color_hash, color->color_string, color);
if (cnt == 0)
fallbackcolor = color;
}
pixel_str[cpp] = 0;
ns = 0;
- color = g_hash_table_lookup (colors, pixel_str);
+ color = g_hash_table_lookup (color_hash, pixel_str);
if (!color) /* screwed up XPM file */
color = fallbackcolor;
error:
if (mask)
- gdk_gc_destroy (gc);
+ gdk_gc_unref (gc);
if (image != NULL)
{
pixmap = gdk_pixmap_new (window, width, height, visual->depth);
+
+ if (color_info)
+ gdk_drawable_set_data (pixmap, "gdk-xpm", color_info,
+ gdk_xpm_destroy_notify);
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);
+ gdk_gc_unref (gc);
+ gdk_image_unref (image);
}
+ else if (color_info)
+ gdk_xpm_destroy_notify (color_info);
+ if (color_hash != NULL)
+ g_hash_table_destroy (color_hash);
+
if (colors != NULL)
- {
- g_hash_table_foreach (colors, free_color, 0);
- g_hash_table_destroy (colors);
- }
-
+ g_free (colors);
+
+ if (name_buf != NULL)
+ g_free (name_buf);
+
return pixmap;
}
}
GdkPixmap*
-gdk_pixmap_ref (GdkPixmap *pixmap)
-{
- GdkWindowPrivate *private = (GdkWindowPrivate *)pixmap;
- g_return_val_if_fail (pixmap != NULL, NULL);
-
- private->ref_count += 1;
- return pixmap;
-}
-
-void
-gdk_pixmap_unref (GdkPixmap *pixmap)
+gdk_pixmap_foreign_new (guint32 anid)
{
- GdkWindowPrivate *private = (GdkWindowPrivate *)pixmap;
- g_return_if_fail(pixmap != NULL);
+ GdkPixmap *pixmap;
+ GdkDrawablePrivate *private;
+ Pixmap xpixmap;
+ Window root_return;
+ unsigned int x_ret, y_ret, w_ret, h_ret, bw_ret, depth_ret;
+
+ /* check to make sure we were passed something at
+ least a little sane */
+ g_return_val_if_fail((anid != 0), NULL);
+
+ /* set the pixmap to the passed in value */
+ xpixmap = anid;
+
+ /* get information about the Pixmap to fill in the structure for
+ the gdk window */
+ if (!XGetGeometry(GDK_DISPLAY(),
+ xpixmap, &root_return,
+ &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
+ return NULL;
+
+ pixmap = gdk_x11_pixmap_alloc ();
+ private = (GdkDrawablePrivate *)pixmap;
- private->ref_count -= 1;
- if (private->ref_count == 0)
- {
- XFreePixmap (private->xdisplay, private->xwindow);
- gdk_xid_table_remove (private->xwindow);
- g_free (private);
- }
-}
+ GDK_DRAWABLE_XDATA (private)->xdisplay = GDK_DISPLAY ();
+ GDK_DRAWABLE_XDATA (private)->xid = xpixmap;
-GdkBitmap *
-gdk_bitmap_ref (GdkBitmap *bitmap)
-{
- return (GdkBitmap *)gdk_pixmap_ref ((GdkPixmap *)bitmap);
-}
+ private->width = w_ret;
+ private->height = h_ret;
+
+ gdk_xid_table_insert(&GDK_DRAWABLE_XID (pixmap), pixmap);
-void
-gdk_bitmap_unref (GdkBitmap *bitmap)
-{
- gdk_pixmap_unref ((GdkPixmap *)bitmap);
+ return pixmap;
}