summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--configure.in4
-rw-r--r--gdk-2.0.pc.in12
-rw-r--r--gdk-pixbuf.pc.in11
-rw-r--r--gdk-pixbuf/ChangeLog23
-rw-r--r--gdk-pixbuf/Makefile.am6
-rw-r--r--gdk-pixbuf/gdk-pixbuf-data.c174
-rw-r--r--gdk-pixbuf/gdk-pixbuf-private.h10
-rw-r--r--gdk-pixbuf/gdk-pixbuf-util.c99
-rw-r--r--gdk-pixbuf/gdk-pixbuf.h16
-rw-r--r--gdk-pixbuf/make-inline-pixbuf.c213
-rw-r--r--gtk+-2.0.pc.in12
-rw-r--r--gtk/Makefile.am16
-rw-r--r--gtk/gtk.h2
-rw-r--r--gtk/gtkbutton.c93
-rw-r--r--gtk/gtkbutton.h6
-rw-r--r--gtk/gtkiconfactory.c1127
-rw-r--r--gtk/gtkiconfactory.h159
-rw-r--r--gtk/gtkimage.c663
-rw-r--r--gtk/gtkimage.h108
-rw-r--r--gtk/gtkrc.c368
-rw-r--r--gtk/gtkrc.h10
-rw-r--r--gtk/gtkstock.c198
-rw-r--r--gtk/gtkstock.h89
-rw-r--r--gtk/gtkstyle.c298
-rw-r--r--gtk/gtkstyle.h25
-rw-r--r--gtk/gtkwidget.c32
-rw-r--r--gtk/gtkwidget.h5
-rw-r--r--gtk/stock-icons/Makefile.am23
-rw-r--r--gtk/stock-icons/dialog_error.pngbin0 -> 2684 bytes
-rw-r--r--gtk/stock-icons/dialog_error_48.pngbin0 -> 2684 bytes
-rw-r--r--gtk/stock-icons/dialog_info.pngbin0 -> 3504 bytes
-rw-r--r--gtk/stock-icons/dialog_info_48.pngbin0 -> 3504 bytes
-rw-r--r--gtk/stock-icons/dialog_question.pngbin0 -> 1302 bytes
-rw-r--r--gtk/stock-icons/dialog_question_48.pngbin0 -> 1302 bytes
-rw-r--r--gtk/stock-icons/dialog_warning.pngbin0 -> 1968 bytes
-rw-r--r--gtk/stock-icons/dialog_warning_48.pngbin0 -> 1968 bytes
-rw-r--r--gtk/stock-icons/stock_apply_20.pngbin0 -> 452 bytes
-rw-r--r--gtk/stock-icons/stock_button_apply.pngbin0 -> 452 bytes
-rw-r--r--gtk/stock-icons/stock_button_apply_24.pngbin0 -> 452 bytes
-rw-r--r--gtk/stock-icons/stock_button_cancel.pngbin0 -> 454 bytes
-rw-r--r--gtk/stock-icons/stock_button_cancel_24.pngbin0 -> 454 bytes
-rw-r--r--gtk/stock-icons/stock_button_close.pngbin0 -> 286 bytes
-rw-r--r--gtk/stock-icons/stock_button_close_24.pngbin0 -> 286 bytes
-rw-r--r--gtk/stock-icons/stock_button_no.pngbin0 -> 847 bytes
-rw-r--r--gtk/stock-icons/stock_button_no_24.pngbin0 -> 847 bytes
-rw-r--r--gtk/stock-icons/stock_button_ok.pngbin0 -> 661 bytes
-rw-r--r--gtk/stock-icons/stock_button_ok_24.pngbin0 -> 661 bytes
-rw-r--r--gtk/stock-icons/stock_button_yes.pngbin0 -> 806 bytes
-rw-r--r--gtk/stock-icons/stock_button_yes_24.pngbin0 -> 806 bytes
-rw-r--r--gtk/stock-icons/stock_cancel_20.pngbin0 -> 454 bytes
-rw-r--r--gtk/stock-icons/stock_close.pngbin0 -> 290 bytes
-rw-r--r--gtk/stock-icons/stock_close_20.pngbin0 -> 286 bytes
-rw-r--r--gtk/stock-icons/stock_close_24.pngbin0 -> 290 bytes
-rw-r--r--gtk/stock-icons/stock_dialog_error_48.pngbin0 -> 2684 bytes
-rw-r--r--gtk/stock-icons/stock_dialog_info_48.pngbin0 -> 3504 bytes
-rw-r--r--gtk/stock-icons/stock_dialog_question_48.pngbin0 -> 1302 bytes
-rw-r--r--gtk/stock-icons/stock_dialog_warning_48.pngbin0 -> 1968 bytes
-rw-r--r--gtk/stock-icons/stock_exit.pngbin0 -> 413 bytes
-rw-r--r--gtk/stock-icons/stock_exit_24.pngbin0 -> 413 bytes
-rw-r--r--gtk/stock-icons/stock_help.pngbin0 -> 480 bytes
-rw-r--r--gtk/stock-icons/stock_help_24.pngbin0 -> 480 bytes
-rw-r--r--gtk/stock-icons/stock_new.pngbin0 -> 771 bytes
-rw-r--r--gtk/stock-icons/stock_new_24.pngbin0 -> 771 bytes
-rw-r--r--gtk/stock-icons/stock_no_20.pngbin0 -> 847 bytes
-rw-r--r--gtk/stock-icons/stock_ok_20.pngbin0 -> 661 bytes
-rw-r--r--gtk/stock-icons/stock_open.pngbin0 -> 393 bytes
-rw-r--r--gtk/stock-icons/stock_open_24.pngbin0 -> 393 bytes
-rw-r--r--gtk/stock-icons/stock_save.pngbin0 -> 849 bytes
-rw-r--r--gtk/stock-icons/stock_save_24.pngbin0 -> 849 bytes
-rw-r--r--gtk/stock-icons/stock_yes_20.pngbin0 -> 806 bytes
71 files changed, 3661 insertions, 144 deletions
diff --git a/Makefile.am b/Makefile.am
index fbab5ecd6..0b42c1c0e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -112,6 +112,9 @@ EXTRA_DIST = \
examples/spinbutton/Makefile \
examples/find-examples.sh
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA= gdk-pixbuf.pc gdk-2.0.pc gtk+-2.0.pc
+
dist-hook: gtk+.spec
if test -e $(srcdir)/INSTALL.in && test -e $(srcdir)/README.in ; then \
CONFIG_FILES="INSTALL:$(srcdir)/INSTALL.in README:$(srcdir)/README.in" \
diff --git a/configure.in b/configure.in
index d33a4fe30..5b1dca127 100644
--- a/configure.in
+++ b/configure.in
@@ -1005,6 +1005,9 @@ gtk+.spec
docs/gtk-config.1
Makefile
gtk-config-2.0
+gdk-pixbuf.pc
+gdk-2.0.pc
+gtk+-2.0.pc
po/Makefile.in
build/Makefile
build/win32/Makefile
@@ -1031,6 +1034,7 @@ gdk/linux-fb/Makefile
gtk/Makefile
gtk/makefile.mingw
gtk/gtkcompat.h
+gtk/stock-icons/Makefile
modules/Makefile
modules/linux-fb/Makefile
], [chmod +x gtk-config-2.0])
diff --git a/gdk-2.0.pc.in b/gdk-2.0.pc.in
new file mode 100644
index 000000000..0dc03329c
--- /dev/null
+++ b/gdk-2.0.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+target=@gdktarget@
+
+Name: GDK
+Description: GIMP Drawing Kit
+Version: @VERSION@
+Requires: gdk-pixbuf,pangox
+Libs: -L${libdir} @more_ldflags@ -lgdk-${target}-1.3 @more_libs@ @GDK_WLIBS@
+Cflags: -I${includedir}/gtk-2.0 -I${libdir}/gtk-2.0/include @more_cflags@
diff --git a/gdk-pixbuf.pc.in b/gdk-pixbuf.pc.in
new file mode 100644
index 000000000..96afc3d31
--- /dev/null
+++ b/gdk-pixbuf.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: GdkPixbuf
+Description: Image loading and scaling
+Version: @VERSION@
+Requires: gobject-2.0,gmodule-2.0
+Libs: -L${libdir} -lgdk_pixbuf-1.3 @INTLLIBS@ @MATH_LIB@
+Cflags: -I${includedir}
diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog
index e8bb33219..8a85fb836 100644
--- a/gdk-pixbuf/ChangeLog
+++ b/gdk-pixbuf/ChangeLog
@@ -1,3 +1,23 @@
+2000-09-26 Havoc Pennington <hp@redhat.com>
+
+ * gdk-pixbuf-util.c (gdk_pixbuf_saturate_and_pixelate): Add this
+ function here, instead of putting it in a private GTK+ file.
+
+ * gdk-pixbuf-private.h (GdkPixbufInlineFormat): include an
+ enum here for the known formats of inlined pixbufs.
+ Also, #define our file magic here.
+
+2000-06-23 Havoc Pennington <hp@redhat.com>
+
+ * make-inline-pixbuf.c: Small program that creates C variable
+ declarations of inline pixbuf data. This can be read
+ by gdk_pixbuf_new_from_inline.
+
+ * gdk-pixbuf.h (gdk_pixbuf_new_from_inline): New function to read
+ inline pixbuf data and create a pixbuf from it.
+
+ * gdk-pixbuf-data.c (gdk_pixbuf_new_from_inline): implement here
+
2000-09-07 Tor Lillqvist <tml@iki.fi>
* makefile.mingw.in: Use own version number for gdk-pixbuf DLLs,
@@ -27,6 +47,7 @@
* io-wbmp.c: Some bug fixes - now tested to work.
2000-07-27 Elliot Lee <sopwith@redhat.com>
+
* gdk-pixbuf-io.h, gdk-pixbuf-io.c: Add gdk_pixbuf_get_named_module() function to facilitate above change
* io-wbmp.c, pixbufloader_wbmp.defs, gdk-pixbuf-io.c, Makefile: Implement loader for WBMP format.
* io-bmp.c: Don't malloc a temporary buffer - use stack instead.
@@ -91,7 +112,7 @@ Thu Jul 6 11:49:47 2000 Owen Taylor <otaylor@redhat.com>
* Makefile.am (libgdk_pixbuf_la_LDFLAGS): Use GTK+ version
soname scheme for gdk-pixbuf.
-
+
2000-06-21 Havoc Pennington <hp@pobox.com>
* gdk-pixbuf.c: Convert GdkPixbuf to GObject, leaving it opaque
diff --git a/gdk-pixbuf/Makefile.am b/gdk-pixbuf/Makefile.am
index 4628de1cc..2247e657e 100644
--- a/gdk-pixbuf/Makefile.am
+++ b/gdk-pixbuf/Makefile.am
@@ -148,6 +148,12 @@ LDADDS = libgdk_pixbuf-1.3.la $(GLIB_LIBS) $(STATIC_LIB_DEPS)
test_gdk_pixbuf_LDADD = $(LDADDS)
+bin_PROGRAMS=make-inline-pixbuf
+
+make_inline_pixbuf_SOURCES=make-inline-pixbuf.c
+
+make_inline_pixbuf_LDADD = $(LDADDS)
+
GDK_PIXBUF_LIBS = $(GLIB_LIBS)
#
diff --git a/gdk-pixbuf/gdk-pixbuf-data.c b/gdk-pixbuf/gdk-pixbuf-data.c
index 62634d214..94db20f37 100644
--- a/gdk-pixbuf/gdk-pixbuf-data.c
+++ b/gdk-pixbuf/gdk-pixbuf-data.c
@@ -23,6 +23,8 @@
#include <config.h>
#include "gdk-pixbuf.h"
#include "gdk-pixbuf-private.h"
+#include <stdlib.h>
+#include <string.h>
@@ -75,3 +77,175 @@ gdk_pixbuf_new_from_data (const guchar *data, GdkColorspace colorspace, gboolean
return pixbuf;
}
+
+static guint32
+read_int (const guchar **p)
+{
+ guint32 num;
+
+ /* Note most significant bytes are first in the byte stream */
+ num =
+ (*p)[3] |
+ ((*p)[2] << 8) |
+ ((*p)[1] << 16) |
+ ((*p)[0] << 24);
+
+ *p += 4;
+
+ return num;
+}
+
+static gboolean
+read_bool (const guchar **p)
+{
+ gboolean val = **p != 0;
+
+ ++(*p);
+
+ return val;
+}
+
+static GdkPixbuf*
+read_raw_inline (const guchar *data, gboolean copy_pixels, int length)
+{
+ GdkPixbuf *pixbuf;
+ const guchar *p = data;
+ guint32 rowstride, width, height, colorspace,
+ n_channels, bits_per_sample;
+ gboolean has_alpha;
+
+ if (length >= 0 && length < 12) {
+ /* Not enough buffer to hold the width/height/rowstride */
+ return NULL;
+ }
+
+ rowstride = read_int (&p);
+ width = read_int (&p);
+ height = read_int (&p);
+
+ if (rowstride < width)
+ return NULL; /* bad data from untrusted source. */
+
+ /* rowstride >= width, so we can trust width */
+
+ length -= 12;
+
+ /* There's some better way like G_MAXINT/height > rowstride
+ * but I'm not sure it works, so stick to this for now.
+ */
+ if (((double)height) * ((double)rowstride) > (double)G_MAXINT)
+ return NULL; /* overflow */
+
+ if (length >= 0 &&
+ length < (height * rowstride + 13)) {
+ /* Not enough buffer to hold the remaining header
+ * information plus the data.
+ */
+
+ return NULL;
+ }
+
+ /* Read the remaining 13 bytes of header information */
+
+ has_alpha = read_bool (&p) != FALSE;
+ colorspace = read_int (&p);
+ n_channels = read_int (&p);
+ bits_per_sample = read_int (&p);
+
+ if (colorspace != GDK_COLORSPACE_RGB)
+ return NULL;
+
+ if (bits_per_sample != 8)
+ return NULL;
+
+ if (has_alpha && n_channels != 4)
+ return NULL;
+
+ if (!has_alpha && n_channels != 3)
+ return NULL;
+
+ if (copy_pixels) {
+ guchar *pixels;
+ gint dest_rowstride;
+ gint row;
+
+ pixbuf = gdk_pixbuf_new (colorspace,
+ has_alpha, bits_per_sample,
+ width, height);
+
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+ dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ for (row = 0; row < height; row++) {
+ memcpy (pixels, p, rowstride);
+ pixels += dest_rowstride;
+ p += rowstride;
+ }
+ } else {
+ pixbuf = gdk_pixbuf_new_from_data (p,
+ colorspace,
+ has_alpha,
+ bits_per_sample,
+ width, height,
+ rowstride,
+ NULL, NULL);
+ }
+
+ return pixbuf;
+}
+
+/**
+ * gdk_pixbuf_new_from_inline:
+ * @data: An inlined GdkPixbuf
+ * @copy_pixels: whether to copy the pixels out of the inline data, or to use them in-place
+ *
+ * Create a #GdkPixbuf from a custom format invented to store pixbuf
+ * data in C program code. This library comes with a program called "make-inline-pixbuf"
+ * that can write out a variable definition containing an inlined pixbuf.
+ * This is useful if you want to ship a program with images, but
+ * don't want to depend on any external files.
+ *
+ * The inline data format contains the pixels in #GdkPixbuf's native
+ * format. Since the inline pixbuf is read-only static data, you
+ * don't need to copy it unless you intend to write to it.
+ *
+ * Return value: A newly-created #GdkPixbuf structure with a reference count of
+ * 1.
+ **/
+GdkPixbuf*
+gdk_pixbuf_new_from_inline (const guchar *inline_pixbuf,
+ gboolean copy_pixels,
+ int length)
+{
+ const guchar *p;
+ GdkPixbuf *pixbuf;
+ GdkPixbufInlineFormat format;
+
+ if (length >= 0 && length < 8) {
+ /* not enough bytes to contain even the magic number
+ * and format code.
+ */
+ return NULL;
+ }
+
+ p = inline_pixbuf;
+
+ if (read_int (&p) != GDK_PIXBUF_INLINE_MAGIC_NUMBER) {
+ return NULL;
+ }
+
+ format = read_int (&p);
+
+ switch (format)
+ {
+ case GDK_PIXBUF_INLINE_RAW:
+ pixbuf = read_raw_inline (p, copy_pixels, length - 8);
+ break;
+
+ default:
+ return NULL;
+ }
+
+ return pixbuf;
+}
+
diff --git a/gdk-pixbuf/gdk-pixbuf-private.h b/gdk-pixbuf/gdk-pixbuf-private.h
index 1b14e3ccc..e8eb7248a 100644
--- a/gdk-pixbuf/gdk-pixbuf-private.h
+++ b/gdk-pixbuf/gdk-pixbuf-private.h
@@ -117,4 +117,14 @@ struct _GdkPixbufAnimationClass {
+#define GDK_PIXBUF_INLINE_MAGIC_NUMBER 0x47646B50 /* 'GdkP' */
+
+typedef enum
+{
+ GDK_PIXBUF_INLINE_RAW = 0,
+ GDK_PIXBUF_INLINE_RLE = 1
+} GdkPixbufInlineFormat;
+
+
+
#endif
diff --git a/gdk-pixbuf/gdk-pixbuf-util.c b/gdk-pixbuf/gdk-pixbuf-util.c
index 848aadd14..db8ca758e 100644
--- a/gdk-pixbuf/gdk-pixbuf-util.c
+++ b/gdk-pixbuf/gdk-pixbuf-util.c
@@ -131,3 +131,102 @@ gdk_pixbuf_copy_area (const GdkPixbuf *src_pixbuf,
1.0, 1.0,
GDK_INTERP_NEAREST);
}
+
+
+
+#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
+
+/**
+ * gdk_pixbuf_saturate_and_pixelate:
+ * @src: source image
+ * @dest: place to write modified version of @src
+ * @saturation: saturation factor
+ * @pixelate: whether to pixelate
+ *
+ * Modifies saturation and optionally pixelates @src, placing the
+ * result in @dest. @src and @dest may be the same pixbuf with no ill
+ * effects. If @saturation is 1.0 then saturation is not changed. If
+ * it's less than 1.0, saturation is reduced (the image is darkened);
+ * if greater than 1.0, saturation is increased (the image is
+ * brightened). If @pixelate is TRUE, then pixels are faded in a
+ * checkerboard pattern to create a pixelated image. @src and @dest
+ * must have the same image format, size, and rowstride.
+ *
+ **/
+void
+gdk_pixbuf_saturate_and_pixelate(const GdkPixbuf *src,
+ GdkPixbuf *dest,
+ gfloat saturation,
+ gboolean pixelate)
+{
+ /* NOTE that src and dest MAY be the same pixbuf! */
+
+ g_return_if_fail (GDK_IS_PIXBUF (src));
+ g_return_if_fail (GDK_IS_PIXBUF (dest));
+ g_return_if_fail (gdk_pixbuf_get_height (src) == gdk_pixbuf_get_height (dest));
+ g_return_if_fail (gdk_pixbuf_get_width (src) == gdk_pixbuf_get_width (dest));
+ g_return_if_fail (gdk_pixbuf_get_rowstride (src) == gdk_pixbuf_get_rowstride (dest));
+ g_return_if_fail (gdk_pixbuf_get_colorspace (src) == gdk_pixbuf_get_colorspace (dest));
+
+ if (saturation == 1.0 && !pixelate) {
+ if (dest != src)
+ memcpy (gdk_pixbuf_get_pixels (dest),
+ gdk_pixbuf_get_pixels (src),
+ gdk_pixbuf_get_height (src) * gdk_pixbuf_get_rowstride (src));
+
+ return;
+ } else {
+ gint i, j;
+ gint width, height, has_alpha, rowstride;
+ guchar *target_pixels;
+ guchar *original_pixels;
+ guchar *current_pixel;
+ guchar intensity;
+
+ has_alpha = gdk_pixbuf_get_has_alpha (src);
+ width = gdk_pixbuf_get_width (src);
+ height = gdk_pixbuf_get_height (src);
+ rowstride = gdk_pixbuf_get_rowstride (src);
+
+ target_pixels = gdk_pixbuf_get_pixels (dest);
+ original_pixels = gdk_pixbuf_get_pixels (src);
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ current_pixel = original_pixels + i*rowstride + j*(has_alpha?4:3);
+ intensity = INTENSITY (*(current_pixel), *(current_pixel + 1), *(current_pixel + 2));
+ if (pixelate && (i+j)%2 == 0) {
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3)) = intensity/2 + 127;
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 1) = intensity/2 + 127;
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 2) = intensity/2 + 127;
+ } else if (pixelate) {
+#define DARK_FACTOR 0.7
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3)) =
+ (guchar) (((1.0 - saturation) * intensity
+ + saturation * (*(current_pixel)))) * DARK_FACTOR;
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 1) =
+ (guchar) (((1.0 - saturation) * intensity
+ + saturation * (*(current_pixel + 1)))) * DARK_FACTOR;
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 2) =
+ (guchar) (((1.0 - saturation) * intensity
+ + saturation * (*(current_pixel + 2)))) * DARK_FACTOR;
+ } else {
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3)) =
+ (guchar) ((1.0 - saturation) * intensity
+ + saturation * (*(current_pixel)));
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 1) =
+ (guchar) ((1.0 - saturation) * intensity
+ + saturation * (*(current_pixel + 1)));
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 2) =
+ (guchar) ((1.0 - saturation) * intensity
+ + saturation * (*(current_pixel + 2)));
+ }
+
+ if (has_alpha)
+ *(target_pixels + i*rowstride + j*(has_alpha?4:3) + 3) = *(current_pixel + 3);
+ }
+ }
+
+ return;
+ }
+}
diff --git a/gdk-pixbuf/gdk-pixbuf.h b/gdk-pixbuf/gdk-pixbuf.h
index a7074fd50..aaaad7fda 100644
--- a/gdk-pixbuf/gdk-pixbuf.h
+++ b/gdk-pixbuf/gdk-pixbuf.h
@@ -36,7 +36,10 @@ extern "C" {
-/* Color spaces; right now only RGB is supported */
+/* Color spaces; right now only RGB is supported.
+ * Note that these values are encoded in inline pixbufs
+ * as ints, so don't reorder them
+ */
typedef enum {
GDK_COLORSPACE_RGB
} GdkColorspace;
@@ -103,6 +106,11 @@ GdkPixbuf *gdk_pixbuf_new_from_data (const guchar *data,
GdkPixbuf *gdk_pixbuf_new_from_xpm_data (const char **data);
+/* Read an inline pixbuf */
+GdkPixbuf *gdk_pixbuf_new_from_inline (const guchar *inline_pixbuf,
+ gboolean copy_pixels,
+ int length);
+
/* Adding an alpha channel */
GdkPixbuf *gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf, gboolean substitute_color,
guchar r, guchar g, guchar b);
@@ -114,6 +122,12 @@ void gdk_pixbuf_copy_area (const GdkPixbuf *src_pixbuf,
GdkPixbuf *dest_pixbuf,
int dest_x, int dest_y);
+/* Brighten/darken and optionally make it pixelated-looking */
+void gdk_pixbuf_saturate_and_pixelate (const GdkPixbuf *src,
+ GdkPixbuf *dest,
+ gfloat saturation,
+ gboolean pixelate);
+
/* Rendering to a drawable */
diff --git a/gdk-pixbuf/make-inline-pixbuf.c b/gdk-pixbuf/make-inline-pixbuf.c
new file mode 100644
index 000000000..daf0a7e20
--- /dev/null
+++ b/gdk-pixbuf/make-inline-pixbuf.c
@@ -0,0 +1,213 @@
+/* Program to convert an image file to inline C data
+ *
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * Developed by Havoc Pennington <hp@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "gdk-pixbuf-private.h"
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+void
+output_int (FILE *outfile, guint32 num, const char *comment)
+{
+ guchar bytes[4];
+
+ /* Note, most significant bytes first */
+ bytes[0] = num >> 24;
+ bytes[1] = num >> 16;
+ bytes[2] = num >> 8;
+ bytes[3] = num;
+
+ fprintf(outfile, " /* %s (%u) */\n 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,\n",
+ comment, num,
+ bytes[0], bytes[1], bytes[2], bytes[3]);
+}
+
+void
+output_bool (FILE *outfile, gboolean val, const char *comment)
+{
+ fprintf(outfile, " /* %s (%s) */\n 0x%.2x,\n",
+ comment,
+ val ? "TRUE" : "FALSE",
+ val ? 1 : 0);
+}
+
+void
+output_pixbuf (FILE *outfile, gboolean ext_symbols,
+ const char *varname,
+ GdkPixbuf *pixbuf)
+{
+ const char *modifier;
+ const guchar *p;
+ const guchar *end;
+ gboolean has_alpha;
+ int column;
+
+ modifier = "static ";
+ if (ext_symbols)
+ modifier = "";
+
+ fprintf (outfile, "%sconst guchar ", modifier);
+ fputs (varname, outfile);
+ fputs ("[] =\n", outfile);
+ fputs ("{\n", outfile);
+
+ p = gdk_pixbuf_get_pixels (pixbuf);
+ end = p + gdk_pixbuf_get_rowstride (pixbuf) * gdk_pixbuf_get_height (pixbuf);
+ has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+
+ /* Sync the order of writing with the order of reading in
+ * gdk-pixbuf-data.c
+ */
+ output_int (outfile, GDK_PIXBUF_INLINE_MAGIC_NUMBER, "File magic");
+ output_int (outfile, GDK_PIXBUF_INLINE_RAW, "Format of following stuff");
+ output_int (outfile, gdk_pixbuf_get_rowstride (pixbuf), "Rowstride");
+ output_int (outfile, gdk_pixbuf_get_width (pixbuf), "Width");
+ output_int (outfile, gdk_pixbuf_get_height (pixbuf), "Height");
+
+ output_bool (outfile, has_alpha, "Has an alpha channel");
+
+ output_int (outfile, gdk_pixbuf_get_colorspace (pixbuf), "Colorspace (0 == RGB, no other options implemented)");
+
+ output_int (outfile, gdk_pixbuf_get_n_channels (pixbuf), "Number of channels");
+
+ output_int (outfile, gdk_pixbuf_get_bits_per_sample (pixbuf), "Bits per sample");
+
+ fputs (" /* Image data */\n", outfile);
+
+ /* Copy the data in the pixbuf */
+ column = 0;
+ while (p != end)
+ {
+ guchar r, g, b, a;
+
+ r = *p;
+ ++p;
+ g = *p;
+ ++p;
+ b = *p;
+ ++p;
+ if (has_alpha)
+ {
+ a = *p;
+ ++p;
+ }
+ else
+ a = 0;
+
+
+ if (has_alpha)
+ fprintf(outfile, " 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x", r, g, b, a);
+ else
+ fprintf(outfile, " 0x%.2x, 0x%.2x, 0x%.2x", r, g, b);
+
+ if (p != end)
+ fputs (",", outfile);
+ else
+ fputs ("\n", outfile);
+
+ ++column;
+
+ if (column > 2)
+ {
+ fputs ("\n", outfile);
+ column = 0;
+ }
+ }
+
+ fputs ("};\n\n", outfile);
+}
+
+void
+usage (void)
+{
+ fprintf (stderr, "Usage: make-inline-pixbuf [--extern-symbols] OUTFILE varname1 imagefile1 varname2 imagefile2 ...\n");
+ exit (1);
+}
+
+int
+main (int argc, char **argv)
+{
+ gboolean ext_symbols = FALSE;
+ FILE *outfile;
+ int i;
+
+ gdk_pixbuf_init ();
+
+ if (argc < 4)
+ usage ();
+
+ i = 1;
+ if (strcmp (argv[i], "--extern-symbols") == 0)
+ {
+ ext_symbols = TRUE;
+ ++i;
+ if (argc < 5)
+ usage ();
+ }
+
+ outfile = fopen (argv[i], "w");
+ if (outfile == NULL)
+ {
+ fprintf (stderr, "Failed to open output file `%s': %s\n",
+ argv[i], strerror (errno));
+ exit (1);
+ }
+
+ ++i;
+
+ fputs ("/* This file was automatically generated by the make-inline-pixbuf program.\n"
+ " * It contains inline RGB image data.\n"
+ " */\n\n", outfile);
+
+ /* Check for matched pairs of images/names */
+ if (((argc - i) % 2) != 0)
+ usage ();
+
+ while (i < argc)
+ {
+ GdkPixbuf *pixbuf;
+
+ g_assert ((i + 1) < argc);
+
+ pixbuf = gdk_pixbuf_new_from_file (argv[i+1]);
+
+ if (pixbuf == NULL)
+ {
+ fprintf (stderr, "Failed to open image file `%s': %s\n",
+ argv[i+1], strerror (errno));
+
+ exit (1);
+ }
+
+ output_pixbuf (outfile, ext_symbols, argv[i], pixbuf);
+
+ gdk_pixbuf_unref (pixbuf);
+
+ i += 2;
+ }
+
+ fclose (outfile);
+
+ return 0;
+}
diff --git a/gtk+-2.0.pc.in b/gtk+-2.0.pc.in
new file mode 100644
index 000000000..ddf6c4b62
--- /dev/null
+++ b/gtk+-2.0.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+target=@gdktarget@
+
+Name: GTK+
+Description: GIMP Tool Kit
+Version: @VERSION@
+Requires: gdk-2.0
+Libs: -L${libdir} -lgtk-${target}-1.3
+Cflags: -I${includedir}
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 274ecc36a..173ef56a9 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -1,5 +1,7 @@
## Makefile.am for gtk+/gtk
+SUBDIRS=stock-icons
+
INCLUDES = @STRIP_BEGIN@ \
-DG_LOG_DOMAIN=\"Gtk\" \
-DGTK_DISABLE_COMPAT_H \
@@ -96,6 +98,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
gtkhscrollbar.h \
gtkhseparator.h \
gtkhsv.h \
+ gtkiconfactory.h \
gtkimage.h \
gtkimcontext.h \
gtkimmulticontext.h \
@@ -141,6 +144,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
gtkspinbutton.h \
gtkstyle.h \
gtkstatusbar.h \
+ gtkstock.h \
gtktable.h \
gtktearoffmenuitem.h \
gtktextbuffer.h \
@@ -178,16 +182,18 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
# interface)
gtk_semipublic_h_sources = @STRIP_BEGIN@ \
- gtktextbtree.h \
- gtktextchild.h \
gtktextdisplay.h \
gtktextlayout.h \
- gtktextsegment.h \
- gtktexttypes.h \
@STRIP_END@
# GTK+ header files that don't get installed
gtk_private_h_sources = @STRIP_BEGIN@ \
+ gtktextbtree.h \
+ gtktextchild.h \
+ gtktextsegment.h \
+ gtktexttypes.h \
+ gtktextiterprivate.h \
+ gtktextmarkprivate.h \
gtktexttagprivate.h \
@STRIP_END@
@@ -238,6 +244,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
gtkhscrollbar.c \
gtkhseparator.c \
gtkhsv.c \
+ gtkiconfactory.c \
gtkimage.c \
gtkimcontext.c \
gtkimcontextsimple.c \
@@ -283,6 +290,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
gtksignal.c \
gtksocket.c \
gtkspinbutton.c \
+ gtkstock.c \
gtkstyle.c \
gtkstatusbar.c \
gtktable.c \
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 25765fdd3..2e2bd5138 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -75,6 +75,7 @@
#include <gtk/gtkhscale.h>
#include <gtk/gtkhscrollbar.h>
#include <gtk/gtkhseparator.h>
+#include <gtk/gtkiconfactory.h>
#include <gtk/gtkimage.h>
#include <gtk/gtkimcontext.h>
#include <gtk/gtkimmulticontext.h>
@@ -116,6 +117,7 @@
#include <gtk/gtksignal.h>
#include <gtk/gtksocket.h>
#include <gtk/gtkspinbutton.h>
+#include <gtk/gtkstock.h>
#include <gtk/gtkstyle.h>
#include <gtk/gtkstatusbar.h>
#include <gtk/gtktable.h>
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index 802873e00..394688496 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -29,7 +29,10 @@
#include "gtklabel.h"
#include "gtkmain.h"
#include "gtksignal.h"
-
+#include "gtkimage.h"
+#include "gtkhbox.h"
+#include "gtkstock.h"
+#include "gtkiconfactory.h"
#define CHILD_SPACING 1
#define DEFAULT_LEFT_POS 4
@@ -45,6 +48,7 @@ enum {
LEAVE,
LAST_SIGNAL
};
+
enum {
ARG_0,
ARG_LABEL,
@@ -311,6 +315,93 @@ gtk_button_new_with_label (const gchar *label)
return button;
}
+GtkWidget*
+gtk_button_new_stock (const gchar *stock_id,
+ GtkAccelGroup *accel_group)
+{
+ GtkWidget *button;
+ GtkStockItem item;
+
+ if (gtk_stock_lookup (stock_id, &item))
+ {
+ GtkWidget *label;
+ GtkWidget *image;
+ GtkWidget *hbox;
+ guint keyval;
+
+ button = gtk_button_new ();
+
+ label = gtk_label_new (NULL);
+ keyval = gtk_label_parse_uline (GTK_LABEL (label),
+ item.label);
+
+ if (keyval && accel_group)
+ {
+ gtk_widget_add_accelerator (button,
+ "clicked",
+ accel_group,
+ keyval,
+ GDK_MOD1_MASK,
+ GTK_ACCEL_LOCKED);
+ }
+
+ /* Also add the stock accelerator if one was specified. */
+ if (item.keyval && accel_group)
+ {
+ gtk_widget_add_accelerator (button,
+ "clicked",
+ accel_group,
+ item.keyval,
+ item.modifier,
+ GTK_ACCEL_LOCKED);
+ }
+
+ image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
+ hbox = gtk_hbox_new (FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 2);
+ gtk_box_pack_end (GTK_BOX (hbox), label, TRUE, TRUE, 2);
+
+ gtk_container_add (GTK_CONTAINER (button), hbox);
+ gtk_widget_show_all (hbox);
+ }
+ else
+ {
+ button = gtk_button_new_accel (stock_id, accel_group);
+ }
+
+ return button;
+}
+
+GtkWidget*
+gtk_button_new_accel (const gchar *uline_label,
+ GtkAccelGroup *accel_group)
+{
+ GtkWidget *button;
+ GtkWidget *label;
+ guint keyval;
+
+ button = gtk_button_new ();
+
+ label = gtk_label_new (NULL);
+ keyval = gtk_label_parse_uline (GTK_LABEL (label), uline_label);
+
+ if (keyval && accel_group)
+ {
+ gtk_widget_add_accelerator (button,
+ "clicked",
+ accel_group,
+ keyval,
+ GDK_MOD1_MASK,
+ GTK_ACCEL_LOCKED);
+ }
+
+ gtk_container_add (GTK_CONTAINER (button), label);
+ gtk_widget_show (label);
+
+ return button;
+}
+
void
gtk_button_pressed (GtkButton *button)
{
diff --git a/gtk/gtkbutton.h b/gtk/gtkbutton.h
index a55460e03..0d8c676d0 100644
--- a/gtk/gtkbutton.h
+++ b/gtk/gtkbutton.h
@@ -75,7 +75,11 @@ struct _GtkButtonClass
GtkType gtk_button_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_button_new (void);
-GtkWidget* gtk_button_new_with_label (const gchar *label);
+GtkWidget* gtk_button_new_with_label (const gchar *label);
+GtkWidget* gtk_button_new_stock (const gchar *stock_id,
+ GtkAccelGroup *accel_group);
+GtkWidget* gtk_button_new_accel (const gchar *uline_label,
+ GtkAccelGroup *accel_group);
void gtk_button_pressed (GtkButton *button);
void gtk_button_released (GtkButton *button);
void gtk_button_clicked (GtkButton *button);
diff --git a/gtk/gtkiconfactory.c b/gtk/gtkiconfactory.c
new file mode 100644
index 000000000..8924df75c
--- /dev/null
+++ b/gtk/gtkiconfactory.c
@@ -0,0 +1,1127 @@
+/* GTK - The GIMP Toolkit
+ * 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 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.
+ */
+
+/*
+ * 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/.
+ */
+
+#include "gtkiconfactory.h"
+#include "stock-icons/gtkstockpixbufs.h"
+#include "gtkstock.h"
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+
+static gpointer parent_class = NULL;
+
+static void gtk_icon_factory_init (GtkIconFactory *icon_factory);
+static void gtk_icon_factory_class_init (GtkIconFactoryClass *klass);
+static void gtk_icon_factory_finalize (GObject *object);
+static void get_default_icons (GtkIconFactory *icon_factory);
+
+GType
+gtk_icon_factory_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GtkIconFactoryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gtk_icon_factory_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkIconFactory),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_icon_factory_init,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "GtkIconFactory",
+ &object_info);
+ }
+
+ return object_type;
+}
+
+static void
+gtk_icon_factory_init (GtkIconFactory *factory)
+{
+ factory->icons = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+static void
+gtk_icon_factory_class_init (GtkIconFactoryClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = gtk_icon_factory_finalize;
+}
+
+static void
+free_icon_set (gpointer key, gpointer value, gpointer data)
+{
+ g_free (key);
+ gtk_icon_set_unref (value);
+}
+
+static void
+gtk_icon_factory_finalize (GObject *object)
+{
+ GtkIconFactory *factory = GTK_ICON_FACTORY (object);
+
+ g_hash_table_foreach (factory->icons, free_icon_set, NULL);
+
+ g_hash_table_destroy (factory->icons);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+GtkIconFactory*
+gtk_icon_factory_new (void)
+{
+ return GTK_ICON_FACTORY (g_object_new (GTK_TYPE_ICON_FACTORY, NULL));
+}
+
+void
+gtk_icon_factory_add (GtkIconFactory *factory,
+ const gchar *stock_id,
+ GtkIconSet *icon_set)
+{
+ gpointer old_key = NULL;
+ gpointer old_value = NULL;
+
+ g_return_if_fail (GTK_IS_ICON_FACTORY (factory));
+ g_return_if_fail (stock_id != NULL);
+ g_return_if_fail (icon_set != NULL);
+
+ g_hash_table_lookup_extended (factory->icons, stock_id,
+ &old_key, &old_value);
+
+ if (old_value == icon_set)
+ return;
+
+ gtk_icon_set_ref (icon_set);
+
+ /* GHashTable key memory management is so fantastically broken. */
+ if (old_key)
+ g_hash_table_insert (factory->icons, old_key, icon_set);
+ else
+ g_hash_table_insert (factory->icons, g_strdup (stock_id), icon_set);
+
+ if (old_value)
+ gtk_icon_set_unref (old_value);
+}
+
+GtkIconSet *
+gtk_icon_factory_lookup (GtkIconFactory *factory,
+ const gchar *stock_id)
+{
+ g_return_val_if_fail (GTK_IS_ICON_FACTORY (factory), NULL);
+ g_return_val_if_fail (stock_id != NULL, NULL);
+
+ return g_hash_table_lookup (factory->icons, stock_id);
+}
+
+static GtkIconFactory *gtk_default_icons = NULL;
+static GSList *default_factories = NULL;
+
+void
+gtk_icon_factory_add_default (GtkIconFactory *factory)
+{
+ g_return_if_fail (GTK_IS_ICON_FACTORY (factory));
+
+ g_object_ref (G_OBJECT (factory));
+
+ default_factories = g_slist_prepend (default_factories, factory);
+}
+
+void
+gtk_icon_factory_remove_default (GtkIconFactory *factory)
+{
+ g_return_if_fail (GTK_IS_ICON_FACTORY (factory));
+
+ default_factories = g_slist_remove (default_factories, factory);
+
+ g_object_unref (G_OBJECT (factory));
+}
+
+GtkIconSet *
+gtk_icon_factory_lookup_default (const gchar *stock_id)
+{
+ GSList *tmp_list;
+
+ g_return_val_if_fail (stock_id != NULL, NULL);
+
+ tmp_list = default_factories;
+ while (tmp_list != NULL)
+ {
+ GtkIconSet *icon_set =
+ gtk_icon_factory_lookup (GTK_ICON_FACTORY (tmp_list->data),
+ stock_id);
+
+ if (icon_set)
+ return icon_set;
+
+ tmp_list = g_slist_next (tmp_list);
+ }
+
+ if (gtk_default_icons == NULL)
+ {
+ gtk_default_icons = gtk_icon_factory_new ();
+
+ get_default_icons (gtk_default_icons);
+ }
+
+ return gtk_icon_factory_lookup (gtk_default_icons, stock_id);
+}
+
+static GtkIconSet *
+sized_icon_set_from_inline (const guchar *inline_data,
+ const gchar *size)
+{
+ GtkIconSet *set;
+
+ GtkIconSource source = { NULL, NULL, 0, 0, NULL,
+ TRUE, TRUE, FALSE };
+
+ source.size = size;
+
+ set = gtk_icon_set_new ();
+
+ source.pixbuf = gdk_pixbuf_new_from_inline (inline_data, FALSE, -1);
+
+ g_assert (source.pixbuf);
+
+ gtk_icon_set_add_source (set, &source);
+
+ g_object_unref (G_OBJECT (source.pixbuf));
+
+ return set;
+}
+
+static GtkIconSet *
+unsized_icon_set_from_inline (const guchar *inline_data)
+{
+ GtkIconSet *set;
+
+ /* This icon can be used for any direction/state/size */
+ GtkIconSource source = { NULL, NULL, 0, 0, 0,
+ TRUE, TRUE, TRUE };
+
+ set = gtk_icon_set_new ();
+
+ source.pixbuf = gdk_pixbuf_new_from_inline (inline_data, FALSE, -1);
+
+ g_assert (source.pixbuf);
+
+ gtk_icon_set_add_source (set, &source);
+
+ g_object_unref (G_OBJECT (source.pixbuf));
+
+ return set;
+}
+
+static void
+add_sized (GtkIconFactory *factory,
+ const guchar *inline_data,
+ const gchar *size,
+ const gchar *stock_id)
+{
+ GtkIconSet *set;
+
+ set = sized_icon_set_from_inline (inline_data, size);
+
+ gtk_icon_factory_add (factory, stock_id, set);
+
+ gtk_icon_set_unref (set);
+}
+
+static void
+add_unsized (GtkIconFactory *factory,
+ const guchar *inline_data,
+ const gchar *stock_id)
+{
+ GtkIconSet *set;
+
+ set = unsized_icon_set_from_inline (inline_data);
+
+ gtk_icon_factory_add (factory, stock_id, set);
+
+ gtk_icon_set_unref (set);
+}
+
+static void
+get_default_icons (GtkIconFactory *factory)
+{
+ /* KEEP IN SYNC with gtkstock.c */
+
+ add_sized (factory, dialog_error, GTK_ICON_SIZE_DIALOG, GTK_STOCK_DIALOG_ERROR);
+ add_sized (factory, dialog_info, GTK_ICON_SIZE_DIALOG, GTK_STOCK_DIALOG_INFO);
+ add_sized (factory, dialog_question, GTK_ICON_SIZE_DIALOG, GTK_STOCK_DIALOG_QUESTION);
+ add_sized (factory, dialog_warning, GTK_ICON_SIZE_DIALOG, GTK_STOCK_DIALOG_WARNING);
+
+ add_sized (factory, stock_button_apply, GTK_ICON_SIZE_BUTTON, GTK_STOCK_BUTTON_APPLY);
+ add_sized (factory, stock_button_ok, GTK_ICON_SIZE_BUTTON, GTK_STOCK_BUTTON_OK);
+ add_sized (factory, stock_button_cancel, GTK_ICON_SIZE_BUTTON, GTK_STOCK_BUTTON_CANCEL);
+ add_sized (factory, stock_button_close, GTK_ICON_SIZE_BUTTON, GTK_STOCK_BUTTON_CLOSE);
+ add_sized (factory, stock_button_yes, GTK_ICON_SIZE_BUTTON, GTK_STOCK_BUTTON_YES);
+ add_sized (factory, stock_button_no, GTK_ICON_SIZE_BUTTON, GTK_STOCK_BUTTON_NO);
+
+ add_unsized (factory, stock_close, GTK_STOCK_CLOSE);
+ add_unsized (factory, stock_exit, GTK_STOCK_QUIT);
+ add_unsized (factory, stock_help, GTK_STOCK_HELP);
+ add_unsized (factory, stock_new, GTK_STOCK_NEW);
+ add_unsized (factory, stock_open, GTK_STOCK_OPEN);
+ add_unsized (factory, stock_save, GTK_STOCK_SAVE);
+}
+
+/* Sizes */
+
+static GHashTable *icon_sizes = NULL;
+
+typedef struct _IconSize IconSize;
+
+struct _IconSize
+{
+ gchar *name;
+
+ gboolean is_alias;
+
+ union
+ {
+ gchar *target;
+ struct
+ {
+ gint width;
+ gint height;
+ } size;
+ } d;
+};
+
+static IconSize*
+icon_size_new (const gchar *name)
+{
+ IconSize *is;
+
+ is = g_new0 (IconSize, 1);
+
+ is->name = g_strdup (name);
+
+ return is;
+}
+
+static void
+icon_size_free (IconSize *is)
+{
+ g_free (is->name);
+
+ if (is->is_alias)
+ g_free (is->d.target);
+
+ g_free (is);
+}
+
+static void
+icon_size_insert (IconSize *is)
+{
+ gpointer old_key, old_value;
+
+ /* Remove old ones */
+ if (g_hash_table_lookup_extended (icon_sizes,
+ is->name,
+ &old_key, &old_value))
+ {
+ g_hash_table_remove (icon_sizes, is->name);
+ icon_size_free (old_value);
+ }
+
+ g_hash_table_insert (icon_sizes,
+ is->name, is);
+
+}
+
+static IconSize*
+icon_size_lookup (const gchar *name)
+{
+ IconSize *is;
+
+ is = g_hash_table_lookup (icon_sizes,
+ name);
+
+ while (is && is->is_alias)
+ {
+ is = g_hash_table_lookup (icon_sizes,
+ is->d.target);
+
+ }
+
+ return is;
+}
+
+static void
+icon_size_add (const gchar *name,
+ gint width,
+ gint height)
+{
+ IconSize *is;
+
+ is = icon_size_new (name);
+ is->d.size.width = width;
+ is->d.size.height = height;
+
+ icon_size_insert (is);
+}
+
+static void
+icon_alias_add (const gchar *name,
+ const gchar *target)
+{
+ IconSize *is;
+
+ is = icon_size_new (name);
+ is->is_alias = TRUE;
+
+ is->d.target = g_strdup (target);
+
+ icon_size_insert (is);
+}
+
+static void
+init_icon_sizes (void)
+{
+ if (icon_sizes == NULL)
+ {
+ IconSize *is;
+
+ icon_sizes = g_hash_table_new (g_str_hash, g_str_equal);
+
+ icon_size_add (GTK_ICON_SIZE_MENU, 16, 16);
+ icon_size_add (GTK_ICON_SIZE_BUTTON, 24, 24);
+ icon_size_add (GTK_ICON_SIZE_SMALL_TOOLBAR, 18, 18);
+ icon_size_add (GTK_ICON_SIZE_LARGE_TOOLBAR, 24, 24);
+ icon_size_add (GTK_ICON_SIZE_DIALOG, 48, 48);
+ }
+}
+
+gboolean
+gtk_icon_size_lookup (const gchar *alias,
+ gint *widthp,
+ gint *heightp)
+{
+ IconSize *is;
+
+ g_return_val_if_fail (alias != NULL, FALSE);
+
+ init_icon_sizes ();
+
+ is = icon_size_lookup (alias);
+
+ if (is == NULL)
+ return FALSE;
+
+ if (widthp)
+ *widthp = is->d.size.width;
+
+ if (heightp)
+ *heightp = is->d.size.height;
+
+ return TRUE;
+}
+
+void
+gtk_icon_size_register (const gchar *alias,
+ gint width,
+ gint height)
+{
+ gpointer old_key, old_value;
+
+ g_return_if_fail (alias != NULL);
+ g_return_if_fail (width > 0);
+ g_return_if_fail (height > 0);
+
+ init_icon_sizes ();
+
+ icon_size_add (alias, width, height);
+}
+
+void
+gtk_icon_size_register_alias (const gchar *alias,
+ const gchar *target)
+{
+ g_return_if_fail (alias != NULL);
+ g_return_if_fail (target != NULL);
+
+ init_icon_sizes ();
+
+ icon_alias_add (alias, target);
+}
+
+/* Icon Set */
+
+
+/* Clear icon set contents, drop references to all contained
+ * GdkPixbuf objects and forget all GtkIconSources. Used to
+ * recycle an icon set.
+ */
+static void gtk_icon_set_clear (GtkIconSet *icon_set);
+
+static GdkPixbuf *find_in_cache (GtkIconSet *icon_set,
+ GtkStyle *style,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size);
+static void add_to_cache (GtkIconSet *icon_set,
+ GtkStyle *style,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size,
+ GdkPixbuf *pixbuf);
+static void clear_cache (GtkIconSet *icon_set,
+ gboolean style_detach);
+static GSList* copy_cache (GtkIconSet *icon_set,
+ GtkIconSet *copy_recipient);
+static void attach_to_style (GtkIconSet *icon_set,
+ GtkStyle *style);
+static void detach_from_style (GtkIconSet *icon_set,
+ GtkStyle *style);
+static void style_dnotify (gpointer data);
+
+struct _GtkIconSet
+{
+ guint ref_count;
+
+ GSList *sources;
+
+ /* Cache of the last few rendered versions of the icon. */
+ GSList *cache;
+
+ guint cache_size;
+
+ guint cache_serial;
+};
+
+static guint cache_serial = 0;
+
+GtkIconSet*
+gtk_icon_set_new (void)
+{
+ GtkIconSet *icon_set;
+
+ icon_set = g_new (GtkIconSet, 1);
+
+ icon_set->ref_count = 1;
+ icon_set->sources = NULL;
+ icon_set->cache = NULL;
+ icon_set->cache_size = 0;
+ icon_set->cache_serial = cache_serial;
+
+ return icon_set;
+}
+
+GtkIconSet*
+gtk_icon_set_ref (GtkIconSet *icon_set)
+{
+ g_return_val_if_fail (icon_set != NULL, NULL);
+ g_return_val_if_fail (icon_set->ref_count > 0, NULL);
+
+ icon_set->ref_count += 1;
+
+ return icon_set;
+}
+
+void
+gtk_icon_set_unref (GtkIconSet *icon_set)
+{
+ g_return_if_fail (icon_set != NULL);
+ g_return_if_fail (icon_set->ref_count > 0);
+
+ icon_set->ref_count -= 1;
+
+ if (icon_set->ref_count == 0)
+ {
+ GSList *tmp_list = icon_set->sources;
+ while (tmp_list != NULL)
+ {
+ gtk_icon_source_free (tmp_list->data);
+
+ tmp_list = g_slist_next (tmp_list);
+ }
+
+ clear_cache (icon_set, TRUE);
+
+ g_free (icon_set);
+ }
+}
+
+GtkIconSet*
+gtk_icon_set_copy (GtkIconSet *icon_set)
+{
+ GtkIconSet *copy;
+ GSList *tmp_list;
+
+ copy = gtk_icon_set_new ();
+
+ tmp_list = icon_set->sources;
+ while (tmp_list != NULL)
+ {
+ copy->sources = g_slist_prepend (copy->sources,
+ gtk_icon_source_copy (tmp_list->data));
+
+ tmp_list = g_slist_next (tmp_list);
+ }
+
+ copy->sources = g_slist_reverse (copy->sources);
+
+ copy->cache = copy_cache (icon_set, copy);
+ copy->cache_size = icon_set->cache_size;
+ copy->cache_serial = icon_set->cache_serial;
+
+ return copy;
+}
+
+
+static gboolean
+sizes_equivalent (const gchar *rhs, const gchar *lhs)
+{
+ gint r_w, r_h, l_w, l_h;
+
+ gtk_icon_size_lookup (rhs, &r_w, &r_h);
+ gtk_icon_size_lookup (lhs, &l_w, &l_h);
+
+ return r_w == l_w && r_h == l_h;
+}
+
+static GtkIconSource*
+find_and_prep_icon_source (GtkIconSet *icon_set,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size)
+{
+ GtkIconSource *source;
+ GSList *tmp_list;
+
+
+ /* We need to find the best icon source. Direction matters more
+ * than state, state matters more than size. icon_set->sources
+ * is sorted according to wildness, so if we take the first
+ * match we find it will be the least-wild match (if there are
+ * multiple matches for a given "wildness" then the RC file contained
+ * dumb stuff, and we end up with an arbitrary matching source)
+ */
+
+ source = NULL;
+ tmp_list = icon_set->sources;
+ while (tmp_list != NULL)
+ {
+ GtkIconSource *s = tmp_list->data;
+
+ if ((s->any_direction || (s->direction == direction)) &&
+ (s->any_state || (s->state == state)) &&
+ (s->any_size || (sizes_equivalent (size, s->size))))
+ {
+ source = s;
+ break;
+ }
+
+ tmp_list = g_slist_next (tmp_list);
+ }
+
+ if (source == NULL)
+ return NULL;
+
+ if (source->pixbuf == NULL)
+ {
+ gchar *full;
+
+ g_assert (source->filename);
+
+ if (*source->filename != G_DIR_SEPARATOR)
+ full = gtk_rc_find_pixmap_in_path (NULL, source->filename);
+ else
+ full = g_strdup (source->filename);
+
+ source->pixbuf = gdk_pixbuf_new_from_file (full);
+
+ g_free (full);
+
+ if (source->pixbuf == NULL)
+ {
+ /* Remove this icon source so we don't keep trying to
+ * load it.
+ */
+ g_warning ("Failed to load icon '%s'", source->filename);
+
+ icon_set->sources = g_slist_remove (icon_set->sources, source);
+
+ gtk_icon_source_free (source);
+
+ /* Try to fall back to other sources */
+ if (icon_set->sources != NULL)
+ return find_and_prep_icon_source (icon_set,
+ direction,
+ state,
+ size);
+ else
+ return NULL;
+ }
+ }
+
+ return source;
+}
+
+GdkPixbuf*
+gtk_icon_set_render_icon (GtkIconSet *icon_set,
+ GtkStyle *style,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size,
+ GtkWidget *widget,
+ const char *detail)
+{
+ GdkPixbuf *icon;
+ GtkIconSource *source;
+
+ /* FIXME conceivably, everywhere this function
+ * returns NULL, we should return some default
+ * dummy icon like a question mark or the image icon
+ * from netscape
+ */
+
+ g_return_val_if_fail (icon_set != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
+
+ if (icon_set->sources == NULL)
+ return NULL;
+
+ icon = find_in_cache (icon_set, style, direction,
+ state, size);
+
+ if (icon)
+ {
+ g_object_ref (G_OBJECT (icon));
+ return icon;
+ }
+
+
+ source = find_and_prep_icon_source (icon_set, direction, state, size);
+
+ if (source == NULL)
+ return NULL;
+
+ g_assert (source->pixbuf != NULL);
+
+ icon = gtk_style_render_icon (style,
+ source,
+ direction,
+ state,
+ size,
+ widget,
+ detail);
+
+ if (icon == NULL)
+ {
+ g_warning ("Theme engine failed to render icon");
+ return NULL;
+ }
+
+ add_to_cache (icon_set, style, direction, state, size, icon);
+
+ return icon;
+}
+
+/* Order sources by their "wildness", so that "wilder" sources are
+ * greater than "specific" sources; for determining ordering,
+ * direction beats state beats size.
+ */
+
+static int
+icon_source_compare (gconstpointer ap, gconstpointer bp)
+{
+ const GtkIconSource *a = ap;
+ const GtkIconSource *b = bp;
+
+ if (!a->any_direction && b->any_direction)
+ return -1;
+ else if (a->any_direction && !b->any_direction)
+ return 1;
+ else if (!a->any_state && b->any_state)
+ return -1;
+ else if (a->any_state && !b->any_state)
+ return 1;
+ else if (!a->any_size && b->any_size)
+ return -1;
+ else if (a->any_size && !b->any_size)
+ return 1;
+ else
+ return 0;
+}
+
+void
+gtk_icon_set_add_source (GtkIconSet *icon_set,
+ const GtkIconSource *source)
+{
+ g_return_if_fail (icon_set != NULL);
+ g_return_if_fail (source != NULL);
+
+ if (source->pixbuf == NULL &&
+ source->filename == NULL)
+ {
+ g_warning ("Useless GtkIconSource contains NULL filename and pixbuf");
+ return;
+ }
+
+ icon_set->sources = g_slist_insert_sorted (icon_set->sources,
+ gtk_icon_source_copy (source),
+ icon_source_compare);
+}
+
+GtkIconSource *
+gtk_icon_source_copy (const GtkIconSource *source)
+{
+ GtkIconSource *copy;
+
+ g_return_val_if_fail (source != NULL, NULL);
+
+ copy = g_new (GtkIconSource, 1);
+
+ *copy = *source;
+
+ copy->filename = g_strdup (source->filename);
+ copy->size = g_strdup (source->size);
+ if (copy->pixbuf)
+ g_object_ref (G_OBJECT (copy->pixbuf));
+
+ return copy;
+}
+
+void
+gtk_icon_source_free (GtkIconSource *source)
+{
+ g_return_if_fail (source != NULL);
+
+ g_free ((char*) source->filename);
+ g_free ((char*) source->size);
+ if (source->pixbuf)
+ g_object_unref (G_OBJECT (source->pixbuf));
+
+ g_free (source);
+}
+
+void
+gtk_icon_set_clear (GtkIconSet *icon_set)
+{
+ GSList *tmp_list;
+
+ g_return_if_fail (icon_set != NULL);
+
+ tmp_list = icon_set->sources;
+ while (tmp_list != NULL)
+ {
+ gtk_icon_source_free (tmp_list->data);
+
+ tmp_list = g_slist_next (tmp_list);
+ }
+
+ clear_cache (icon_set, TRUE);
+}
+
+/* Note that the logical maximum is 20 per GtkTextDirection, so we could
+ * eventually set this to >20 to never throw anything out.
+ */
+#define NUM_CACHED_ICONS 8
+
+typedef struct _CachedIcon CachedIcon;
+
+struct _CachedIcon
+{
+ /* These must all match to use the cached pixbuf.
+ * If any don't match, we must re-render the pixbuf.
+ */
+ GtkStyle *style;
+ GtkTextDirection direction;
+ GtkStateType state;
+ gchar *size;
+
+ GdkPixbuf *pixbuf;
+};
+
+static void
+ensure_cache_up_to_date (GtkIconSet *icon_set)
+{
+ if (icon_set->cache_serial != cache_serial)
+ clear_cache (icon_set, TRUE);
+}
+
+static void
+cached_icon_free (CachedIcon *icon)
+{
+ g_free (icon->size);
+ g_object_unref (G_OBJECT (icon->pixbuf));
+
+ g_free (icon);
+}
+
+static GdkPixbuf *
+find_in_cache (GtkIconSet *icon_set,
+ GtkStyle *style,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size)
+{
+ GSList *tmp_list;
+ GSList *prev;
+
+ ensure_cache_up_to_date (icon_set);
+
+ prev = NULL;
+ tmp_list = icon_set->cache;
+ while (tmp_list != NULL)
+ {
+ CachedIcon *icon = tmp_list->data;
+
+ if (icon->style == style &&
+ icon->direction == direction &&
+ icon->state == state &&
+ strcmp (icon->size, size) == 0)
+ {
+ if (prev)
+ {
+ /* Move this icon to the front of the list. */
+ prev->next = tmp_list->next;
+ tmp_list->next = icon_set->cache;
+ icon_set->cache = tmp_list;
+ }
+
+ return icon->pixbuf;
+ }
+
+ prev = tmp_list;
+ tmp_list = g_slist_next (tmp_list);
+ }
+
+ return NULL;
+}
+
+static void
+add_to_cache (GtkIconSet *icon_set,
+ GtkStyle *style,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size,
+ GdkPixbuf *pixbuf)
+{
+ CachedIcon *icon;
+
+ ensure_cache_up_to_date (icon_set);
+
+ g_object_ref (G_OBJECT (pixbuf));
+
+ /* We have to ref the style, since if the style was finalized
+ * its address could be reused by another style, creating a
+ * really weird bug
+ */
+
+ if (style)
+ g_object_ref (G_OBJECT (style));
+
+
+ icon = g_new (CachedIcon, 1);
+ icon_set->cache = g_slist_prepend (icon_set->cache, icon);
+
+ icon->style = style;
+ icon->direction = direction;
+ icon->state = state;
+ icon->size = g_strdup (size);
+ icon->pixbuf = pixbuf;
+
+ if (icon->style)
+ attach_to_style (icon_set, icon->style);
+
+ if (icon_set->cache_size >= NUM_CACHED_ICONS)
+ {
+ /* Remove oldest item in the cache */
+
+ GSList *tmp_list;
+
+ tmp_list = icon_set->cache;
+
+ /* Find next-to-last link */
+ g_assert (NUM_CACHED_ICONS > 2);
+ while (tmp_list->next->next)
+ tmp_list = tmp_list->next;
+
+ g_assert (tmp_list != NULL);
+ g_assert (tmp_list->next != NULL);
+ g_assert (tmp_list->next->next == NULL);
+
+ /* Free the last icon */
+ icon = tmp_list->next->data;
+
+ g_slist_free (tmp_list->next);
+ tmp_list->next = NULL;
+
+ cached_icon_free (icon);
+ }
+}
+
+static void
+clear_cache (GtkIconSet *icon_set,
+ gboolean style_detach)
+{
+ GSList *tmp_list;
+ GtkStyle *last_style = NULL;
+
+ tmp_list = icon_set->cache;
+ while (tmp_list != NULL)
+ {
+ CachedIcon *icon = tmp_list->data;
+
+ if (style_detach)
+ {
+ /* simple optimization for the case where the cache
+ * contains contiguous icons from the same style.
+ * it's safe to call detach_from_style more than
+ * once on the same style though.
+ */
+ if (last_style != icon->style)
+ {
+ detach_from_style (icon_set, icon->style);
+ last_style = icon->style;
+ }
+ }
+
+ cached_icon_free (icon);
+
+ tmp_list = g_slist_next (tmp_list);
+ }
+
+ g_slist_free (icon_set->cache);
+ icon_set->cache = NULL;
+ icon_set->cache_size = 0;
+}
+
+static GSList*
+copy_cache (GtkIconSet *icon_set,
+ GtkIconSet *copy_recipient)
+{
+ GSList *tmp_list;
+ GSList *copy = NULL;
+
+ ensure_cache_up_to_date (icon_set);
+
+ tmp_list = icon_set->cache;
+ while (tmp_list != NULL)
+ {
+ CachedIcon *icon = tmp_list->data;
+ CachedIcon *icon_copy = g_new (CachedIcon, 1);
+
+ *icon_copy = *icon;
+
+ if (icon_copy->style)
+ attach_to_style (copy_recipient, icon_copy->style);
+
+ g_object_ref (G_OBJECT (icon_copy->pixbuf));
+
+ icon_copy->size = g_strdup (icon->size);
+
+ copy = g_slist_prepend (copy, icon_copy);
+
+ tmp_list = g_slist_next (tmp_list);
+ }
+
+ return g_slist_reverse (copy);
+}
+
+static void
+attach_to_style (GtkIconSet *icon_set,
+ GtkStyle *style)
+{
+ GHashTable *table;
+
+ table = g_object_get_qdata (G_OBJECT (style),
+ g_quark_try_string ("gtk-style-icon-sets"));
+
+ if (table == NULL)
+ {
+ table = g_hash_table_new (NULL, NULL);
+ g_object_set_qdata_full (G_OBJECT (style),
+ g_quark_from_static_string ("gtk-style-icon-sets"),
+ table,
+ style_dnotify);
+ }
+
+ g_hash_table_insert (table, icon_set, icon_set);
+}
+
+static void
+detach_from_style (GtkIconSet *icon_set,
+ GtkStyle *style)
+{
+ GHashTable *table;
+
+ table = g_object_get_qdata (G_OBJECT (style),
+ g_quark_try_string ("gtk-style-icon-sets"));
+
+ if (table != NULL)
+ g_hash_table_remove (table, icon_set);
+}
+
+static void
+iconsets_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ GtkIconSet *icon_set = key;
+
+ /* We only need to remove cache entries for the given style;
+ * but that complicates things because in destroy notify
+ * we don't know which style got destroyed, and 95% of the
+ * time all cache entries will have the same style,
+ * so this is faster anyway.
+ */
+
+ clear_cache (icon_set, FALSE);
+}
+
+static void
+style_dnotify (gpointer data)
+{
+ GHashTable *table = data;
+
+ g_hash_table_foreach (table, iconsets_foreach, NULL);
+
+ g_hash_table_destroy (table);
+}
+
+/* This allows the icon set to detect that its cache is out of date. */
+void
+_gtk_icon_set_invalidate_caches (void)
+{
+ ++cache_serial;
+}
diff --git a/gtk/gtkiconfactory.h b/gtk/gtkiconfactory.h
new file mode 100644
index 000000000..357e37eb7
--- /dev/null
+++ b/gtk/gtkiconfactory.h
@@ -0,0 +1,159 @@
+/* GTK - The GIMP Toolkit
+ * 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 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.
+ */
+
+/*
+ * 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/.
+ */
+
+#ifndef __GTK_ICON_FACTORY_H__
+#define __GTK_ICON_FACTORY_H__
+
+#include <gdk/gdk.h>
+#include <gtk/gtkrc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GtkIconFactoryClass GtkIconFactoryClass;
+
+#define GTK_TYPE_ICON_FACTORY (gtk_icon_factory_get_type ())
+#define GTK_ICON_FACTORY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_ICON_FACTORY, GtkIconFactory))
+#define GTK_ICON_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ICON_FACTORY, GtkIconFactoryClass))
+#define GTK_IS_ICON_FACTORY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_ICON_FACTORY))
+#define GTK_IS_ICON_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ICON_FACTORY))
+#define GTK_ICON_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ICON_FACTORY, GtkIconFactoryClass))
+
+struct _GtkIconFactory
+{
+ GObject parent_instance;
+
+ GHashTable *icons;
+};
+
+struct _GtkIconFactoryClass
+{
+ GObjectClass parent_class;
+
+
+};
+
+GType gtk_icon_factory_get_type (void);
+GtkIconFactory* gtk_icon_factory_new (void);
+void gtk_icon_factory_add (GtkIconFactory *factory,
+ const gchar *stock_id,
+ GtkIconSet *icon_set);
+GtkIconSet* gtk_icon_factory_lookup (GtkIconFactory *factory,
+ const gchar *stock_id);
+
+/* Manage the default icon factory stack */
+
+void gtk_icon_factory_add_default (GtkIconFactory *factory);
+void gtk_icon_factory_remove_default (GtkIconFactory *factory);
+GtkIconSet* gtk_icon_factory_lookup_default (const gchar *stock_id);
+
+/* Get preferred real size from registered semantic size. Note that
+ * themes SHOULD use this size, but they aren't required to; for size
+ * requests and such, you should get the actual pixbuf from the icon
+ * set and see what size was rendered.
+ *
+ * This function is intended for people who are scaling icons,
+ * rather than for people who are displaying already-scaled icons.
+ * That is, if you are displaying an icon, you should get the
+ * size from the rendered pixbuf, not from here.
+ */
+
+gboolean gtk_icon_size_lookup (const gchar *alias,
+ gint *width,
+ gint *height);
+void gtk_icon_size_register (const gchar *alias,
+ gint width,
+ gint height);
+void gtk_icon_size_register_alias (const gchar *alias,
+ const gchar *target);
+
+
+/* Standard sizes */
+
+#define GTK_ICON_SIZE_MENU "gtk-menu"
+#define GTK_ICON_SIZE_SMALL_TOOLBAR "gtk-small-toolbar"
+#define GTK_ICON_SIZE_LARGE_TOOLBAR "gtk-large-toolbar"
+#define GTK_ICON_SIZE_BUTTON "gtk-button"
+#define GTK_ICON_SIZE_DIALOG "gtk-dialog"
+
+/* Icon sets */
+
+GtkIconSet* gtk_icon_set_new (void);
+
+GtkIconSet* gtk_icon_set_ref (GtkIconSet *icon_set);
+void gtk_icon_set_unref (GtkIconSet *icon_set);
+GtkIconSet* gtk_icon_set_copy (GtkIconSet *icon_set);
+
+/* Get one of the icon variants in the set, creating the variant if
+ * necessary.
+ */
+GdkPixbuf* gtk_icon_set_render_icon (GtkIconSet *icon_set,
+ GtkStyle *style,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size,
+ GtkWidget *widget,
+ const char *detail);
+
+
+void gtk_icon_set_add_source (GtkIconSet *icon_set,
+ const GtkIconSource *source);
+
+/* INTERNAL */
+void _gtk_icon_set_invalidate_caches (void);
+
+struct _GtkIconSource
+{
+ /* Either filename or pixbuf can be NULL. If both are non-NULL,
+ * the pixbuf is assumed to be the already-loaded contents of the
+ * file.
+ */
+ gchar *filename;
+ GdkPixbuf *pixbuf;
+
+ GtkTextDirection direction;
+ GtkStateType state;
+ gchar *size;
+
+ /* If TRUE, then the parameter is wildcarded, and the above
+ * fields should be ignored. If FALSE, the parameter is
+ * specified, and the above fields should be valid.
+ */
+ guint any_direction : 1;
+ guint any_state : 1;
+ guint any_size : 1;
+};
+
+
+GtkIconSource* gtk_icon_source_copy (const GtkIconSource *source);
+void gtk_icon_source_free (GtkIconSource *source);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GTK_ICON_FACTORY_H__ */
diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c
index 01154d929..504b2a2e1 100644
--- a/gtk/gtkimage.c
+++ b/gtk/gtkimage.c
@@ -26,13 +26,20 @@
#include "gtkcontainer.h"
#include "gtkimage.h"
+#include "gtkiconfactory.h"
+static void gtk_image_class_init (GtkImageClass *klass);
+static void gtk_image_init (GtkImage *image);
+static gint gtk_image_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+static void gtk_image_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void gtk_image_clear (GtkImage *image);
+static void gtk_image_update_size (GtkImage *image,
+ gint image_width,
+ gint image_height);
-static void gtk_image_class_init (GtkImageClass *klass);
-static void gtk_image_init (GtkImage *image);
-static gint gtk_image_expose (GtkWidget *widget,
- GdkEventExpose *event);
-
+static gpointer parent_class;
GtkType
gtk_image_get_type (void)
@@ -64,9 +71,12 @@ gtk_image_class_init (GtkImageClass *class)
{
GtkWidgetClass *widget_class;
+ parent_class = g_type_class_peek_parent (class);
+
widget_class = (GtkWidgetClass*) class;
widget_class->expose_event = gtk_image_expose;
+ widget_class->size_request = gtk_image_size_request;
}
static void
@@ -74,49 +84,371 @@ gtk_image_init (GtkImage *image)
{
GTK_WIDGET_SET_FLAGS (image, GTK_NO_WINDOW);
- image->image = NULL;
- image->mask = NULL;
+ image->storage_type = GTK_IMAGE_EMPTY;
}
GtkWidget*
-gtk_image_new (GdkImage *val,
- GdkBitmap *mask)
+gtk_image_new_from_pixmap (GdkPixmap *pixmap,
+ GdkBitmap *mask)
{
GtkImage *image;
- g_return_val_if_fail (val != NULL, NULL);
+ image = gtk_type_new (GTK_TYPE_IMAGE);
+
+ gtk_image_set_from_pixmap (image, pixmap, mask);
+
+ return GTK_WIDGET (image);
+}
+
+GtkWidget*
+gtk_image_new_from_image (GdkImage *gdk_image,
+ GdkBitmap *mask)
+{
+ GtkImage *image;
image = gtk_type_new (GTK_TYPE_IMAGE);
- gtk_image_set (image, val, mask);
+ gtk_image_set_from_image (image, gdk_image, mask);
+
+ return GTK_WIDGET (image);
+}
+
+GtkWidget*
+gtk_image_new_from_file (const gchar *filename)
+{
+ GtkImage *image;
+
+ image = gtk_type_new (GTK_TYPE_IMAGE);
+
+ gtk_image_set_from_file (image, filename);
+
+ return GTK_WIDGET (image);
+}
+
+GtkWidget*
+gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
+{
+ GtkImage *image;
+
+ image = gtk_type_new (GTK_TYPE_IMAGE);
+
+ gtk_image_set_from_pixbuf (image, pixbuf);
+
+ return GTK_WIDGET (image);
+}
+
+GtkWidget*
+gtk_image_new_from_stock (const gchar *stock_id,
+ const gchar *size)
+{
+ GtkImage *image;
+
+ image = gtk_type_new (GTK_TYPE_IMAGE);
+
+ gtk_image_set_from_stock (image, stock_id, size);
+
+ return GTK_WIDGET (image);
+}
+
+GtkWidget*
+gtk_image_new_from_icon_set (GtkIconSet *icon_set,
+ const gchar *size)
+{
+ GtkImage *image;
+
+ image = gtk_type_new (GTK_TYPE_IMAGE);
+
+ gtk_image_set_from_icon_set (image, icon_set, size);
return GTK_WIDGET (image);
}
void
-gtk_image_set (GtkImage *image,
- GdkImage *val,
- GdkBitmap *mask)
+gtk_image_set_from_pixmap (GtkImage *image,
+ GdkPixmap *pixmap,
+ GdkBitmap *mask)
+{
+ g_return_if_fail (GTK_IS_IMAGE (image));
+ g_return_if_fail (pixmap == NULL ||
+ GDK_IS_PIXMAP (pixmap));
+ g_return_if_fail (mask == NULL ||
+ GDK_IS_PIXMAP (mask));
+
+ if (pixmap)
+ g_object_ref (G_OBJECT (pixmap));
+
+ if (mask)
+ g_object_ref (G_OBJECT (mask));
+
+ gtk_image_clear (image);
+
+ if (pixmap)
+ {
+ int width;
+ int height;
+
+ image->storage_type = GTK_IMAGE_PIXMAP;
+
+ image->data.pixmap.pixmap = pixmap;
+ image->data.pixmap.mask = mask;
+
+ gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height);
+
+ gtk_image_update_size (image, width, height);
+ }
+ else
+ {
+ /* Clean up the mask if pixmap was NULL */
+ if (mask)
+ g_object_unref (G_OBJECT (mask));
+ }
+}
+
+void
+gtk_image_set_from_image (GtkImage *image,
+ GdkImage *gdk_image,
+ GdkBitmap *mask)
{
- g_return_if_fail (image != NULL);
g_return_if_fail (GTK_IS_IMAGE (image));
+ g_return_if_fail (gdk_image == NULL ||
+ GDK_IS_IMAGE (gdk_image));
+ g_return_if_fail (mask == NULL ||
+ GDK_IS_PIXMAP (mask));
+
+
+ if (gdk_image)
+ g_object_ref (G_OBJECT (gdk_image));
+
+ if (mask)
+ g_object_ref (G_OBJECT (mask));
- image->image = val;
- image->mask = mask;
+ gtk_image_clear (image);
- if (image->image)
+ if (gdk_image)
{
- GTK_WIDGET (image)->requisition.width = image->image->width + GTK_MISC (image)->xpad * 2;
- GTK_WIDGET (image)->requisition.height = image->image->height + GTK_MISC (image)->ypad * 2;
+ image->storage_type = GTK_IMAGE_IMAGE;
+
+ image->data.image.image = gdk_image;
+ image->data.image.mask = mask;
+
+ gtk_image_update_size (image, gdk_image->width, gdk_image->height);
}
else
{
- GTK_WIDGET (image)->requisition.width = 0;
- GTK_WIDGET (image)->requisition.height = 0;
+ /* Clean up the mask if gdk_image was NULL */
+ if (mask)
+ g_object_unref (G_OBJECT (mask));
}
+}
- if (GTK_WIDGET_VISIBLE (image))
- gtk_widget_queue_resize (GTK_WIDGET (image));
+void
+gtk_image_set_from_file (GtkImage *image,
+ const gchar *filename)
+{
+ GdkPixbuf *pixbuf;
+
+ g_return_if_fail (GTK_IS_IMAGE (image));
+ g_return_if_fail (filename != NULL);
+
+ gtk_image_clear (image);
+
+ if (filename == NULL)
+ return;
+
+ pixbuf = gdk_pixbuf_new_from_file (filename);
+
+ if (pixbuf == NULL)
+ return;
+
+ gtk_image_set_from_pixbuf (image, pixbuf);
+
+ g_object_unref (G_OBJECT (pixbuf));
+}
+
+void
+gtk_image_set_from_pixbuf (GtkImage *image,
+ GdkPixbuf *pixbuf)
+{
+ g_return_if_fail (GTK_IS_IMAGE (image));
+ g_return_if_fail (pixbuf == NULL ||
+ GDK_IS_PIXBUF (pixbuf));
+
+ if (pixbuf)
+ g_object_ref (G_OBJECT (pixbuf));
+
+ gtk_image_clear (image);
+
+ if (pixbuf != NULL)
+ {
+ image->storage_type = GTK_IMAGE_PIXBUF;
+
+ image->data.pixbuf.pixbuf = pixbuf;
+
+ gtk_image_update_size (image,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+ }
+}
+
+void
+gtk_image_set_from_stock (GtkImage *image,
+ const gchar *stock_id,
+ const gchar *size)
+{
+ g_return_if_fail (GTK_IS_IMAGE (image));
+
+ gtk_image_clear (image);
+
+ if (stock_id)
+ {
+ image->storage_type = GTK_IMAGE_STOCK;
+
+ image->data.stock.stock_id = g_strdup (stock_id);
+ image->data.stock.size = g_strdup (size);
+
+ /* Size is demand-computed in size request method
+ * if we're a stock image, since changing the
+ * style impacts the size request
+ */
+ }
+}
+
+void
+gtk_image_set_from_icon_set (GtkImage *image,
+ GtkIconSet *icon_set,
+ const gchar *size)
+{
+ g_return_if_fail (GTK_IS_IMAGE (image));
+
+ if (icon_set)
+ gtk_icon_set_ref (icon_set);
+
+ gtk_image_clear (image);
+
+ if (icon_set)
+ {
+ image->storage_type = GTK_IMAGE_ICON_SET;
+
+ image->data.icon_set.icon_set = icon_set;
+ image->data.icon_set.size = g_strdup (size);
+
+ /* Size is demand-computed in size request method
+ * if we're an icon set
+ */
+ }
+}
+
+GtkImageType
+gtk_image_get_storage_type (GtkImage *image)
+{
+ g_return_val_if_fail (GTK_IS_IMAGE (image), GTK_IMAGE_EMPTY);
+
+ return image->storage_type;
+}
+
+void
+gtk_image_get_pixmap (GtkImage *image,
+ GdkPixmap **pixmap,
+ GdkBitmap **mask)
+{
+ g_return_if_fail (GTK_IS_IMAGE (image));
+ g_return_if_fail (image->storage_type == GTK_IMAGE_PIXMAP ||
+ image->storage_type == GTK_IMAGE_EMPTY);
+
+ if (pixmap)
+ *pixmap = image->data.pixmap.pixmap;
+
+ if (mask)
+ *mask = image->data.pixmap.mask;
+}
+
+void
+gtk_image_get_image (GtkImage *image,
+ GdkImage **gdk_image,
+ GdkBitmap **mask)
+{
+ g_return_if_fail (GTK_IS_IMAGE (image));
+ g_return_if_fail (image->storage_type == GTK_IMAGE_IMAGE ||
+ image->storage_type == GTK_IMAGE_EMPTY);
+
+ if (gdk_image)
+ *gdk_image = image->data.image.image;
+
+ if (mask)
+ *mask = image->data.image.mask;
+}
+
+GdkPixbuf*
+gtk_image_get_pixbuf (GtkImage *image)
+{
+ g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
+ g_return_val_if_fail (image->storage_type == GTK_IMAGE_PIXBUF ||
+ image->storage_type == GTK_IMAGE_EMPTY, NULL);
+
+ if (image->storage_type == GTK_IMAGE_EMPTY)
+ image->data.pixbuf.pixbuf = NULL;
+
+ return image->data.pixbuf.pixbuf;
+}
+
+void
+gtk_image_get_stock (GtkImage *image,
+ gchar **stock_id,
+ gchar **size)
+{
+ g_return_if_fail (GTK_IS_IMAGE (image));
+ g_return_if_fail (image->storage_type == GTK_IMAGE_STOCK ||
+ image->storage_type == GTK_IMAGE_EMPTY);
+
+ if (image->storage_type == GTK_IMAGE_EMPTY)
+ image->data.stock.stock_id = NULL;
+
+ if (stock_id)
+ *stock_id = g_strdup (image->data.stock.stock_id);
+
+ if (size)
+ *size = image->data.stock.size;
+}
+
+void
+gtk_image_get_icon_set (GtkImage *image,
+ GtkIconSet **icon_set,
+ gchar **size)
+{
+ g_return_if_fail (GTK_IS_IMAGE (image));
+ g_return_if_fail (image->storage_type == GTK_IMAGE_ICON_SET ||
+ image->storage_type == GTK_IMAGE_EMPTY);
+
+ if (icon_set)
+ *icon_set = image->data.icon_set.icon_set;
+
+ if (size)
+ *size = g_strdup (image->data.icon_set.size);
+}
+
+GtkWidget*
+gtk_image_new (GdkImage *val,
+ GdkBitmap *mask)
+{
+ GtkImage *image;
+
+ g_return_val_if_fail (val != NULL, NULL);
+
+ image = gtk_type_new (GTK_TYPE_IMAGE);
+
+ gtk_image_set (image, val, mask);
+
+ return GTK_WIDGET (image);
+}
+
+void
+gtk_image_set (GtkImage *image,
+ GdkImage *val,
+ GdkBitmap *mask)
+{
+ g_return_if_fail (GTK_IS_IMAGE (image));
+
+ gtk_image_set_from_image (image, val, mask);
}
void
@@ -124,13 +456,9 @@ gtk_image_get (GtkImage *image,
GdkImage **val,
GdkBitmap **mask)
{
- g_return_if_fail (image != NULL);
g_return_if_fail (GTK_IS_IMAGE (image));
- if (val)
- *val = image->image;
- if (mask)
- *mask = image->mask;
+ gtk_image_get_image (image, val, mask);
}
@@ -141,13 +469,16 @@ gtk_image_expose (GtkWidget *widget,
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
-
- if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+
+ if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) &&
+ GTK_IMAGE (widget)->storage_type != GTK_IMAGE_EMPTY)
{
GtkImage *image;
GtkMisc *misc;
GdkRectangle area, image_bound, intersection;
gint x, y;
+ GdkBitmap *mask = NULL;
+ GdkPixbuf *stock_pixbuf = NULL;
image = GTK_IMAGE (widget);
misc = GTK_MISC (widget);
@@ -161,35 +492,265 @@ gtk_image_expose (GtkWidget *widget,
- (widget->requisition.height - misc->ypad * 2)) *
misc->yalign) + 0.5;
- if (image->mask)
+ image_bound.x = x;
+ image_bound.y = y;
+
+ switch (image->storage_type)
+ {
+ case GTK_IMAGE_PIXMAP:
+ mask = image->data.pixmap.mask;
+ gdk_drawable_get_size (image->data.pixmap.pixmap,
+ &image_bound.width,
+ &image_bound.height);
+ break;
+
+ case GTK_IMAGE_IMAGE:
+ mask = image->data.image.mask;
+ image_bound.width = image->data.image.image->width;
+ image_bound.height = image->data.image.image->height;
+ break;
+
+ case GTK_IMAGE_PIXBUF:
+ image_bound.width = gdk_pixbuf_get_width (image->data.pixbuf.pixbuf);
+ image_bound.height = gdk_pixbuf_get_height (image->data.pixbuf.pixbuf);
+ break;
+
+ case GTK_IMAGE_STOCK:
+ stock_pixbuf = gtk_widget_render_stock_icon (widget,
+ image->data.stock.stock_id,
+ image->data.stock.size,
+ NULL);
+
+ if (stock_pixbuf)
+ {
+ image_bound.width = gdk_pixbuf_get_width (stock_pixbuf);
+ image_bound.height = gdk_pixbuf_get_height (stock_pixbuf);
+ }
+ break;
+
+ case GTK_IMAGE_ICON_SET:
+ stock_pixbuf =
+ gtk_icon_set_render_icon (image->data.icon_set.icon_set,
+ widget->style,
+ gtk_widget_get_direction (widget),
+ GTK_WIDGET_STATE (widget),
+ image->data.icon_set.size,
+ widget,
+ NULL);
+
+ if (stock_pixbuf)
+ {
+ image_bound.width = gdk_pixbuf_get_width (stock_pixbuf);
+ image_bound.height = gdk_pixbuf_get_height (stock_pixbuf);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (mask)
{
- gdk_gc_set_clip_mask (widget->style->black_gc, image->mask);
+ gdk_gc_set_clip_mask (widget->style->black_gc, mask);
gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
}
- image_bound.x = x;
- image_bound.y = y;
- image_bound.width = image->image->width;
- image_bound.height = image->image->height;
-
area = event->area;
- if(gdk_rectangle_intersect(&image_bound, &area, &intersection))
+ if (gdk_rectangle_intersect (&image_bound, &area, &intersection))
{
- gdk_draw_image (widget->window,
- widget->style->black_gc,
- image->image,
- image_bound.x - x, image_bound.y - y,
- image_bound.x, image_bound.y,
- image_bound.width, image_bound.height);
+
+ switch (image->storage_type)
+ {
+ case GTK_IMAGE_PIXMAP:
+ gdk_draw_drawable (widget->window,
+ widget->style->black_gc,
+ image->data.pixmap.pixmap,
+ image_bound.x - x, image_bound.y - y,
+ image_bound.x, image_bound.y,
+ image_bound.width, image_bound.height);
+ break;
+
+ case GTK_IMAGE_IMAGE:
+ gdk_draw_image (widget->window,
+ widget->style->black_gc,
+ image->data.image.image,
+ image_bound.x - x, image_bound.y - y,
+ image_bound.x, image_bound.y,
+ image_bound.width, image_bound.height);
+ break;
+
+ case GTK_IMAGE_PIXBUF:
+ gdk_pixbuf_render_to_drawable_alpha (image->data.pixbuf.pixbuf,
+ widget->window,
+ image_bound.x - x, image_bound.y - y,
+ image_bound.x, image_bound.y,
+ image_bound.width, image_bound.height,
+ GDK_PIXBUF_ALPHA_FULL,
+ 128,
+ GDK_RGB_DITHER_NORMAL,
+ 0, 0);
+ break;
+
+ case GTK_IMAGE_STOCK: /* fall thru */
+ case GTK_IMAGE_ICON_SET:
+ if (stock_pixbuf)
+ {
+ gdk_pixbuf_render_to_drawable_alpha (stock_pixbuf,
+ widget->window,
+ image_bound.x - x, image_bound.y - y,
+ image_bound.x, image_bound.y,
+ image_bound.width, image_bound.height,
+ GDK_PIXBUF_ALPHA_FULL,
+ 128,
+ GDK_RGB_DITHER_NORMAL,
+ 0, 0);
+
+ g_object_unref (G_OBJECT (stock_pixbuf));
+ }
+ break;
+
+ default:
+ break;
+ }
+ } /* if rectangle intersects */
+ if (mask)
+ {
+ gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
+ gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
}
+ } /* if widget is drawable */
+
+ return FALSE;
+}
+
+static void
+gtk_image_clear (GtkImage *image)
+{
+ switch (image->storage_type)
+ {
+ case GTK_IMAGE_PIXMAP:
+
+ if (image->data.pixmap.pixmap)
+ g_object_unref (G_OBJECT (image->data.pixmap.pixmap));
+
+ if (image->data.pixmap.mask)
+ g_object_unref (G_OBJECT (image->data.pixmap.mask));
+
+ image->data.pixmap.pixmap = NULL;
+ image->data.pixmap.mask = NULL;
+
+ break;
+
+ case GTK_IMAGE_IMAGE:
+
+ if (image->data.image.image)
+ g_object_unref (G_OBJECT (image->data.image.image));
+
+ if (image->data.image.mask)
+ g_object_unref (G_OBJECT (image->data.image.mask));
+
+ image->data.image.image = NULL;
+ image->data.image.mask = NULL;
+
+ break;
+
+ case GTK_IMAGE_PIXBUF:
+
+ if (image->data.pixbuf.pixbuf)
+ g_object_unref (G_OBJECT (image->data.pixbuf.pixbuf));
+
+ image->data.pixbuf.pixbuf = NULL;
+
+ break;
+
+ case GTK_IMAGE_STOCK:
+
+ g_free (image->data.stock.size);
+ g_free (image->data.stock.stock_id);
+
+ image->data.stock.stock_id = NULL;
+ image->data.stock.size = NULL;
+
+ break;
+
+ case GTK_IMAGE_ICON_SET:
+ if (image->data.icon_set.icon_set)
+ gtk_icon_set_unref (image->data.icon_set.icon_set);
+
+ g_free (image->data.icon_set.size);
+
+ image->data.icon_set.size = NULL;
+ image->data.icon_set.icon_set = NULL;
+
+ break;
+
+ case GTK_IMAGE_EMPTY:
+ default:
+ break;
- if (image->mask)
- {
- gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
- gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
- }
}
- return FALSE;
+ image->storage_type = GTK_IMAGE_EMPTY;
+
+ GTK_WIDGET (image)->requisition.width = 0;
+ GTK_WIDGET (image)->requisition.height = 0;
+
+ if (GTK_WIDGET_VISIBLE (image))
+ gtk_widget_queue_resize (GTK_WIDGET (image));
+}
+
+static void
+gtk_image_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ GtkImage *image;
+ GdkPixbuf *pixbuf = NULL;
+
+ image = GTK_IMAGE (widget);
+
+ switch (image->storage_type)
+ {
+ case GTK_IMAGE_STOCK:
+ pixbuf = gtk_widget_render_stock_icon (GTK_WIDGET (image),
+ image->data.stock.stock_id,
+ image->data.stock.size,
+ NULL);
+ break;
+
+ case GTK_IMAGE_ICON_SET:
+ pixbuf = gtk_icon_set_render_icon (image->data.icon_set.icon_set,
+ widget->style,
+ gtk_widget_get_direction (widget),
+ GTK_WIDGET_STATE (widget),
+ image->data.icon_set.size,
+ widget,
+ NULL);
+ break;
+
+ default:
+ break;
+ }
+
+ if (pixbuf)
+ {
+ gtk_image_update_size (image,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+
+ /* Chain up to default that simply reads current requisition */
+ GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
}
+
+static void
+gtk_image_update_size (GtkImage *image,
+ gint image_width,
+ gint image_height)
+{
+ GTK_WIDGET (image)->requisition.width = image_width + GTK_MISC (image)->xpad * 2;
+ GTK_WIDGET (image)->requisition.height = image_height + GTK_MISC (image)->ypad * 2;
+}
+
+
diff --git a/gtk/gtkimage.h b/gtk/gtkimage.h
index 147a60646..266d032e6 100644
--- a/gtk/gtkimage.h
+++ b/gtk/gtkimage.h
@@ -36,7 +36,6 @@
extern "C" {
#endif /* __cplusplus */
-
#define GTK_TYPE_IMAGE (gtk_image_get_type ())
#define GTK_IMAGE(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_IMAGE, GtkImage))
#define GTK_IMAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_IMAGE, GtkImageClass))
@@ -48,21 +47,122 @@ extern "C" {
typedef struct _GtkImage GtkImage;
typedef struct _GtkImageClass GtkImageClass;
-struct _GtkImage
+typedef struct _GtkImagePixmapData GtkImagePixmapData;
+typedef struct _GtkImageImageData GtkImageImageData;
+typedef struct _GtkImagePixbufData GtkImagePixbufData;
+typedef struct _GtkImageStockData GtkImageStockData;
+typedef struct _GtkImageIconSetData GtkImageIconSetData;
+
+struct _GtkImagePixmapData
{
- GtkMisc misc;
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+};
+struct _GtkImageImageData
+{
GdkImage *image;
GdkBitmap *mask;
};
+struct _GtkImagePixbufData
+{
+ GdkPixbuf *pixbuf;
+};
+
+struct _GtkImageStockData
+{
+ gchar *stock_id;
+ gchar *size;
+};
+
+struct _GtkImageIconSetData
+{
+ GtkIconSet *icon_set;
+ gchar *size;
+};
+
+typedef enum
+{
+ GTK_IMAGE_EMPTY,
+ GTK_IMAGE_PIXMAP,
+ GTK_IMAGE_IMAGE,
+ GTK_IMAGE_PIXBUF,
+ GTK_IMAGE_STOCK,
+ GTK_IMAGE_ICON_SET
+} GtkImageType;
+
+struct _GtkImage
+{
+ GtkMisc misc;
+
+ GtkImageType storage_type;
+
+ union
+ {
+ GtkImagePixmapData pixmap;
+ GtkImageImageData image;
+ GtkImagePixbufData pixbuf;
+ GtkImageStockData stock;
+ GtkImageIconSetData icon_set;
+ } data;
+};
+
struct _GtkImageClass
{
GtkMiscClass parent_class;
};
-
GtkType gtk_image_get_type (void) G_GNUC_CONST;
+
+GtkWidget* gtk_image_new_from_pixmap (GdkPixmap *pixmap,
+ GdkBitmap *mask);
+GtkWidget* gtk_image_new_from_image (GdkImage *image,
+ GdkBitmap *mask);
+GtkWidget* gtk_image_new_from_file (const gchar *filename);
+GtkWidget* gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf);
+GtkWidget* gtk_image_new_from_stock (const gchar *stock_id,
+ const gchar *size);
+GtkWidget* gtk_image_new_from_icon_set (GtkIconSet *icon_set,
+ const gchar *size);
+
+void gtk_image_set_from_pixmap (GtkImage *image,
+ GdkPixmap *pixmap,
+ GdkBitmap *mask);
+void gtk_image_set_from_image (GtkImage *image,
+ GdkImage *gdk_image,
+ GdkBitmap *mask);
+void gtk_image_set_from_file (GtkImage *image,
+ const gchar *filename);
+void gtk_image_set_from_pixbuf (GtkImage *image,
+ GdkPixbuf *pixbuf);
+void gtk_image_set_from_stock (GtkImage *image,
+ const gchar *stock_id,
+ const gchar *size);
+void gtk_image_set_from_icon_set (GtkImage *image,
+ GtkIconSet *icon_set,
+ const gchar *size);
+
+GtkImageType gtk_image_get_storage_type (GtkImage *image);
+
+void gtk_image_get_pixmap (GtkImage *image,
+ GdkPixmap **pixmap,
+ GdkBitmap **mask);
+void gtk_image_get_image (GtkImage *image,
+ GdkImage **gdk_image,
+ GdkBitmap **mask);
+GdkPixbuf* gtk_image_get_pixbuf (GtkImage *image);
+void gtk_image_get_stock (GtkImage *image,
+ gchar **stock_id,
+ gchar **size);
+void gtk_image_get_icon_set (GtkImage *image,
+ GtkIconSet **icon_set,
+ gchar **size);
+
+
+
+/* These three are deprecated */
+
GtkWidget* gtk_image_new (GdkImage *val,
GdkBitmap *mask);
void gtk_image_set (GtkImage *image,
diff --git a/gtk/gtkrc.c b/gtk/gtkrc.c
index 495fbbd41..324e8d3a5 100644
--- a/gtk/gtkrc.c
+++ b/gtk/gtkrc.c
@@ -60,6 +60,7 @@
#include "gtkbindings.h"
#include "gtkthemes.h"
#include "gtkintl.h"
+#include "gtkiconfactory.h"
typedef struct _GtkRcSet GtkRcSet;
typedef struct _GtkRcNode GtkRcNode;
@@ -127,6 +128,9 @@ static void gtk_rc_parse_pixmap_path_string (gchar *pix_path)
static guint gtk_rc_parse_module_path (GScanner *scanner);
static void gtk_rc_parse_module_path_string (gchar *mod_path);
static guint gtk_rc_parse_path_pattern (GScanner *scanner);
+static guint gtk_rc_parse_stock (GScanner *scanner,
+ GtkRcStyle *rc_style,
+ GtkIconFactory *factory);
static void gtk_rc_clear_hash_node (gpointer key,
gpointer data,
gpointer user_data);
@@ -220,6 +224,9 @@ static const struct
{ "highest", GTK_RC_TOKEN_HIGHEST },
{ "engine", GTK_RC_TOKEN_ENGINE },
{ "module_path", GTK_RC_TOKEN_MODULE_PATH },
+ { "stock", GTK_RC_TOKEN_STOCK },
+ { "LTR", GTK_RC_TOKEN_LTR },
+ { "RTL", GTK_RC_TOKEN_RTL }
};
static const guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
@@ -857,8 +864,19 @@ gtk_rc_style_finalize (GObject *object)
tmp_list1 = tmp_list1->next;
}
+
g_slist_free (rc_style->rc_style_lists);
+ tmp_list1 = rc_style->icon_factories;
+ while (tmp_list1)
+ {
+ g_object_unref (G_OBJECT (tmp_list1->data));
+
+ tmp_list1 = tmp_list1->next;
+ }
+
+ g_slist_free (rc_style->icon_factories);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -887,7 +905,7 @@ gtk_rc_style_copy (GtkRcStyle *orig)
{
GtkRcStyle *style;
- g_return_if_fail (GTK_IS_RC_STYLE (orig));
+ g_return_val_if_fail (GTK_IS_RC_STYLE (orig), NULL);
style = GTK_RC_STYLE_GET_CLASS (orig)->clone (orig);
GTK_RC_STYLE_GET_CLASS (style)->merge (style, orig);
@@ -1363,10 +1381,11 @@ gtk_rc_style_to_style (GtkRcStyle *rc_style)
style = GTK_RC_STYLE_GET_CLASS (rc_style)->create_style (rc_style);
style->rc_style = rc_style;
+
gtk_rc_style_ref (rc_style);
- GTK_STYLE_GET_CLASS (style)->init_from_rc (style, rc_style);
-
+ GTK_STYLE_GET_CLASS (style)->init_from_rc (style, rc_style);
+
return style;
}
@@ -1402,13 +1421,13 @@ gtk_rc_init_style (GSList *rc_styles)
while (tmp_styles)
{
GtkRcStyle *rc_style = tmp_styles->data;
-
+
if (G_OBJECT_TYPE (rc_style) != rc_style_type)
{
base_style = rc_style;
break;
}
-
+
tmp_styles = tmp_styles->next;
}
@@ -1419,13 +1438,31 @@ gtk_rc_init_style (GSList *rc_styles)
while (tmp_styles)
{
GtkRcStyle *rc_style = tmp_styles->data;
-
- proto_style_class->merge (proto_style, rc_style);
-
+ GSList *factories;
+
+ proto_style_class->merge (proto_style, rc_style);
+
/* Point from each rc_style to the list of styles */
if (!g_slist_find (rc_style->rc_style_lists, rc_styles))
rc_style->rc_style_lists = g_slist_prepend (rc_style->rc_style_lists, rc_styles);
-
+
+ factories = g_slist_copy (rc_style->icon_factories);
+ if (factories)
+ {
+ GSList *iter;
+
+ iter = factories;
+ while (iter != NULL)
+ {
+ g_object_ref (G_OBJECT (iter->data));
+ iter = g_slist_next (iter);
+ }
+
+ proto_style->icon_factories = g_slist_concat (proto_style->icon_factories,
+ factories);
+
+ }
+
tmp_styles = tmp_styles->next;
}
@@ -1508,6 +1545,7 @@ gtk_rc_parse_style (GScanner *scanner)
guint token;
gint insert;
gint i;
+ GtkIconFactory *our_factory = NULL;
token = g_scanner_get_next_token (scanner);
if (token != GTK_RC_TOKEN_STYLE)
@@ -1519,6 +1557,12 @@ gtk_rc_parse_style (GScanner *scanner)
insert = FALSE;
rc_style = gtk_rc_style_find (scanner->value.v_string);
+
+ /* If there's a list, its first member is always the factory belonging
+ * to this RcStyle
+ */
+ if (rc_style && rc_style->icon_factories)
+ our_factory = rc_style->icon_factories->data;
if (!rc_style)
{
@@ -1532,7 +1576,7 @@ gtk_rc_parse_style (GScanner *scanner)
for (i = 0; i < 5; i++)
rc_style->color_flags[i] = 0;
}
-
+
token = g_scanner_peek_next_token (scanner);
if (token == G_TOKEN_EQUAL_SIGN)
{
@@ -1550,6 +1594,8 @@ gtk_rc_parse_style (GScanner *scanner)
parent_style = gtk_rc_style_find (scanner->value.v_string);
if (parent_style)
{
+ GSList *factories;
+
for (i = 0; i < 5; i++)
{
rc_style->color_flags[i] = parent_style->color_flags[i];
@@ -1575,6 +1621,35 @@ gtk_rc_parse_style (GScanner *scanner)
g_free (rc_style->bg_pixmap_name[i]);
rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
}
+
+ /* Append parent's factories, adding a ref to them */
+ if (parent_style->icon_factories != NULL)
+ {
+ /* Add a factory for ourselves if we have none,
+ * in case we end up defining more stock icons.
+ * I see no real way around this; we need to maintain
+ * the invariant that the first factory in the list
+ * is always our_factory, the one belonging to us,
+ * and if we put parent factories in the list we can't
+ * do that if the style is reopened.
+ */
+ if (our_factory == NULL)
+ {
+ our_factory = gtk_icon_factory_new ();
+ rc_style->icon_factories = g_slist_prepend (rc_style->icon_factories,
+ our_factory);
+ }
+
+ rc_style->icon_factories = g_slist_concat (rc_style->icon_factories,
+ g_slist_copy (parent_style->icon_factories));
+
+ factories = parent_style->icon_factories;
+ while (factories != NULL)
+ {
+ g_object_ref (G_OBJECT (factories->data));
+ factories = factories->next;
+ }
+ }
}
}
@@ -1625,6 +1700,15 @@ gtk_rc_parse_style (GScanner *scanner)
case GTK_RC_TOKEN_ENGINE:
token = gtk_rc_parse_engine (scanner, &rc_style);
break;
+ case GTK_RC_TOKEN_STOCK:
+ if (our_factory == NULL)
+ {
+ our_factory = gtk_icon_factory_new ();
+ rc_style->icon_factories = g_slist_prepend (rc_style->icon_factories,
+ our_factory);
+ }
+ token = gtk_rc_parse_stock (scanner, rc_style, our_factory);
+ break;
default:
g_scanner_get_next_token (scanner);
token = G_TOKEN_RIGHT_CURLY;
@@ -2502,6 +2586,270 @@ gtk_rc_parse_path_pattern (GScanner *scanner)
return G_TOKEN_NONE;
}
+static guint
+gtk_rc_parse_stock_id (GScanner *scanner,
+ gchar **stock_id)
+{
+ guint token;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_LEFT_BRACE)
+ return G_TOKEN_LEFT_BRACE;
+
+ token = g_scanner_get_next_token (scanner);
+
+ if (token != G_TOKEN_STRING)
+ return G_TOKEN_STRING;
+
+ *stock_id = g_strdup (scanner->value.v_string);
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_RIGHT_BRACE)
+ {
+ g_free (*stock_id);
+ return G_TOKEN_RIGHT_BRACE;
+ }
+
+ return G_TOKEN_NONE;
+}
+
+static void
+cleanup_source (GtkIconSource *source)
+{
+ g_free (source->filename);
+ g_free (source->size);
+}
+
+static guint
+gtk_rc_parse_icon_source (GScanner *scanner,
+ GtkIconSet *icon_set)
+{
+ guint token;
+ GtkIconSource source = { NULL, NULL,
+ 0, 0, 0,
+ TRUE, TRUE, TRUE };
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_LEFT_CURLY)
+ return G_TOKEN_LEFT_CURLY;
+
+ token = g_scanner_get_next_token (scanner);
+
+ if (token != G_TOKEN_STRING)
+ return G_TOKEN_STRING;
+
+ source.filename = g_strdup (scanner->value.v_string);
+
+ token = g_scanner_get_next_token (scanner);
+
+ if (token == G_TOKEN_RIGHT_CURLY)
+ {
+ gtk_icon_set_add_source (icon_set, &source);
+ cleanup_source (&source);
+ return G_TOKEN_NONE;
+ }
+ else if (token != G_TOKEN_COMMA)
+ {
+ cleanup_source (&source);
+ return G_TOKEN_COMMA;
+ }
+
+ /* Get the direction */
+
+ token = g_scanner_get_next_token (scanner);
+
+ switch (token)
+ {
+ case GTK_RC_TOKEN_RTL:
+ source.any_direction = FALSE;
+ source.direction = GTK_TEXT_DIR_RTL;
+ break;
+
+ case GTK_RC_TOKEN_LTR:
+ source.any_direction = FALSE;
+ source.direction = GTK_TEXT_DIR_LTR;
+ break;
+
+ case '*':
+ break;
+
+ default:
+ cleanup_source (&source);
+ return GTK_RC_TOKEN_RTL;
+ break;
+ }
+
+ token = g_scanner_get_next_token (scanner);
+
+ if (token == G_TOKEN_RIGHT_CURLY)
+ {
+ gtk_icon_set_add_source (icon_set, &source);
+ cleanup_source (&source);
+ return G_TOKEN_NONE;
+ }
+ else if (token != G_TOKEN_COMMA)
+ {
+ cleanup_source (&source);
+ return G_TOKEN_COMMA;
+ }
+
+ /* Get the state */
+
+ token = g_scanner_get_next_token (scanner);
+
+ switch (token)
+ {
+ case GTK_RC_TOKEN_NORMAL:
+ source.any_state = FALSE;
+ source.state = GTK_STATE_NORMAL;
+ break;
+
+ case GTK_RC_TOKEN_PRELIGHT:
+ source.any_state = FALSE;
+ source.state = GTK_STATE_PRELIGHT;
+ break;
+
+
+ case GTK_RC_TOKEN_INSENSITIVE:
+ source.any_state = FALSE;
+ source.state = GTK_STATE_INSENSITIVE;
+ break;
+
+ case GTK_RC_TOKEN_ACTIVE:
+ source.any_state = FALSE;
+ source.state = GTK_STATE_ACTIVE;
+ break;
+
+ case GTK_RC_TOKEN_SELECTED:
+ source.any_state = FALSE;
+ source.state = GTK_STATE_SELECTED;
+ break;
+
+ case '*':
+ break;
+
+ default:
+ cleanup_source (&source);
+ return GTK_RC_TOKEN_PRELIGHT;
+ break;
+ }
+
+ token = g_scanner_get_next_token (scanner);
+
+ if (token == G_TOKEN_RIGHT_CURLY)
+ {
+ gtk_icon_set_add_source (icon_set, &source);
+ cleanup_source (&source);
+ return G_TOKEN_NONE;
+ }
+ else if (token != G_TOKEN_COMMA)
+ {
+ cleanup_source (&source);
+ return G_TOKEN_COMMA;
+ }
+
+ /* Get the size */
+
+ token = g_scanner_get_next_token (scanner);
+
+ if (token != '*')
+ {
+ if (token != G_TOKEN_STRING)
+ {
+ cleanup_source (&source);
+ return G_TOKEN_STRING;
+ }
+
+ source.size = g_strdup (scanner->value.v_string);
+ source.any_size = FALSE;
+ }
+
+ /* Check the close brace */
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_RIGHT_CURLY)
+ {
+ cleanup_source (&source);
+ return G_TOKEN_RIGHT_CURLY;
+ }
+
+ gtk_icon_set_add_source (icon_set, &source);
+
+ cleanup_source (&source);
+
+ return G_TOKEN_NONE;
+}
+
+static guint
+gtk_rc_parse_stock (GScanner *scanner,
+ GtkRcStyle *rc_style,
+ GtkIconFactory *factory)
+{
+ GtkIconSet *icon_set = NULL;
+ gchar *stock_id = NULL;
+ guint token;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_STOCK)
+ return GTK_RC_TOKEN_STOCK;
+
+ token = gtk_rc_parse_stock_id (scanner, &stock_id);
+ if (token != G_TOKEN_NONE)
+ return token;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_EQUAL_SIGN)
+ {
+ g_free (stock_id);
+ return G_TOKEN_EQUAL_SIGN;
+ }
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_LEFT_CURLY)
+ {
+ g_free (stock_id);
+ return G_TOKEN_LEFT_CURLY;
+ }
+
+ token = g_scanner_peek_next_token (scanner);
+ while (token != G_TOKEN_RIGHT_CURLY)
+ {
+ if (icon_set == NULL)
+ icon_set = gtk_icon_set_new ();
+
+ token = gtk_rc_parse_icon_source (scanner, icon_set);
+ if (token != G_TOKEN_NONE)
+ {
+ g_free (stock_id);
+ gtk_icon_set_unref (icon_set);
+ return token;
+ }
+
+ token = g_scanner_get_next_token (scanner);
+
+ if (token != G_TOKEN_COMMA &&
+ token != G_TOKEN_RIGHT_CURLY)
+ {
+ g_free (stock_id);
+ gtk_icon_set_unref (icon_set);
+ return G_TOKEN_RIGHT_CURLY;
+ }
+ }
+
+ if (icon_set)
+ {
+ gtk_icon_factory_add (factory,
+ stock_id,
+ icon_set);
+
+ gtk_icon_set_unref (icon_set);
+ }
+
+ g_free (stock_id);
+
+ return G_TOKEN_NONE;
+}
+
/*
typedef GdkPixmap * (*GtkImageLoader) (GdkWindow *window,
GdkColormap *colormap,
diff --git a/gtk/gtkrc.h b/gtk/gtkrc.h
index a1a98f227..0b3703931 100644
--- a/gtk/gtkrc.h
+++ b/gtk/gtkrc.h
@@ -35,6 +35,9 @@
extern "C" {
#endif /* __cplusplus */
+/* Forward declaration */
+typedef struct _GtkIconFactory GtkIconFactory;
+
#define GTK_TYPE_RC_STYLE (gtk_rc_style_get_type ())
#define GTK_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_RC_STYLE, GtkRcStyle))
#define GTK_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_RC_STYLE, GtkRcStyleClass))
@@ -70,11 +73,13 @@ struct _GtkRcStyle
gint xthickness;
gint ythickness;
-
+
/*< private >*/
/* list of RC style lists including this RC style */
GSList *rc_style_lists;
+
+ GSList *icon_factories;
};
struct _GtkRcStyleClass
@@ -177,6 +182,9 @@ typedef enum {
GTK_RC_TOKEN_HIGHEST,
GTK_RC_TOKEN_ENGINE,
GTK_RC_TOKEN_MODULE_PATH,
+ GTK_RC_TOKEN_STOCK,
+ GTK_RC_TOKEN_LTR,
+ GTK_RC_TOKEN_RTL,
GTK_RC_TOKEN_LAST
} GtkRcTokenType;
diff --git a/gtk/gtkstock.c b/gtk/gtkstock.c
new file mode 100644
index 000000000..ecb307973
--- /dev/null
+++ b/gtk/gtkstock.c
@@ -0,0 +1,198 @@
+/* GTK - The GIMP Toolkit
+ * 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 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.
+ */
+
+/*
+ * 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/.
+ */
+
+#include "gtkstock.h"
+#include "gtkintl.h"
+#include <gdk/gdkkeysyms.h>
+
+static GHashTable *stock_hash = NULL;
+static void init_stock_hash (void);
+
+static void
+real_add (const GtkStockItem *items,
+ guint n_items,
+ gboolean copy)
+{
+ int i;
+
+ init_stock_hash ();
+
+ if (n_items == 0)
+ return;
+
+ i = 0;
+ while (i < n_items)
+ {
+ gpointer old_key, old_value;
+ const GtkStockItem *item = &items[i];
+ if (copy)
+ item = gtk_stock_item_copy (item);
+
+ if (g_hash_table_lookup_extended (stock_hash, item->stock_id,
+ &old_key, &old_value))
+ {
+ g_hash_table_remove (stock_hash, old_key);
+ gtk_stock_item_free (old_value);
+ }
+
+ g_hash_table_insert (stock_hash,
+ (gchar*)item->stock_id, (GtkStockItem*)item);
+
+ ++i;
+ }
+}
+
+void
+gtk_stock_add (const GtkStockItem *items,
+ guint n_items)
+{
+ g_return_if_fail (items != NULL);
+
+ real_add (items, n_items, TRUE);
+}
+
+void
+gtk_stock_add_static (const GtkStockItem *items,
+ guint n_items)
+{
+ g_return_if_fail (items != NULL);
+
+ real_add (items, n_items, FALSE);
+}
+
+gboolean
+gtk_stock_lookup (const gchar *stock_id,
+ GtkStockItem *item)
+{
+ const GtkStockItem *found;
+
+ g_return_val_if_fail (stock_id != NULL, FALSE);
+ g_return_val_if_fail (item != NULL, FALSE);
+
+ init_stock_hash ();
+
+ found = g_hash_table_lookup (stock_hash, stock_id);
+
+ if (found)
+ {
+ *item = *found;
+ if (item->label)
+ item->label = dgettext (item->translation_domain, item->label);
+ }
+
+ return found != NULL;
+}
+
+static void
+listify_foreach (gpointer key, gpointer value, gpointer data)
+{
+ GSList **list = data;
+
+ *list = g_slist_prepend (*list, value);
+}
+
+static GSList *
+g_hash_table_get_values (GHashTable *table)
+{
+ GSList *list = NULL;
+
+ g_hash_table_foreach (table, listify_foreach, &list);
+
+ return list;
+}
+
+GSList *
+gtk_stock_list_items (void)
+{
+ init_stock_hash ();
+
+ return g_hash_table_get_values (stock_hash);
+}
+
+GtkStockItem *
+gtk_stock_item_copy (const GtkStockItem *item)
+{
+ GtkStockItem *copy;
+
+ g_return_val_if_fail (item != NULL, NULL);
+
+ copy = g_new (GtkStockItem, 1);
+
+ *copy = *item;
+
+ copy->stock_id = g_strdup (item->stock_id);
+ copy->label = g_strdup (item->label);
+ copy->translation_domain = g_strdup (item->translation_domain);
+
+ return copy;
+}
+
+void
+gtk_stock_item_free (GtkStockItem *item)
+{
+ g_return_if_fail (item != NULL);
+
+ g_free ((gchar*)item->stock_id);
+ g_free ((gchar*)item->label);
+ g_free ((gchar*)item->translation_domain);
+
+ g_free (item);
+}
+
+static GtkStockItem builtin_items [] =
+{
+ /* KEEP IN SYNC with gtkiconfactory.c stock icons */
+
+ { GTK_STOCK_DIALOG_INFO, N_("Information"), 0, 0, GETTEXT_PACKAGE },
+ { GTK_STOCK_DIALOG_WARNING, N_("Warning"), 0, 0, GETTEXT_PACKAGE },
+ { GTK_STOCK_DIALOG_ERROR, N_("Error"), 0, 0, GETTEXT_PACKAGE },
+ { GTK_STOCK_DIALOG_QUESTION, N_("Question"), 0, 0, GETTEXT_PACKAGE },
+
+ { GTK_STOCK_BUTTON_APPLY, N_("_Apply"), 0, 0, GETTEXT_PACKAGE },
+ { GTK_STOCK_BUTTON_OK, N_("OK"), 0, 0, GETTEXT_PACKAGE },
+ { GTK_STOCK_BUTTON_CANCEL, N_("Cancel"), 0, 0, GETTEXT_PACKAGE },
+ { GTK_STOCK_BUTTON_CLOSE, N_("_Close"), 0, 0, GETTEXT_PACKAGE },
+ { GTK_STOCK_BUTTON_YES, N_("_Yes"), 0, 0, GETTEXT_PACKAGE },
+ { GTK_STOCK_BUTTON_NO, N_("_No"), 0, 0, GETTEXT_PACKAGE },
+
+ { GTK_STOCK_CLOSE, N_("Close"), GDK_CONTROL_MASK, 'w', GETTEXT_PACKAGE },
+ { GTK_STOCK_QUIT, N_("Quit"), GDK_CONTROL_MASK, 'q', GETTEXT_PACKAGE },
+ { GTK_STOCK_HELP, N_("Help"), GDK_CONTROL_MASK, 'h', GETTEXT_PACKAGE },
+ { GTK_STOCK_NEW, N_("New"), GDK_CONTROL_MASK, 'n', GETTEXT_PACKAGE },
+ { GTK_STOCK_OPEN, N_("Open"), GDK_CONTROL_MASK, 'o', GETTEXT_PACKAGE },
+ { GTK_STOCK_SAVE, N_("Save"), GDK_CONTROL_MASK, 's', GETTEXT_PACKAGE }
+};
+
+static void
+init_stock_hash (void)
+{
+ if (stock_hash == NULL)
+ {
+ stock_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ gtk_stock_add_static (builtin_items, G_N_ELEMENTS (builtin_items));
+ }
+}
diff --git a/gtk/gtkstock.h b/gtk/gtkstock.h
new file mode 100644
index 000000000..02b51ff97
--- /dev/null
+++ b/gtk/gtkstock.h
@@ -0,0 +1,89 @@
+/* GTK - The GIMP Toolkit
+ * 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 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.
+ */
+
+/*
+ * 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/.
+ */
+
+#ifndef __GTK_STOCK_H__
+#define __GTK_STOCK_H__
+
+
+#include <gdk/gdk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GtkStockItem GtkStockItem;
+
+struct _GtkStockItem
+{
+ gchar *stock_id;
+ gchar *label;
+ GdkModifierType modifier;
+ guint keyval;
+ gchar *translation_domain;
+};
+
+void gtk_stock_add (const GtkStockItem *item,
+ guint n_items);
+void gtk_stock_add_static (const GtkStockItem *item,
+ guint n_items);
+gboolean gtk_stock_lookup (const gchar *stock_id,
+ GtkStockItem *item);
+
+/* Should free the list, but DO NOT modify the items in the list.
+ * This function is only useful for GUI builders and such.
+ */
+GSList* gtk_stock_list_items (void);
+
+GtkStockItem *gtk_stock_item_copy (const GtkStockItem *item);
+void gtk_stock_item_free (GtkStockItem *item);
+
+
+/* Stock IDs */
+#define GTK_STOCK_DIALOG_INFO "gtk-dialog-info"
+#define GTK_STOCK_DIALOG_WARNING "gtk-dialog-warning"
+#define GTK_STOCK_DIALOG_ERROR "gtk-dialog-error"
+#define GTK_STOCK_DIALOG_QUESTION "gtk-dialog-question"
+
+#define GTK_STOCK_BUTTON_APPLY "gtk-button-apply"
+#define GTK_STOCK_BUTTON_OK "gtk-button-ok"
+#define GTK_STOCK_BUTTON_CANCEL "gtk-button-cancel"
+#define GTK_STOCK_BUTTON_CLOSE "gtk-button-close"
+#define GTK_STOCK_BUTTON_YES "gtk-button-yes"
+#define GTK_STOCK_BUTTON_NO "gtk-button-no"
+
+#define GTK_STOCK_CLOSE "gtk-close"
+#define GTK_STOCK_QUIT "gtk-quit"
+#define GTK_STOCK_HELP "gtk-help"
+#define GTK_STOCK_NEW "gtk-new"
+#define GTK_STOCK_OPEN "gtk-open"
+#define GTK_STOCK_SAVE "gtk-save"
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_STOCK_H__ */
diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c
index a7c1b6880..087bcb12e 100644
--- a/gtk/gtkstyle.c
+++ b/gtk/gtkstyle.c
@@ -31,7 +31,7 @@
#include "gtkstyle.h"
#include "gtkwidget.h"
#include "gtkthemes.h"
-
+#include "gtkiconfactory.h"
#define LIGHTNESS_MULT 1.3
#define DARKNESS_MULT 0.7
@@ -56,7 +56,16 @@ static void gtk_style_real_set_background (GtkStyle *style,
GtkStateType state_type);
static GtkStyle *gtk_style_real_clone (GtkStyle *style);
static void gtk_style_real_init_from_rc (GtkStyle *style,
- GtkRcStyle *rc_style);
+ GtkRcStyle *rc_style);
+
+
+static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
+ const GtkIconSource *source,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size,
+ GtkWidget *widget,
+ const gchar *detail);
static void gtk_default_draw_hline (GtkStyle *style,
GdkWindow *window,
@@ -445,7 +454,8 @@ gtk_style_class_init (GtkStyleClass *klass)
klass->realize = gtk_style_real_realize;
klass->unrealize = gtk_style_real_unrealize;
klass->set_background = gtk_style_real_set_background;
-
+ klass->render_icon = gtk_default_render_icon;
+
klass->draw_hline = gtk_default_draw_hline;
klass->draw_vline = gtk_default_draw_vline;
klass->draw_shadow = gtk_default_draw_shadow;
@@ -521,7 +531,7 @@ gtk_style_duplicate (GtkStyle *style)
{
GtkStyle *new_style;
- g_return_val_if_fail (style != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
new_style = gtk_style_copy (style);
@@ -582,7 +592,7 @@ gtk_style_attach (GtkStyle *style,
GtkStyle *new_style = NULL;
GdkColormap *colormap;
- g_return_val_if_fail (style != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
g_return_val_if_fail (window != NULL, NULL);
colormap = gdk_window_get_colormap (window);
@@ -632,7 +642,7 @@ gtk_style_attach (GtkStyle *style,
void
gtk_style_detach (GtkStyle *style)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
style->attach_count -= 1;
if (style->attach_count == 0)
@@ -659,7 +669,7 @@ static void
gtk_style_realize (GtkStyle *style,
GdkColormap *colormap)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
style->colormap = colormap;
style->depth = gdk_colormap_get_visual (colormap)->depth;
@@ -667,6 +677,31 @@ gtk_style_realize (GtkStyle *style,
GTK_STYLE_GET_CLASS (style)->realize (style);
}
+GtkIconSet*
+gtk_style_lookup_icon_set (GtkStyle *style,
+ const char *stock_id)
+{
+ GSList *iter;
+
+ g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
+ g_return_val_if_fail (stock_id != NULL, NULL);
+
+ iter = style->icon_factories;
+ while (iter != NULL)
+ {
+ GtkIconSet *icon_set =
+ gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
+ stock_id);
+
+ if (icon_set)
+ return icon_set;
+
+ iter = g_slist_next (iter);
+ }
+
+ return gtk_icon_factory_lookup_default (stock_id);
+}
+
void
gtk_draw_hline (GtkStyle *style,
GdkWindow *window,
@@ -675,7 +710,7 @@ gtk_draw_hline (GtkStyle *style,
gint x2,
gint y)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, NULL, NULL, NULL, x1, x2, y);
@@ -690,7 +725,7 @@ gtk_draw_vline (GtkStyle *style,
gint y2,
gint x)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, NULL, NULL, NULL, y1, y2, x);
@@ -707,7 +742,7 @@ gtk_draw_shadow (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
@@ -722,7 +757,7 @@ gtk_draw_polygon (GtkStyle *style,
gint npoints,
gboolean fill)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, NULL, NULL, NULL, points, npoints, fill);
@@ -740,7 +775,7 @@ gtk_draw_arrow (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, fill, x, y, width, height);
@@ -757,7 +792,7 @@ gtk_draw_diamond (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
@@ -774,7 +809,7 @@ gtk_draw_oval (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_oval != NULL);
GTK_STYLE_GET_CLASS (style)->draw_oval (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
@@ -788,7 +823,7 @@ gtk_draw_string (GtkStyle *style,
gint y,
const gchar *string)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, NULL, NULL, NULL, x, y, string);
@@ -804,7 +839,7 @@ gtk_draw_box (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
@@ -820,7 +855,7 @@ gtk_draw_flat_box (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
@@ -836,7 +871,7 @@ gtk_draw_check (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
@@ -852,7 +887,7 @@ gtk_draw_option (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
@@ -868,7 +903,7 @@ gtk_draw_cross (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_cross != NULL);
GTK_STYLE_GET_CLASS (style)->draw_cross (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
@@ -885,7 +920,7 @@ gtk_draw_ramp (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_ramp != NULL);
GTK_STYLE_GET_CLASS (style)->draw_ramp (style, window, state_type, shadow_type, NULL, NULL, NULL, arrow_type, x, y, width, height);
@@ -901,7 +936,7 @@ gtk_draw_tab (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height);
@@ -920,7 +955,7 @@ gtk_draw_shadow_gap (GtkStyle *style,
gint gap_x,
gint gap_width)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
@@ -939,7 +974,7 @@ gtk_draw_box_gap (GtkStyle *style,
gint gap_x,
gint gap_width)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side, gap_x, gap_width);
@@ -956,7 +991,7 @@ gtk_draw_extension (GtkStyle *style,
gint height,
GtkPositionType gap_side)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, gap_side);
@@ -970,7 +1005,7 @@ gtk_draw_focus (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, NULL, NULL, NULL, x, y, width, height);
@@ -987,7 +1022,7 @@ gtk_draw_slider (GtkStyle *style,
gint height,
GtkOrientation orientation)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
@@ -1004,7 +1039,7 @@ gtk_draw_handle (GtkStyle *style,
gint height,
GtkOrientation orientation)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, NULL, NULL, NULL, x, y, width, height, orientation);
@@ -1015,7 +1050,7 @@ gtk_style_set_background (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
@@ -1103,6 +1138,22 @@ gtk_style_real_init_from_rc (GtkStyle *style,
style->xthickness = rc_style->xthickness;
if (rc_style->ythickness >= 0)
style->ythickness = rc_style->ythickness;
+
+
+ if (rc_style->icon_factories)
+ {
+ GSList *iter;
+
+ style->icon_factories = g_slist_copy (rc_style->icon_factories);
+
+ iter = style->icon_factories;
+ while (iter != NULL)
+ {
+ g_object_ref (G_OBJECT (iter->data));
+
+ iter = g_slist_next (iter);
+ }
+ }
}
static void
@@ -1241,6 +1292,29 @@ gtk_style_real_set_background (GtkStyle *style,
gdk_window_set_background (window, &style->bg[state_type]);
}
+GdkPixbuf *
+gtk_style_render_icon (GtkStyle *style,
+ const GtkIconSource *source,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size,
+ GtkWidget *widget,
+ const gchar *detail)
+{
+ GdkPixbuf *pixbuf;
+
+ g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
+ g_return_val_if_fail (GTK_STYLE_GET_CLASS (style)->render_icon != NULL, NULL);
+
+ pixbuf = GTK_STYLE_GET_CLASS (style)->render_icon (style, source, direction, state,
+ size, widget, detail);
+
+ g_return_val_if_fail (pixbuf != NULL, NULL);
+
+ return pixbuf;
+}
+
+/* Default functions */
void
gtk_style_apply_default_background (GtkStyle *style,
GdkWindow *window,
@@ -1305,6 +1379,92 @@ gtk_style_apply_default_background (GtkStyle *style,
}
}
+static GdkPixbuf*
+scale_or_ref (GdkPixbuf *src,
+ gint width,
+ gint height)
+{
+ if (width == gdk_pixbuf_get_width (src) &&
+ height == gdk_pixbuf_get_height (src))
+ {
+ gdk_pixbuf_ref (src);
+ return src;
+ }
+ else
+ {
+ return gdk_pixbuf_scale_simple (src,
+ width, height,
+ GDK_INTERP_BILINEAR);
+ }
+}
+
+static GdkPixbuf *
+gtk_default_render_icon (GtkStyle *style,
+ const GtkIconSource *source,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size,
+ GtkWidget *widget,
+ const gchar *detail)
+{
+ gint width = 1;
+ gint height = 1;
+ GdkPixbuf *scaled;
+ GdkPixbuf *stated;
+
+ /* Oddly, style can be NULL in this function, because
+ * GtkIconSet can be used without a style and if so
+ * it uses this function.
+ */
+
+ g_return_val_if_fail (source->pixbuf != NULL, NULL);
+
+ if (!gtk_icon_size_lookup (size, &width, &height))
+ {
+ g_warning ("Bad icon size '%s' passed to render_icon", size);
+ return NULL;
+ }
+
+ /* If the size was wildcarded, then scale; otherwise, leave it
+ * alone.
+ */
+ if (source->any_size)
+ scaled = scale_or_ref (source->pixbuf, width, height);
+ else
+ scaled = GDK_PIXBUF (g_object_ref (G_OBJECT (source->pixbuf)));
+
+ /* If the state was wildcarded, then generate a state. */
+ if (source->any_state)
+ {
+ if (state == GTK_STATE_INSENSITIVE)
+ {
+ stated = gdk_pixbuf_copy (scaled);
+
+ gdk_pixbuf_saturate_and_pixelate (scaled, stated,
+ 0.8, TRUE);
+
+ gdk_pixbuf_unref (scaled);
+ }
+ else if (state == GTK_STATE_PRELIGHT)
+ {
+ stated = gdk_pixbuf_copy (scaled);
+
+ gdk_pixbuf_saturate_and_pixelate (scaled, stated,
+ 1.2, FALSE);
+
+ gdk_pixbuf_unref (scaled);
+ }
+ else
+ {
+ stated = scaled;
+ }
+ }
+ else
+ stated = scaled;
+
+ return stated;
+}
+
static void
gtk_default_draw_hline (GtkStyle *style,
GdkWindow *window,
@@ -1320,7 +1480,7 @@ gtk_default_draw_hline (GtkStyle *style,
gint thickness_dark;
gint i;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
thickness_light = style->ythickness / 2;
@@ -1377,7 +1537,7 @@ gtk_default_draw_vline (GtkStyle *style,
gint thickness_dark;
gint i;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
thickness_light = style->xthickness / 2;
@@ -1427,7 +1587,7 @@ gtk_default_draw_shadow (GtkStyle *style,
gint thickness_dark;
gint i;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
if ((width == -1) && (height == -1))
@@ -1606,7 +1766,7 @@ gtk_default_draw_polygon (GtkStyle *style,
gint yadjust;
gint i;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
g_return_if_fail (points != NULL);
@@ -1740,7 +1900,7 @@ gtk_default_draw_arrow (GtkStyle *style,
gint half_height;
GdkPoint points[3];
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
switch (shadow_type)
@@ -2086,7 +2246,7 @@ gtk_default_draw_diamond (GtkStyle *style,
gint half_width;
gint half_height;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
if ((width == -1) && (height == -1))
@@ -2211,7 +2371,7 @@ gtk_default_draw_oval (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
g_warning ("gtk_default_draw_oval(): FIXME, this function is currently unimplemented");
@@ -2228,7 +2388,7 @@ gtk_default_draw_string (GtkStyle *style,
gint y,
const gchar *string)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
if (area)
@@ -2262,7 +2422,7 @@ gtk_default_draw_box (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
if (width == -1 && height == -1)
@@ -2307,7 +2467,7 @@ gtk_default_draw_flat_box (GtkStyle *style,
{
GdkGC *gc1;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
if (width == -1 && height == -1)
@@ -2400,7 +2560,7 @@ gtk_default_draw_cross (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
g_warning ("gtk_default_draw_cross(): FIXME, this function is currently unimplemented");
@@ -2420,7 +2580,7 @@ gtk_default_draw_ramp (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
g_warning ("gtk_default_draw_ramp(): FIXME, this function is currently unimplemented");
@@ -2439,7 +2599,7 @@ gtk_default_draw_tab (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail,
@@ -2467,7 +2627,7 @@ gtk_default_draw_shadow_gap (GtkStyle *style,
GdkGC *gc3 = NULL;
GdkGC *gc4 = NULL;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
if (width == -1 && height == -1)
@@ -2688,7 +2848,7 @@ gtk_default_draw_box_gap (GtkStyle *style,
GdkGC *gc3 = NULL;
GdkGC *gc4 = NULL;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
gtk_style_apply_default_background (style, window,
@@ -2912,7 +3072,7 @@ gtk_default_draw_extension (GtkStyle *style,
GdkGC *gc3 = NULL;
GdkGC *gc4 = NULL;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
gtk_style_apply_default_background (style, window,
@@ -3084,7 +3244,7 @@ gtk_default_draw_focus (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
if (width == -1 && height == -1)
@@ -3143,7 +3303,7 @@ gtk_default_draw_slider (GtkStyle *style,
gint height,
GtkOrientation orientation)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
if (width == -1 && height == -1)
@@ -3214,7 +3374,7 @@ gtk_default_draw_handle (GtkStyle *style,
GdkRectangle dest;
gint intersect;
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (window != NULL);
if (width == -1 && height == -1)
@@ -3488,7 +3648,7 @@ gtk_paint_hline (GtkStyle *style,
gint x2,
gint y)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
@@ -3505,7 +3665,7 @@ gtk_paint_vline (GtkStyle *style,
gint y2,
gint x)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1, y2, x);
@@ -3524,7 +3684,7 @@ gtk_paint_shadow (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
@@ -3542,7 +3702,7 @@ gtk_paint_polygon (GtkStyle *style,
gint npoints,
gboolean fill)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
@@ -3563,7 +3723,7 @@ gtk_paint_arrow (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
@@ -3582,7 +3742,7 @@ gtk_paint_diamond (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
@@ -3601,7 +3761,7 @@ gtk_paint_oval (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_oval != NULL);
GTK_STYLE_GET_CLASS (style)->draw_oval (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
@@ -3618,7 +3778,7 @@ gtk_paint_string (GtkStyle *style,
gint y,
const gchar *string)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
@@ -3637,7 +3797,7 @@ gtk_paint_box (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
@@ -3656,7 +3816,7 @@ gtk_paint_flat_box (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
@@ -3675,7 +3835,7 @@ gtk_paint_check (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
@@ -3694,7 +3854,7 @@ gtk_paint_option (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
@@ -3713,7 +3873,7 @@ gtk_paint_cross (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_cross != NULL);
GTK_STYLE_GET_CLASS (style)->draw_cross (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
@@ -3733,7 +3893,7 @@ gtk_paint_ramp (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_ramp != NULL);
GTK_STYLE_GET_CLASS (style)->draw_ramp (style, window, state_type, shadow_type, area, widget, detail, arrow_type, x, y, width, height);
@@ -3752,7 +3912,7 @@ gtk_paint_tab (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
@@ -3774,7 +3934,7 @@ gtk_paint_shadow_gap (GtkStyle *style,
gint gap_x,
gint gap_width)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
@@ -3797,7 +3957,7 @@ gtk_paint_box_gap (GtkStyle *style,
gint gap_x,
gint gap_width)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
@@ -3817,7 +3977,7 @@ gtk_paint_extension (GtkStyle *style,
gint height,
GtkPositionType gap_side)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
@@ -3834,7 +3994,7 @@ gtk_paint_focus (GtkStyle *style,
gint width,
gint height)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, area, widget, detail, x, y, width, height);
@@ -3854,7 +4014,7 @@ gtk_paint_slider (GtkStyle *style,
gint height,
GtkOrientation orientation)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
@@ -3874,7 +4034,7 @@ gtk_paint_handle (GtkStyle *style,
gint height,
GtkOrientation orientation)
{
- g_return_if_fail (style != NULL);
+ g_return_if_fail (GTK_IS_STYLE (style));
g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
diff --git a/gtk/gtkstyle.h b/gtk/gtkstyle.h
index e23203a1c..842712730 100644
--- a/gtk/gtkstyle.h
+++ b/gtk/gtkstyle.h
@@ -51,7 +51,8 @@ typedef struct _GtkStyleClass GtkStyleClass;
*/
typedef struct _GtkThemeEngine GtkThemeEngine;
typedef struct _GtkRcStyle GtkRcStyle;
-
+typedef struct _GtkIconSet GtkIconSet;
+typedef struct _GtkIconSource GtkIconSource;
/* We make this forward declaration here, since we pass
* GtkWidgt's to the draw functions.
@@ -110,6 +111,8 @@ struct _GtkStyle
* was created
*/
GSList *styles;
+
+ GSList *icon_factories;
};
struct _GtkStyleClass
@@ -149,8 +152,18 @@ struct _GtkStyleClass
GdkWindow *window,
GtkStateType state_type);
+
+ GdkPixbuf * (* render_icon) (GtkStyle *style,
+ const GtkIconSource *source,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar *size,
+ GtkWidget *widget,
+ const gchar *detail);
+
/* Drawing functions
*/
+
void (*draw_hline) (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
@@ -408,6 +421,15 @@ void gtk_style_apply_default_background (GtkStyle *style,
gint width,
gint height);
+GtkIconSet* gtk_style_lookup_icon_set (GtkStyle *style,
+ const gchar *stock_id);
+GdkPixbuf * gtk_style_render_icon (GtkStyle *style,
+ const GtkIconSource *source,
+ GtkTextDirection direction,
+ GtkStateType state,
+ const gchar * size,
+ GtkWidget *widget,
+ const gchar *detail);
void gtk_draw_hline (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
@@ -815,6 +837,7 @@ void gtk_paint_handle (GtkStyle *style,
gint height,
GtkOrientation orientation);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index bd084de24..ed19d79e4 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <locale.h>
#include "gtkcontainer.h"
+#include "gtkiconfactory.h"
#include "gtkmain.h"
#include "gtkrc.h"
#include "gtkselection.h"
@@ -3541,6 +3542,37 @@ gtk_widget_create_pango_layout (GtkWidget *widget,
return layout;
}
+GdkPixbuf*
+gtk_widget_render_stock_icon (GtkWidget *widget,
+ const gchar *stock_id,
+ const gchar *size,
+ const gchar *detail)
+{
+ GtkIconSet *icon_set;
+ GdkPixbuf *retval;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+ g_return_val_if_fail (stock_id != NULL, NULL);
+ g_return_val_if_fail (size != NULL, NULL);
+
+ gtk_widget_ensure_style (widget);
+
+ icon_set = gtk_style_lookup_icon_set (widget->style, stock_id);
+
+ if (icon_set == NULL)
+ return NULL;
+
+ retval = gtk_icon_set_render_icon (icon_set,
+ widget->style,
+ gtk_widget_get_direction (widget),
+ GTK_WIDGET_STATE (widget),
+ size,
+ widget,
+ detail);
+
+ return retval;
+}
+
/*************************************************************
* gtk_widget_set_parent_window:
* Set a non default parent window for widget
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 4e2a87e7f..b55a2a1b9 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -606,6 +606,11 @@ PangoContext *gtk_widget_get_pango_context (GtkWidget *widget);
PangoLayout *gtk_widget_create_pango_layout (GtkWidget *widget,
const gchar *text);
+GdkPixbuf* gtk_widget_render_stock_icon (GtkWidget *widget,
+ const gchar *stock_id,
+ const gchar *size,
+ const gchar *detail);
+
/* handle composite names for GTK_COMPOSITE_CHILD widgets,
* the returned name is newly allocated.
*/
diff --git a/gtk/stock-icons/Makefile.am b/gtk/stock-icons/Makefile.am
new file mode 100644
index 000000000..3bf0d5074
--- /dev/null
+++ b/gtk/stock-icons/Makefile.am
@@ -0,0 +1,23 @@
+BUILT_SOURCES=gtkstockpixbufs.h
+
+IMAGES= dialog_error.png dialog_info.png dialog_question.png dialog_warning.png stock_button_apply.png stock_button_cancel.png stock_button_close.png stock_button_no.png stock_button_ok.png stock_button_yes.png stock_close.png stock_exit.png stock_help.png stock_new.png stock_open.png stock_save.png
+
+VARIABLES= dialog_error dialog_error.png \
+ dialog_info dialog_info.png \
+ dialog_question dialog_question.png \
+ dialog_warning dialog_warning.png \
+ stock_button_apply stock_button_apply.png \
+ stock_button_cancel stock_button_cancel.png \
+ stock_button_close stock_button_close.png \
+ stock_button_no stock_button_no.png \
+ stock_button_ok stock_button_ok.png \
+ stock_button_yes stock_button_yes.png \
+ stock_close stock_close.png \
+ stock_exit stock_exit.png \
+ stock_help stock_help.png \
+ stock_new stock_new.png \
+ stock_open stock_open.png \
+ stock_save stock_save.png
+
+gtkstockpixbufs.h: $(top_builddir)/gdk-pixbuf/make-inline-pixbuf $(IMAGES)
+ GDK_PIXBUF_MODULEDIR=$(top_builddir)/gdk-pixbuf/.libs $(top_builddir)/gdk-pixbuf/make-inline-pixbuf gtkstockpixbufs.h $(VARIABLES)
diff --git a/gtk/stock-icons/dialog_error.png b/gtk/stock-icons/dialog_error.png
new file mode 100644
index 000000000..cc7830e26
--- /dev/null
+++ b/gtk/stock-icons/dialog_error.png
Binary files differ
diff --git a/gtk/stock-icons/dialog_error_48.png b/gtk/stock-icons/dialog_error_48.png
new file mode 100644
index 000000000..cc7830e26
--- /dev/null
+++ b/gtk/stock-icons/dialog_error_48.png
Binary files differ
diff --git a/gtk/stock-icons/dialog_info.png b/gtk/stock-icons/dialog_info.png
new file mode 100644
index 000000000..757e599d2
--- /dev/null
+++ b/gtk/stock-icons/dialog_info.png
Binary files differ
diff --git a/gtk/stock-icons/dialog_info_48.png b/gtk/stock-icons/dialog_info_48.png
new file mode 100644
index 000000000..757e599d2
--- /dev/null
+++ b/gtk/stock-icons/dialog_info_48.png
Binary files differ
diff --git a/gtk/stock-icons/dialog_question.png b/gtk/stock-icons/dialog_question.png
new file mode 100644
index 000000000..2afbc7a87
--- /dev/null
+++ b/gtk/stock-icons/dialog_question.png
Binary files differ
diff --git a/gtk/stock-icons/dialog_question_48.png b/gtk/stock-icons/dialog_question_48.png
new file mode 100644
index 000000000..2afbc7a87
--- /dev/null
+++ b/gtk/stock-icons/dialog_question_48.png
Binary files differ
diff --git a/gtk/stock-icons/dialog_warning.png b/gtk/stock-icons/dialog_warning.png
new file mode 100644
index 000000000..d6f2306db
--- /dev/null
+++ b/gtk/stock-icons/dialog_warning.png
Binary files differ
diff --git a/gtk/stock-icons/dialog_warning_48.png b/gtk/stock-icons/dialog_warning_48.png
new file mode 100644
index 000000000..d6f2306db
--- /dev/null
+++ b/gtk/stock-icons/dialog_warning_48.png
Binary files differ
diff --git a/gtk/stock-icons/stock_apply_20.png b/gtk/stock-icons/stock_apply_20.png
new file mode 100644
index 000000000..58a64cfc4
--- /dev/null
+++ b/gtk/stock-icons/stock_apply_20.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_apply.png b/gtk/stock-icons/stock_button_apply.png
new file mode 100644
index 000000000..58a64cfc4
--- /dev/null
+++ b/gtk/stock-icons/stock_button_apply.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_apply_24.png b/gtk/stock-icons/stock_button_apply_24.png
new file mode 100644
index 000000000..58a64cfc4
--- /dev/null
+++ b/gtk/stock-icons/stock_button_apply_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_cancel.png b/gtk/stock-icons/stock_button_cancel.png
new file mode 100644
index 000000000..2d7c194c8
--- /dev/null
+++ b/gtk/stock-icons/stock_button_cancel.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_cancel_24.png b/gtk/stock-icons/stock_button_cancel_24.png
new file mode 100644
index 000000000..2d7c194c8
--- /dev/null
+++ b/gtk/stock-icons/stock_button_cancel_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_close.png b/gtk/stock-icons/stock_button_close.png
new file mode 100644
index 000000000..b900bdf3b
--- /dev/null
+++ b/gtk/stock-icons/stock_button_close.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_close_24.png b/gtk/stock-icons/stock_button_close_24.png
new file mode 100644
index 000000000..b900bdf3b
--- /dev/null
+++ b/gtk/stock-icons/stock_button_close_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_no.png b/gtk/stock-icons/stock_button_no.png
new file mode 100644
index 000000000..6478554f6
--- /dev/null
+++ b/gtk/stock-icons/stock_button_no.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_no_24.png b/gtk/stock-icons/stock_button_no_24.png
new file mode 100644
index 000000000..6478554f6
--- /dev/null
+++ b/gtk/stock-icons/stock_button_no_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_ok.png b/gtk/stock-icons/stock_button_ok.png
new file mode 100644
index 000000000..f1c33753f
--- /dev/null
+++ b/gtk/stock-icons/stock_button_ok.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_ok_24.png b/gtk/stock-icons/stock_button_ok_24.png
new file mode 100644
index 000000000..f1c33753f
--- /dev/null
+++ b/gtk/stock-icons/stock_button_ok_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_yes.png b/gtk/stock-icons/stock_button_yes.png
new file mode 100644
index 000000000..e061e7f17
--- /dev/null
+++ b/gtk/stock-icons/stock_button_yes.png
Binary files differ
diff --git a/gtk/stock-icons/stock_button_yes_24.png b/gtk/stock-icons/stock_button_yes_24.png
new file mode 100644
index 000000000..e061e7f17
--- /dev/null
+++ b/gtk/stock-icons/stock_button_yes_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_cancel_20.png b/gtk/stock-icons/stock_cancel_20.png
new file mode 100644
index 000000000..2d7c194c8
--- /dev/null
+++ b/gtk/stock-icons/stock_cancel_20.png
Binary files differ
diff --git a/gtk/stock-icons/stock_close.png b/gtk/stock-icons/stock_close.png
new file mode 100644
index 000000000..4338bdc3f
--- /dev/null
+++ b/gtk/stock-icons/stock_close.png
Binary files differ
diff --git a/gtk/stock-icons/stock_close_20.png b/gtk/stock-icons/stock_close_20.png
new file mode 100644
index 000000000..b900bdf3b
--- /dev/null
+++ b/gtk/stock-icons/stock_close_20.png
Binary files differ
diff --git a/gtk/stock-icons/stock_close_24.png b/gtk/stock-icons/stock_close_24.png
new file mode 100644
index 000000000..4338bdc3f
--- /dev/null
+++ b/gtk/stock-icons/stock_close_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_dialog_error_48.png b/gtk/stock-icons/stock_dialog_error_48.png
new file mode 100644
index 000000000..cc7830e26
--- /dev/null
+++ b/gtk/stock-icons/stock_dialog_error_48.png
Binary files differ
diff --git a/gtk/stock-icons/stock_dialog_info_48.png b/gtk/stock-icons/stock_dialog_info_48.png
new file mode 100644
index 000000000..757e599d2
--- /dev/null
+++ b/gtk/stock-icons/stock_dialog_info_48.png
Binary files differ
diff --git a/gtk/stock-icons/stock_dialog_question_48.png b/gtk/stock-icons/stock_dialog_question_48.png
new file mode 100644
index 000000000..2afbc7a87
--- /dev/null
+++ b/gtk/stock-icons/stock_dialog_question_48.png
Binary files differ
diff --git a/gtk/stock-icons/stock_dialog_warning_48.png b/gtk/stock-icons/stock_dialog_warning_48.png
new file mode 100644
index 000000000..d6f2306db
--- /dev/null
+++ b/gtk/stock-icons/stock_dialog_warning_48.png
Binary files differ
diff --git a/gtk/stock-icons/stock_exit.png b/gtk/stock-icons/stock_exit.png
new file mode 100644
index 000000000..34cccc31d
--- /dev/null
+++ b/gtk/stock-icons/stock_exit.png
Binary files differ
diff --git a/gtk/stock-icons/stock_exit_24.png b/gtk/stock-icons/stock_exit_24.png
new file mode 100644
index 000000000..34cccc31d
--- /dev/null
+++ b/gtk/stock-icons/stock_exit_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_help.png b/gtk/stock-icons/stock_help.png
new file mode 100644
index 000000000..2836a0f8a
--- /dev/null
+++ b/gtk/stock-icons/stock_help.png
Binary files differ
diff --git a/gtk/stock-icons/stock_help_24.png b/gtk/stock-icons/stock_help_24.png
new file mode 100644
index 000000000..2836a0f8a
--- /dev/null
+++ b/gtk/stock-icons/stock_help_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_new.png b/gtk/stock-icons/stock_new.png
new file mode 100644
index 000000000..538e9acd3
--- /dev/null
+++ b/gtk/stock-icons/stock_new.png
Binary files differ
diff --git a/gtk/stock-icons/stock_new_24.png b/gtk/stock-icons/stock_new_24.png
new file mode 100644
index 000000000..538e9acd3
--- /dev/null
+++ b/gtk/stock-icons/stock_new_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_no_20.png b/gtk/stock-icons/stock_no_20.png
new file mode 100644
index 000000000..6478554f6
--- /dev/null
+++ b/gtk/stock-icons/stock_no_20.png
Binary files differ
diff --git a/gtk/stock-icons/stock_ok_20.png b/gtk/stock-icons/stock_ok_20.png
new file mode 100644
index 000000000..f1c33753f
--- /dev/null
+++ b/gtk/stock-icons/stock_ok_20.png
Binary files differ
diff --git a/gtk/stock-icons/stock_open.png b/gtk/stock-icons/stock_open.png
new file mode 100644
index 000000000..e966ad7bf
--- /dev/null
+++ b/gtk/stock-icons/stock_open.png
Binary files differ
diff --git a/gtk/stock-icons/stock_open_24.png b/gtk/stock-icons/stock_open_24.png
new file mode 100644
index 000000000..e966ad7bf
--- /dev/null
+++ b/gtk/stock-icons/stock_open_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_save.png b/gtk/stock-icons/stock_save.png
new file mode 100644
index 000000000..2281b92c2
--- /dev/null
+++ b/gtk/stock-icons/stock_save.png
Binary files differ
diff --git a/gtk/stock-icons/stock_save_24.png b/gtk/stock-icons/stock_save_24.png
new file mode 100644
index 000000000..2281b92c2
--- /dev/null
+++ b/gtk/stock-icons/stock_save_24.png
Binary files differ
diff --git a/gtk/stock-icons/stock_yes_20.png b/gtk/stock-icons/stock_yes_20.png
new file mode 100644
index 000000000..e061e7f17
--- /dev/null
+++ b/gtk/stock-icons/stock_yes_20.png
Binary files differ