summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2000-07-17 23:18:29 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-07-17 23:18:29 +0000
commitb8dcd76c998315201651d7caf6452c10d1b6f9b4 (patch)
tree7b218deb9d49c935e1513291b60bd62aeb3c4f61
parent2465ad85f9d97f15841b7d22a87fe08afc19a815 (diff)
downloadgdk-pixbuf-b8dcd76c998315201651d7caf6452c10d1b6f9b4.tar.gz
Restore code to paint the background of the text area which was
Mon Jul 17 18:52:38 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtkentry.c (gtk_entry_draw_text): Restore code to paint the background of the text area which was accidentally removed at some point. * gtk/gtkrc.[ch] gtk/gtkstyle.[ch] gtk/gtkthemes.[ch]: - Move most of the functionality from the theme vtable into GtkRcStyleClass and GtkStyleClass. The moved vtable functions were changed a bit in the move to work better in their new home. - Get rid of the engine and engine_data fields from GtkRcStyle and GtkStyle; instead the theme engine derives theme-specific subclasses of GtkRcStyle and GtkStyle - Add extra dlsym() found entry point to themes, theme_create_rc_style(). * gtk/gtkstyle.c: Copy xthickness, ythickness fields in gtk_style_real_copy. * gtk/themes.[ch]: add a function gtk_theme_engine_register_type() to register a type associated with an engine. (The engine won't be unloaded as there is an instance of the type.)
-rw-r--r--ChangeLog29
-rw-r--r--ChangeLog.pre-2-029
-rw-r--r--ChangeLog.pre-2-1029
-rw-r--r--ChangeLog.pre-2-229
-rw-r--r--ChangeLog.pre-2-429
-rw-r--r--ChangeLog.pre-2-629
-rw-r--r--ChangeLog.pre-2-829
-rw-r--r--gtk/gtkentry.c9
-rw-r--r--gtk/gtkrc.c284
-rw-r--r--gtk/gtkrc.h32
-rw-r--r--gtk/gtkstyle.c396
-rw-r--r--gtk/gtkstyle.h47
-rw-r--r--gtk/gtkthemes.c198
-rw-r--r--gtk/gtkthemes.h59
14 files changed, 852 insertions, 376 deletions
diff --git a/ChangeLog b/ChangeLog
index 3d8cb6b04..7684928bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+Mon Jul 17 18:52:38 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkentry.c (gtk_entry_draw_text): Restore code to
+ paint the background of the text area which was accidentally
+ removed at some point.
+
+ * gtk/gtkrc.[ch] gtk/gtkstyle.[ch] gtk/gtkthemes.[ch]:
+
+ - Move most of the functionality from the theme vtable
+ into GtkRcStyleClass and GtkStyleClass. The moved
+ vtable functions were changed a bit in the move to
+ work better in their new home.
+
+ - Get rid of the engine and engine_data fields from
+ GtkRcStyle and GtkStyle; instead the theme
+ engine derives theme-specific subclasses of GtkRcStyle
+ and GtkStyle
+
+ - Add extra dlsym() found entry point to themes,
+ theme_create_rc_style().
+
+ * gtk/gtkstyle.c: Copy xthickness, ythickness fields
+ in gtk_style_real_copy.
+
+ * gtk/themes.[ch]: add a function gtk_theme_engine_register_type()
+ to register a type associated with an engine. (The engine
+ won't be unloaded as there is an instance of the type.)
+
+
Mon Jul 17 18:19:06 BST 2000 Tony Gale <gale@gtk.org>
* docs/tutorial/gtk-tut.sgml: Clean ups.
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index 3d8cb6b04..7684928bf 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,32 @@
+Mon Jul 17 18:52:38 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkentry.c (gtk_entry_draw_text): Restore code to
+ paint the background of the text area which was accidentally
+ removed at some point.
+
+ * gtk/gtkrc.[ch] gtk/gtkstyle.[ch] gtk/gtkthemes.[ch]:
+
+ - Move most of the functionality from the theme vtable
+ into GtkRcStyleClass and GtkStyleClass. The moved
+ vtable functions were changed a bit in the move to
+ work better in their new home.
+
+ - Get rid of the engine and engine_data fields from
+ GtkRcStyle and GtkStyle; instead the theme
+ engine derives theme-specific subclasses of GtkRcStyle
+ and GtkStyle
+
+ - Add extra dlsym() found entry point to themes,
+ theme_create_rc_style().
+
+ * gtk/gtkstyle.c: Copy xthickness, ythickness fields
+ in gtk_style_real_copy.
+
+ * gtk/themes.[ch]: add a function gtk_theme_engine_register_type()
+ to register a type associated with an engine. (The engine
+ won't be unloaded as there is an instance of the type.)
+
+
Mon Jul 17 18:19:06 BST 2000 Tony Gale <gale@gtk.org>
* docs/tutorial/gtk-tut.sgml: Clean ups.
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 3d8cb6b04..7684928bf 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,32 @@
+Mon Jul 17 18:52:38 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkentry.c (gtk_entry_draw_text): Restore code to
+ paint the background of the text area which was accidentally
+ removed at some point.
+
+ * gtk/gtkrc.[ch] gtk/gtkstyle.[ch] gtk/gtkthemes.[ch]:
+
+ - Move most of the functionality from the theme vtable
+ into GtkRcStyleClass and GtkStyleClass. The moved
+ vtable functions were changed a bit in the move to
+ work better in their new home.
+
+ - Get rid of the engine and engine_data fields from
+ GtkRcStyle and GtkStyle; instead the theme
+ engine derives theme-specific subclasses of GtkRcStyle
+ and GtkStyle
+
+ - Add extra dlsym() found entry point to themes,
+ theme_create_rc_style().
+
+ * gtk/gtkstyle.c: Copy xthickness, ythickness fields
+ in gtk_style_real_copy.
+
+ * gtk/themes.[ch]: add a function gtk_theme_engine_register_type()
+ to register a type associated with an engine. (The engine
+ won't be unloaded as there is an instance of the type.)
+
+
Mon Jul 17 18:19:06 BST 2000 Tony Gale <gale@gtk.org>
* docs/tutorial/gtk-tut.sgml: Clean ups.
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index 3d8cb6b04..7684928bf 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,32 @@
+Mon Jul 17 18:52:38 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkentry.c (gtk_entry_draw_text): Restore code to
+ paint the background of the text area which was accidentally
+ removed at some point.
+
+ * gtk/gtkrc.[ch] gtk/gtkstyle.[ch] gtk/gtkthemes.[ch]:
+
+ - Move most of the functionality from the theme vtable
+ into GtkRcStyleClass and GtkStyleClass. The moved
+ vtable functions were changed a bit in the move to
+ work better in their new home.
+
+ - Get rid of the engine and engine_data fields from
+ GtkRcStyle and GtkStyle; instead the theme
+ engine derives theme-specific subclasses of GtkRcStyle
+ and GtkStyle
+
+ - Add extra dlsym() found entry point to themes,
+ theme_create_rc_style().
+
+ * gtk/gtkstyle.c: Copy xthickness, ythickness fields
+ in gtk_style_real_copy.
+
+ * gtk/themes.[ch]: add a function gtk_theme_engine_register_type()
+ to register a type associated with an engine. (The engine
+ won't be unloaded as there is an instance of the type.)
+
+
Mon Jul 17 18:19:06 BST 2000 Tony Gale <gale@gtk.org>
* docs/tutorial/gtk-tut.sgml: Clean ups.
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 3d8cb6b04..7684928bf 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,32 @@
+Mon Jul 17 18:52:38 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkentry.c (gtk_entry_draw_text): Restore code to
+ paint the background of the text area which was accidentally
+ removed at some point.
+
+ * gtk/gtkrc.[ch] gtk/gtkstyle.[ch] gtk/gtkthemes.[ch]:
+
+ - Move most of the functionality from the theme vtable
+ into GtkRcStyleClass and GtkStyleClass. The moved
+ vtable functions were changed a bit in the move to
+ work better in their new home.
+
+ - Get rid of the engine and engine_data fields from
+ GtkRcStyle and GtkStyle; instead the theme
+ engine derives theme-specific subclasses of GtkRcStyle
+ and GtkStyle
+
+ - Add extra dlsym() found entry point to themes,
+ theme_create_rc_style().
+
+ * gtk/gtkstyle.c: Copy xthickness, ythickness fields
+ in gtk_style_real_copy.
+
+ * gtk/themes.[ch]: add a function gtk_theme_engine_register_type()
+ to register a type associated with an engine. (The engine
+ won't be unloaded as there is an instance of the type.)
+
+
Mon Jul 17 18:19:06 BST 2000 Tony Gale <gale@gtk.org>
* docs/tutorial/gtk-tut.sgml: Clean ups.
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 3d8cb6b04..7684928bf 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,32 @@
+Mon Jul 17 18:52:38 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkentry.c (gtk_entry_draw_text): Restore code to
+ paint the background of the text area which was accidentally
+ removed at some point.
+
+ * gtk/gtkrc.[ch] gtk/gtkstyle.[ch] gtk/gtkthemes.[ch]:
+
+ - Move most of the functionality from the theme vtable
+ into GtkRcStyleClass and GtkStyleClass. The moved
+ vtable functions were changed a bit in the move to
+ work better in their new home.
+
+ - Get rid of the engine and engine_data fields from
+ GtkRcStyle and GtkStyle; instead the theme
+ engine derives theme-specific subclasses of GtkRcStyle
+ and GtkStyle
+
+ - Add extra dlsym() found entry point to themes,
+ theme_create_rc_style().
+
+ * gtk/gtkstyle.c: Copy xthickness, ythickness fields
+ in gtk_style_real_copy.
+
+ * gtk/themes.[ch]: add a function gtk_theme_engine_register_type()
+ to register a type associated with an engine. (The engine
+ won't be unloaded as there is an instance of the type.)
+
+
Mon Jul 17 18:19:06 BST 2000 Tony Gale <gale@gtk.org>
* docs/tutorial/gtk-tut.sgml: Clean ups.
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 3d8cb6b04..7684928bf 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,32 @@
+Mon Jul 17 18:52:38 2000 Owen Taylor <otaylor@redhat.com>
+
+ * gtk/gtkentry.c (gtk_entry_draw_text): Restore code to
+ paint the background of the text area which was accidentally
+ removed at some point.
+
+ * gtk/gtkrc.[ch] gtk/gtkstyle.[ch] gtk/gtkthemes.[ch]:
+
+ - Move most of the functionality from the theme vtable
+ into GtkRcStyleClass and GtkStyleClass. The moved
+ vtable functions were changed a bit in the move to
+ work better in their new home.
+
+ - Get rid of the engine and engine_data fields from
+ GtkRcStyle and GtkStyle; instead the theme
+ engine derives theme-specific subclasses of GtkRcStyle
+ and GtkStyle
+
+ - Add extra dlsym() found entry point to themes,
+ theme_create_rc_style().
+
+ * gtk/gtkstyle.c: Copy xthickness, ythickness fields
+ in gtk_style_real_copy.
+
+ * gtk/themes.[ch]: add a function gtk_theme_engine_register_type()
+ to register a type associated with an engine. (The engine
+ won't be unloaded as there is an instance of the type.)
+
+
Mon Jul 17 18:19:06 BST 2000 Tony Gale <gale@gtk.org>
* docs/tutorial/gtk-tut.sgml: Clean ups.
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 9a3a1948a..48a91f50d 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -1183,13 +1183,18 @@ gtk_entry_draw_text (GtkEntry *entry)
if (GTK_WIDGET_DRAWABLE (entry))
{
PangoRectangle logical_rect;
- int area_height;
+ gint area_width, area_height;
- gdk_window_get_size (entry->text_area, NULL, &area_height);
+ gdk_window_get_size (entry->text_area, &area_width, &area_height);
area_height = PANGO_SCALE * (area_height - 2 * INNER_BORDER);
widget = GTK_WIDGET (entry);
+ gtk_paint_flat_box (widget->style, entry->text_area,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE,
+ NULL, widget, "entry_bg",
+ 0, 0, area_width, area_height);
+
gtk_entry_ensure_layout (entry);
line = pango_layout_get_lines (entry->layout)->data;
diff --git a/gtk/gtkrc.c b/gtk/gtkrc.c
index d693edfdd..9fbaa444c 100644
--- a/gtk/gtkrc.c
+++ b/gtk/gtkrc.c
@@ -121,7 +121,7 @@ static guint gtk_rc_parse_fontset (GScanner *scanner,
static guint gtk_rc_parse_font_name (GScanner *scanner,
GtkRcStyle *rc_style);
static guint gtk_rc_parse_engine (GScanner *scanner,
- GtkRcStyle *rc_style);
+ GtkRcStyle **rc_style);
static guint gtk_rc_parse_pixmap_path (GScanner *scanner);
static void gtk_rc_parse_pixmap_path_string (gchar *pix_path);
static guint gtk_rc_parse_module_path (GScanner *scanner);
@@ -134,9 +134,13 @@ static void gtk_rc_clear_styles (void);
static void gtk_rc_append_default_module_path (void);
static void gtk_rc_add_initial_default_files (void);
-static void gtk_rc_style_init (GtkRcStyle *style);
-static void gtk_rc_style_class_init (GtkRcStyleClass *klass);
-static void gtk_rc_style_finalize (GObject *object);
+static void gtk_rc_style_init (GtkRcStyle *style);
+static void gtk_rc_style_class_init (GtkRcStyleClass *klass);
+static void gtk_rc_style_finalize (GObject *object);
+static void gtk_rc_style_real_merge (GtkRcStyle *dest,
+ GtkRcStyle *src);
+static GtkRcStyle *gtk_rc_style_real_clone (GtkRcStyle *rc_style);
+static GtkStyle * gtk_rc_style_real_create_style (GtkRcStyle *rc_style);
static gpointer parent_class = NULL;
@@ -746,8 +750,6 @@ gtk_rc_style_init (GtkRcStyle *style)
}
style->xthickness = -1;
style->ythickness = -1;
- style->engine = NULL;
- style->engine_data = NULL;
style->rc_style_lists = NULL;
}
@@ -759,6 +761,11 @@ gtk_rc_style_class_init (GtkRcStyleClass *klass)
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gtk_rc_style_finalize;
+
+ klass->parse = NULL;
+ klass->clone = gtk_rc_style_real_clone;
+ klass->merge = gtk_rc_style_real_merge;
+ klass->create_style = gtk_rc_style_real_create_style;
}
/* Like g_slist_remove, but remove all copies of data */
@@ -808,18 +815,12 @@ gtk_rc_style_finalize (GObject *object)
rc_style = GTK_RC_STYLE (object);
- if (rc_style->engine)
- {
- rc_style->engine->destroy_rc_style (rc_style);
- gtk_theme_engine_unref (rc_style->engine);
- }
-
if (rc_style->name)
g_free (rc_style->name);
if (rc_style->font_desc)
pango_font_description_free (rc_style->font_desc);
- for (i=0 ; i<5 ; i++)
+ for (i=0 ; i < 5 ; i++)
if (rc_style->bg_pixmap_name[i])
g_free (rc_style->bg_pixmap_name[i]);
@@ -886,6 +887,64 @@ gtk_rc_style_unref (GtkRcStyle *rc_style)
g_object_unref (G_OBJECT (rc_style));
}
+static GtkRcStyle *
+gtk_rc_style_real_clone (GtkRcStyle *style)
+{
+ return GTK_RC_STYLE (g_object_new (G_OBJECT_TYPE (style), NULL));
+}
+
+static void
+gtk_rc_style_real_merge (GtkRcStyle *dest,
+ GtkRcStyle *src)
+{
+ gint i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (!dest->bg_pixmap_name[i] && src->bg_pixmap_name[i])
+ dest->bg_pixmap_name[i] = g_strdup (src->bg_pixmap_name[i]);
+
+ if (!(dest->color_flags[i] & GTK_RC_FG) &&
+ src->color_flags[i] & GTK_RC_FG)
+ {
+ dest->fg[i] = src->fg[i];
+ dest->color_flags[i] |= GTK_RC_FG;
+ }
+ if (!(dest->color_flags[i] & GTK_RC_BG) &&
+ src->color_flags[i] & GTK_RC_BG)
+ {
+ dest->bg[i] = src->bg[i];
+ dest->color_flags[i] |= GTK_RC_BG;
+ }
+ if (!(dest->color_flags[i] & GTK_RC_TEXT) &&
+ src->color_flags[i] & GTK_RC_TEXT)
+ {
+ dest->text[i] = src->text[i];
+ dest->color_flags[i] |= GTK_RC_TEXT;
+ }
+ if (!(dest->color_flags[i] & GTK_RC_BASE) &&
+ src->color_flags[i] & GTK_RC_BASE)
+ {
+ dest->base[i] = src->base[i];
+ dest->color_flags[i] |= GTK_RC_BASE;
+ }
+ }
+
+ if (dest->xthickness < 0 && src->xthickness >= 0)
+ dest->xthickness = src->xthickness;
+ if (dest->ythickness < 0 && src->ythickness >= 0)
+ dest->ythickness = src->ythickness;
+
+ if (!dest->font_desc && src->font_desc)
+ dest->font_desc = pango_font_description_copy (src->font_desc);
+}
+
+static GtkStyle *
+gtk_rc_style_real_create_style (GtkRcStyle *rc_style)
+{
+ return gtk_style_new ();
+}
+
static void
gtk_rc_clear_hash_node (gpointer key,
gpointer data,
@@ -1274,55 +1333,18 @@ gtk_rc_style_find (const char *name)
return NULL;
}
-/* Assumes ownership of rc_style */
static GtkStyle *
gtk_rc_style_to_style (GtkRcStyle *rc_style)
{
GtkStyle *style;
- GdkFont *old_font;
- gint i;
- style = gtk_style_new ();
+ style = GTK_RC_STYLE_GET_CLASS (rc_style)->create_style (rc_style);
style->rc_style = rc_style;
-
- if (rc_style->font_desc)
- {
- pango_font_description_free (style->font_desc);
- style->font_desc = pango_font_description_copy (rc_style->font_desc);
-
- old_font = style->font;
- style->font = gdk_font_from_description (style->font_desc);
- if (style->font)
- gdk_font_unref (old_font);
- else
- style->font = old_font;
- }
-
- for (i = 0; i < 5; i++)
- {
- if (rc_style->color_flags[i] & GTK_RC_FG)
- style->fg[i] = rc_style->fg[i];
- if (rc_style->color_flags[i] & GTK_RC_BG)
- style->bg[i] = rc_style->bg[i];
- if (rc_style->color_flags[i] & GTK_RC_TEXT)
- style->text[i] = rc_style->text[i];
- if (rc_style->color_flags[i] & GTK_RC_BASE)
- style->base[i] = rc_style->base[i];
- }
-
- if (rc_style->xthickness >= 0)
- style->xthickness = rc_style->xthickness;
- if (rc_style->ythickness >= 0)
- style->ythickness = rc_style->ythickness;
-
- if (rc_style->engine)
- {
- style->engine = rc_style->engine;
- gtk_theme_engine_ref (style->engine);
- rc_style->engine->rc_style_to_style (style, rc_style);
- }
-
+ gtk_rc_style_ref (rc_style);
+
+ GTK_STYLE_GET_CLASS (style)->init_from_rc (style, rc_style);
+
return style;
}
@@ -1333,6 +1355,8 @@ gtk_rc_init_style (GSList *rc_styles)
GtkStyle *style = NULL;
gint i;
+ g_return_val_if_fail (rc_styles != NULL, NULL);
+
if (!realized_style_ht)
realized_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_styles_hash,
(GCompareFunc) gtk_rc_styles_compare);
@@ -1341,71 +1365,46 @@ gtk_rc_init_style (GSList *rc_styles)
if (!style)
{
+ GtkRcStyle *base_style = NULL;
GtkRcStyle *proto_style;
- GSList *tmp_style;
-
- proto_style = gtk_rc_style_new ();
+ GtkRcStyleClass *proto_style_class;
+ GSList *tmp_styles;
+ GType rc_style_type = GTK_TYPE_RC_STYLE;
- tmp_style = rc_styles;
- while (tmp_style)
+ /* Find the first derived style in the list, and use that to
+ * create the merged style. If we only have raw GtkRcStyles, use
+ * the first style to create the merged style.
+ */
+ base_style = rc_styles->data;
+ tmp_styles = rc_styles;
+ while (tmp_styles)
{
- GtkRcStyle *rc_style = tmp_style->data;
+ GtkRcStyle *rc_style = tmp_styles->data;
- for (i = 0; i < 5; i++)
+ if (G_OBJECT_TYPE (rc_style) != rc_style_type)
{
- if (!proto_style->bg_pixmap_name[i] && rc_style->bg_pixmap_name[i])
- proto_style->bg_pixmap_name[i] = g_strdup (rc_style->bg_pixmap_name[i]);
-
- if (!(proto_style->color_flags[i] & GTK_RC_FG) &&
- rc_style->color_flags[i] & GTK_RC_FG)
- {
- proto_style->fg[i] = rc_style->fg[i];
- proto_style->color_flags[i] |= GTK_RC_FG;
- }
- if (!(proto_style->color_flags[i] & GTK_RC_BG) &&
- rc_style->color_flags[i] & GTK_RC_BG)
- {
- proto_style->bg[i] = rc_style->bg[i];
- proto_style->color_flags[i] |= GTK_RC_BG;
- }
- if (!(proto_style->color_flags[i] & GTK_RC_TEXT) &&
- rc_style->color_flags[i] & GTK_RC_TEXT)
- {
- proto_style->text[i] = rc_style->text[i];
- proto_style->color_flags[i] |= GTK_RC_TEXT;
- }
- if (!(proto_style->color_flags[i] & GTK_RC_BASE) &&
- rc_style->color_flags[i] & GTK_RC_BASE)
- {
- proto_style->base[i] = rc_style->base[i];
- proto_style->color_flags[i] |= GTK_RC_BASE;
- }
+ base_style = rc_style;
+ break;
}
- if (proto_style->xthickness < 0 && rc_style->xthickness >= 0)
- proto_style->xthickness = rc_style->xthickness;
- if (proto_style->ythickness < 0 && rc_style->ythickness >= 0)
- proto_style->ythickness = rc_style->ythickness;
-
- if (!proto_style->font_desc && rc_style->font_desc)
- proto_style->font_desc = pango_font_description_copy (rc_style->font_desc);
-
- if (!proto_style->engine && rc_style->engine)
- {
- proto_style->engine = rc_style->engine;
- gtk_theme_engine_ref (proto_style->engine);
- }
+ tmp_styles = tmp_styles->next;
+ }
+
+ proto_style_class = GTK_RC_STYLE_GET_CLASS (base_style);
+ proto_style = proto_style_class->clone (base_style);
+
+ tmp_styles = rc_styles;
+ while (tmp_styles)
+ {
+ GtkRcStyle *rc_style = tmp_styles->data;
+
+ proto_style_class->merge (proto_style, rc_style);
- if (proto_style->engine &&
- (proto_style->engine == rc_style->engine))
- proto_style->engine->merge_rc_style (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);
-
- tmp_style = tmp_style->next;
+
+ tmp_styles = tmp_styles->next;
}
for (i = 0; i < 5; i++)
@@ -1417,6 +1416,7 @@ gtk_rc_init_style (GSList *rc_styles)
}
style = gtk_rc_style_to_style (proto_style);
+ gtk_rc_style_unref (proto_style);
g_hash_table_insert (realized_style_ht, rc_styles, style);
}
@@ -1509,9 +1509,6 @@ gtk_rc_parse_style (GScanner *scanner)
for (i = 0; i < 5; i++)
rc_style->color_flags[i] = 0;
-
- rc_style->engine = NULL;
- rc_style->engine_data = NULL;
}
token = g_scanner_peek_next_token (scanner);
@@ -1604,7 +1601,7 @@ gtk_rc_parse_style (GScanner *scanner)
token = gtk_rc_parse_font_name (scanner, rc_style);
break;
case GTK_RC_TOKEN_ENGINE:
- token = gtk_rc_parse_engine (scanner, rc_style);
+ token = gtk_rc_parse_engine (scanner, &rc_style);
break;
default:
g_scanner_get_next_token (scanner);
@@ -1977,10 +1974,14 @@ gtk_rc_parse_font_name (GScanner *scanner,
static guint
gtk_rc_parse_engine (GScanner *scanner,
- GtkRcStyle *rc_style)
+ GtkRcStyle **rc_style)
{
guint token;
-
+ GtkThemeEngine *engine;
+ guint result = G_TOKEN_NONE;
+ GtkRcStyle *new_style = NULL;
+ gboolean parsed_curlies = FALSE;
+
token = g_scanner_get_next_token (scanner);
if (token != GTK_RC_TOKEN_ENGINE)
return GTK_RC_TOKEN_ENGINE;
@@ -1989,32 +1990,67 @@ gtk_rc_parse_engine (GScanner *scanner,
if (token != G_TOKEN_STRING)
return G_TOKEN_STRING;
- rc_style->engine = gtk_theme_engine_get (scanner->value.v_string);
-
+ engine = gtk_theme_engine_get (scanner->value.v_string);
+
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_LEFT_CURLY)
return G_TOKEN_LEFT_CURLY;
- if (rc_style->engine)
- return rc_style->engine->parse_rc_style (scanner, rc_style);
- else
+ if (engine)
+ {
+ GtkRcStyleClass *new_class;
+
+ new_style = gtk_theme_engine_create_rc_style (engine);
+ gtk_theme_engine_unref (engine);
+
+ new_class = GTK_RC_STYLE_GET_CLASS (new_style);
+
+ new_class->merge (new_style, *rc_style);
+ if ((*rc_style)->name)
+ new_style->name = g_strdup ((*rc_style)->name);
+
+ if (new_class->parse)
+ {
+ parsed_curlies = TRUE;
+ result = new_class->parse (new_style, scanner);
+
+ if (result != G_TOKEN_NONE)
+ {
+ g_object_unref (G_OBJECT (new_style));
+ new_style = NULL;
+ }
+ }
+ }
+
+ if (!parsed_curlies)
{
- /* Skip over remainder, looking for nested {}'s */
+ /* Skip over remainder, looking for nested {}'s
+ */
guint count = 1;
+ result = G_TOKEN_RIGHT_CURLY;
while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
{
if (token == G_TOKEN_LEFT_CURLY)
count++;
else if (token == G_TOKEN_RIGHT_CURLY)
count--;
-
+
if (count == 0)
- return G_TOKEN_NONE;
+ {
+ result = G_TOKEN_NONE;
+ break;
+ }
}
+ }
- return G_TOKEN_RIGHT_CURLY;
+ if (new_style)
+ {
+ g_object_unref (G_OBJECT (*rc_style));
+ *rc_style = new_style;
}
+
+ return result;
}
guint
diff --git a/gtk/gtkrc.h b/gtk/gtkrc.h
index 8fc54b1e7..cba8e1f84 100644
--- a/gtk/gtkrc.h
+++ b/gtk/gtkrc.h
@@ -71,9 +71,6 @@ struct _GtkRcStyle
gint xthickness;
gint ythickness;
- GtkThemeEngine *engine;
- gpointer engine_data;
-
/*< private >*/
/* list of RC style lists including this RC style */
@@ -84,6 +81,27 @@ struct _GtkRcStyleClass
{
GObjectClass parent_class;
+ /* Create an empty RC style of the same type as this RC style.
+ * The default implementation, which does
+ * g_object_new (G_OBJECT_TYPE (style), NULL);
+ * should work in most cases.
+ */
+ GtkRcStyle *(*clone) (GtkRcStyle *rc_style);
+
+ /* Fill in engine specific parts of GtkRcStyle by parsing contents
+ * of brackets. Returns G_TOKEN_NONE if succesful, otherwise returns
+ * the token it expected but didn't get.
+ */
+ guint (*parse) (GtkRcStyle *rc_style, GScanner *scanner);
+
+ /* Combine RC style data from src into dest. If overriden, this
+ * function should chain to the parent.
+ */
+ void (*merge) (GtkRcStyle *dest, GtkRcStyle *src);
+
+ /* Create an empty style suitable to this RC style
+ */
+ GtkStyle *(*create_style) (GtkRcStyle *rc_style);
};
void gtk_rc_init (void);
@@ -101,10 +119,10 @@ void gtk_rc_add_widget_class_style (GtkRcStyle *rc_style,
void gtk_rc_add_class_style (GtkRcStyle *rc_style,
const gchar *pattern);
-GType gtk_rc_style_get_type (void);
-GtkRcStyle* gtk_rc_style_new (void);
-void gtk_rc_style_ref (GtkRcStyle *rc_style);
-void gtk_rc_style_unref (GtkRcStyle *rc_style);
+GType gtk_rc_style_get_type (void);
+GtkRcStyle* gtk_rc_style_new (void);
+void gtk_rc_style_ref (GtkRcStyle *rc_style);
+void gtk_rc_style_unref (GtkRcStyle *rc_style);
/* Tell gtkrc to use a custom routine to load images specified in rc files instead of
* the default xpm-only loader
diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c
index 622ff7b01..d71387120 100644
--- a/gtk/gtkstyle.c
+++ b/gtk/gtkstyle.c
@@ -45,8 +45,18 @@
#endif /* M_PI_4 */
static void gtk_style_realize (GtkStyle *style,
- GdkColormap *colormap,
- gint depth);
+ GdkColormap *colormap);
+
+static void gtk_style_real_realize (GtkStyle *style);
+static void gtk_style_real_unrealize (GtkStyle *style);
+static void gtk_style_real_copy (GtkStyle *style,
+ GtkStyle *src);
+static void gtk_style_real_set_background (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type);
+static GtkStyle *gtk_style_real_clone (GtkStyle *style);
+static void gtk_style_real_init_from_rc (GtkStyle *style,
+ GtkRcStyle *rc_style);
static void gtk_default_draw_hline (GtkStyle *style,
GdkWindow *window,
@@ -403,9 +413,6 @@ gtk_style_init (GtkStyle *style)
for (i = 0; i < 5; i++)
style->bg_pixmap[i] = NULL;
- style->engine = NULL;
- style->engine_data = NULL;
-
style->rc_style = NULL;
for (i = 0; i < 5; i++)
@@ -432,6 +439,13 @@ gtk_style_class_init (GtkStyleClass *klass)
object_class->finalize = gtk_style_finalize;
+ klass->clone = gtk_style_real_clone;
+ klass->copy = gtk_style_real_copy;
+ klass->init_from_rc = gtk_style_real_init_from_rc;
+ klass->realize = gtk_style_real_realize;
+ klass->unrealize = gtk_style_real_unrealize;
+ klass->set_background = gtk_style_real_set_background;
+
klass->draw_hline = gtk_default_draw_hline;
klass->draw_vline = gtk_default_draw_vline;
klass->draw_shadow = gtk_default_draw_shadow;
@@ -479,12 +493,6 @@ gtk_style_finalize (GObject *object)
}
}
- if (style->engine)
- {
- style->engine->destroy_style (style);
- gtk_theme_engine_unref (style->engine);
- }
-
gdk_font_unref (style->font);
pango_font_description_free (style->font_desc);
@@ -499,41 +507,11 @@ GtkStyle*
gtk_style_copy (GtkStyle *style)
{
GtkStyle *new_style;
- guint i;
-
- g_return_val_if_fail (style != NULL, NULL);
-
- new_style = gtk_style_new ();
-
- for (i = 0; i < 5; i++)
- {
- new_style->fg[i] = style->fg[i];
- new_style->bg[i] = style->bg[i];
- new_style->text[i] = style->text[i];
- new_style->base[i] = style->base[i];
-
- new_style->bg_pixmap[i] = style->bg_pixmap[i];
- }
-
- gdk_font_unref (new_style->font);
- new_style->font = style->font;
- gdk_font_ref (new_style->font);
-
- pango_font_description_free (new_style->font_desc);
- new_style->font_desc = pango_font_description_copy (style->font_desc);
- if (style->rc_style)
- {
- new_style->rc_style = style->rc_style;
- gtk_rc_style_ref (style->rc_style);
- }
+ g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
- if (style->engine)
- {
- new_style->engine = style->engine;
- gtk_theme_engine_ref (new_style->engine);
- new_style->engine->duplicate_style (new_style, style);
- }
+ new_style = GTK_STYLE_GET_CLASS (style)->clone (style);
+ GTK_STYLE_GET_CLASS (style)->copy (new_style, style);
return new_style;
}
@@ -603,13 +581,11 @@ gtk_style_attach (GtkStyle *style,
GSList *styles;
GtkStyle *new_style = NULL;
GdkColormap *colormap;
- gint depth;
g_return_val_if_fail (style != NULL, NULL);
g_return_val_if_fail (window != NULL, NULL);
colormap = gdk_window_get_colormap (window);
- depth = gdk_window_get_visual (window)->depth;
if (!style->styles)
style->styles = g_slist_append (NULL, style);
@@ -621,11 +597,10 @@ gtk_style_attach (GtkStyle *style,
if (new_style->attach_count == 0)
{
- gtk_style_realize (new_style, colormap, depth);
+ gtk_style_realize (new_style, colormap);
break;
}
- else if (new_style->colormap == colormap &&
- new_style->depth == depth)
+ else if (new_style->colormap == colormap)
break;
new_style = NULL;
@@ -635,7 +610,7 @@ gtk_style_attach (GtkStyle *style,
if (!new_style)
{
new_style = gtk_style_duplicate (style);
- gtk_style_realize (new_style, colormap, depth);
+ gtk_style_realize (new_style, colormap);
}
/* A style gets a refcount from being attached */
@@ -657,29 +632,12 @@ gtk_style_attach (GtkStyle *style,
void
gtk_style_detach (GtkStyle *style)
{
- gint i;
-
g_return_if_fail (style != NULL);
style->attach_count -= 1;
if (style->attach_count == 0)
{
- if (style->engine)
- style->engine->unrealize_style (style);
-
- gtk_gc_release (style->black_gc);
- gtk_gc_release (style->white_gc);
-
- for (i = 0; i < 5; i++)
- {
- gtk_gc_release (style->fg_gc[i]);
- gtk_gc_release (style->bg_gc[i]);
- gtk_gc_release (style->light_gc[i]);
- gtk_gc_release (style->dark_gc[i]);
- gtk_gc_release (style->mid_gc[i]);
- gtk_gc_release (style->text_gc[i]);
- gtk_gc_release (style->base_gc[i]);
- }
+ GTK_STYLE_GET_CLASS (style)->unrealize (style);
gtk_style_unref (style);
}
@@ -699,100 +657,14 @@ gtk_style_unref (GtkStyle *style)
static void
gtk_style_realize (GtkStyle *style,
- GdkColormap *colormap,
- gint depth)
+ GdkColormap *colormap)
{
- GdkGCValues gc_values;
- GdkGCValuesMask gc_values_mask;
- gint i;
-
g_return_if_fail (style != NULL);
style->colormap = colormap;
- style->depth = depth;
-
- for (i = 0; i < 5; i++)
- {
- gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
- gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
-
- style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
- style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
- style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
- }
-
- gdk_color_black (colormap, &style->black);
- gdk_color_white (colormap, &style->white);
-
- gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_FONT;
- if (style->font->type == GDK_FONT_FONT)
- {
- gc_values.font = style->font;
- }
- else if (style->font->type == GDK_FONT_FONTSET)
- {
- gc_values.font = default_font;
- }
-
- gc_values.foreground = style->black;
- style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
- gc_values.foreground = style->white;
- style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
- for (i = 0; i < 5; i++)
- {
- if (style->rc_style && style->rc_style->bg_pixmap_name[i])
- style->bg_pixmap[i] = gtk_rc_load_image (style->colormap,
- &style->bg[i],
- style->rc_style->bg_pixmap_name[i]);
-
- if (!gdk_color_alloc (colormap, &style->fg[i]))
- g_warning ("unable to allocate color: ( %d %d %d )",
- style->fg[i].red, style->fg[i].green, style->fg[i].blue);
- if (!gdk_color_alloc (colormap, &style->bg[i]))
- g_warning ("unable to allocate color: ( %d %d %d )",
- style->bg[i].red, style->bg[i].green, style->bg[i].blue);
- if (!gdk_color_alloc (colormap, &style->light[i]))
- g_warning ("unable to allocate color: ( %d %d %d )",
- style->light[i].red, style->light[i].green, style->light[i].blue);
- if (!gdk_color_alloc (colormap, &style->dark[i]))
- g_warning ("unable to allocate color: ( %d %d %d )",
- style->dark[i].red, style->dark[i].green, style->dark[i].blue);
- if (!gdk_color_alloc (colormap, &style->mid[i]))
- g_warning ("unable to allocate color: ( %d %d %d )",
- style->mid[i].red, style->mid[i].green, style->mid[i].blue);
- if (!gdk_color_alloc (colormap, &style->text[i]))
- g_warning ("unable to allocate color: ( %d %d %d )",
- style->text[i].red, style->text[i].green, style->text[i].blue);
- if (!gdk_color_alloc (colormap, &style->base[i]))
- g_warning ("unable to allocate color: ( %d %d %d )",
- style->base[i].red, style->base[i].green, style->base[i].blue);
-
- gc_values.foreground = style->fg[i];
- style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
- gc_values.foreground = style->bg[i];
- style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
- gc_values.foreground = style->light[i];
- style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
- gc_values.foreground = style->dark[i];
- style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
- gc_values.foreground = style->mid[i];
- style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
- gc_values.foreground = style->text[i];
- style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
- gc_values.foreground = style->base[i];
- style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
- }
-
- if (style->engine)
- style->engine->realize_style (style);
+ style->depth = gdk_colormap_get_visual (colormap)->depth;
+
+ GTK_STYLE_GET_CLASS (style)->realize (style);
}
void
@@ -1143,18 +1015,212 @@ gtk_style_set_background (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type)
{
- GdkPixmap *pixmap;
- gint parent_relative;
-
g_return_if_fail (style != NULL);
g_return_if_fail (window != NULL);
- if (style->engine && style->engine->set_background)
+ GTK_STYLE_GET_CLASS (style)->set_background (style, window, state_type);
+}
+
+/* Default functions */
+static GtkStyle *
+gtk_style_real_clone (GtkStyle *style)
+{
+ return GTK_STYLE (g_object_new (G_OBJECT_TYPE (style), NULL));
+}
+
+static void
+gtk_style_real_copy (GtkStyle *style,
+ GtkStyle *src)
+{
+ gint i;
+
+ for (i = 0; i < 5; i++)
{
- style->engine->set_background (style, window, state_type);
+ style->fg[i] = src->fg[i];
+ style->bg[i] = src->bg[i];
+ style->text[i] = src->text[i];
+ style->base[i] = src->base[i];
- return;
+ style->bg_pixmap[i] = src->bg_pixmap[i];
}
+
+ if (style->font)
+ gdk_font_unref (style->font);
+ style->font = src->font;
+ if (style->font)
+ gdk_font_ref (style->font);
+
+ if (style->font_desc)
+ pango_font_description_free (style->font_desc);
+ if (src->font_desc)
+ style->font_desc = pango_font_description_copy (src->font_desc);
+ else
+ style->font_desc = NULL;
+
+ style->xthickness = src->xthickness;
+ style->ythickness = src->ythickness;
+
+ if (style->rc_style)
+ gtk_rc_style_unref (style->rc_style);
+ style->rc_style = src->rc_style;
+ if (src->rc_style)
+ gtk_rc_style_ref (src->rc_style);
+}
+
+static void
+gtk_style_real_init_from_rc (GtkStyle *style,
+ GtkRcStyle *rc_style)
+{
+ GdkFont *old_font;
+ gint i;
+
+ if (rc_style->font_desc)
+ {
+ pango_font_description_free (style->font_desc);
+ style->font_desc = pango_font_description_copy (rc_style->font_desc);
+
+ old_font = style->font;
+ style->font = gdk_font_from_description (style->font_desc);
+ if (style->font)
+ gdk_font_unref (old_font);
+ else
+ style->font = old_font;
+ }
+
+ for (i = 0; i < 5; i++)
+ {
+ if (rc_style->color_flags[i] & GTK_RC_FG)
+ style->fg[i] = rc_style->fg[i];
+ if (rc_style->color_flags[i] & GTK_RC_BG)
+ style->bg[i] = rc_style->bg[i];
+ if (rc_style->color_flags[i] & GTK_RC_TEXT)
+ style->text[i] = rc_style->text[i];
+ if (rc_style->color_flags[i] & GTK_RC_BASE)
+ style->base[i] = rc_style->base[i];
+ }
+
+ if (rc_style->xthickness >= 0)
+ style->xthickness = rc_style->xthickness;
+ if (rc_style->ythickness >= 0)
+ style->ythickness = rc_style->ythickness;
+}
+
+static void
+gtk_style_real_realize (GtkStyle *style)
+{
+ GdkGCValues gc_values;
+ GdkGCValuesMask gc_values_mask;
+
+ gint i;
+
+ for (i = 0; i < 5; i++)
+ {
+ gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
+ gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
+
+ style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
+ style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
+ style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
+ }
+
+ gdk_color_black (style->colormap, &style->black);
+ gdk_color_white (style->colormap, &style->white);
+
+ gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_FONT;
+ if (style->font->type == GDK_FONT_FONT)
+ {
+ gc_values.font = style->font;
+ }
+ else if (style->font->type == GDK_FONT_FONTSET)
+ {
+ gc_values.font = default_font;
+ }
+
+ gc_values.foreground = style->black;
+ style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+ gc_values.foreground = style->white;
+ style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+ for (i = 0; i < 5; i++)
+ {
+ if (style->rc_style && style->rc_style->bg_pixmap_name[i])
+ style->bg_pixmap[i] = gtk_rc_load_image (style->colormap,
+ &style->bg[i],
+ style->rc_style->bg_pixmap_name[i]);
+
+ if (!gdk_color_alloc (style->colormap, &style->fg[i]))
+ g_warning ("unable to allocate color: ( %d %d %d )",
+ style->fg[i].red, style->fg[i].green, style->fg[i].blue);
+ if (!gdk_color_alloc (style->colormap, &style->bg[i]))
+ g_warning ("unable to allocate color: ( %d %d %d )",
+ style->bg[i].red, style->bg[i].green, style->bg[i].blue);
+ if (!gdk_color_alloc (style->colormap, &style->light[i]))
+ g_warning ("unable to allocate color: ( %d %d %d )",
+ style->light[i].red, style->light[i].green, style->light[i].blue);
+ if (!gdk_color_alloc (style->colormap, &style->dark[i]))
+ g_warning ("unable to allocate color: ( %d %d %d )",
+ style->dark[i].red, style->dark[i].green, style->dark[i].blue);
+ if (!gdk_color_alloc (style->colormap, &style->mid[i]))
+ g_warning ("unable to allocate color: ( %d %d %d )",
+ style->mid[i].red, style->mid[i].green, style->mid[i].blue);
+ if (!gdk_color_alloc (style->colormap, &style->text[i]))
+ g_warning ("unable to allocate color: ( %d %d %d )",
+ style->text[i].red, style->text[i].green, style->text[i].blue);
+ if (!gdk_color_alloc (style->colormap, &style->base[i]))
+ g_warning ("unable to allocate color: ( %d %d %d )",
+ style->base[i].red, style->base[i].green, style->base[i].blue);
+
+ gc_values.foreground = style->fg[i];
+ style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+ gc_values.foreground = style->bg[i];
+ style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+ gc_values.foreground = style->light[i];
+ style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+ gc_values.foreground = style->dark[i];
+ style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+ gc_values.foreground = style->mid[i];
+ style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+ gc_values.foreground = style->text[i];
+ style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+ gc_values.foreground = style->base[i];
+ style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+ }
+}
+
+static void
+gtk_style_real_unrealize (GtkStyle *style)
+{
+ int i;
+
+ gtk_gc_release (style->black_gc);
+ gtk_gc_release (style->white_gc);
+
+ for (i = 0; i < 5; i++)
+ {
+ gtk_gc_release (style->fg_gc[i]);
+ gtk_gc_release (style->bg_gc[i]);
+ gtk_gc_release (style->light_gc[i]);
+ gtk_gc_release (style->dark_gc[i]);
+ gtk_gc_release (style->mid_gc[i]);
+ gtk_gc_release (style->text_gc[i]);
+ gtk_gc_release (style->base_gc[i]);
+ }
+}
+
+static void
+gtk_style_real_set_background (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type)
+{
+ GdkPixmap *pixmap;
+ gint parent_relative;
if (style->bg_pixmap[state_type])
{
@@ -1175,8 +1241,6 @@ gtk_style_set_background (GtkStyle *style,
gdk_window_set_background (window, &style->bg[state_type]);
}
-
-/* Default functions */
void
gtk_style_apply_default_background (GtkStyle *style,
GdkWindow *window,
diff --git a/gtk/gtkstyle.h b/gtk/gtkstyle.h
index 45e028eac..8fdebbc7d 100644
--- a/gtk/gtkstyle.h
+++ b/gtk/gtkstyle.h
@@ -84,6 +84,9 @@ struct _GtkStyle
GdkFont *font;
PangoFontDescription *font_desc;
+ gint xthickness;
+ gint ythickness;
+
GdkGC *fg_gc[5];
GdkGC *bg_gc[5];
GdkGC *light_gc[5];
@@ -96,9 +99,6 @@ struct _GtkStyle
GdkPixmap *bg_pixmap[5];
- gint xthickness;
- gint ythickness;
-
/*< private >*/
gint attach_count;
@@ -106,10 +106,6 @@ struct _GtkStyle
gint depth;
GdkColormap *colormap;
- GtkThemeEngine *engine;
-
- gpointer engine_data;
-
GtkRcStyle *rc_style; /* the Rc style from which this style
* was created
*/
@@ -119,7 +115,42 @@ struct _GtkStyle
struct _GtkStyleClass
{
GObjectClass parent_class;
-
+
+ /* Initialize for a particular colormap/depth
+ * combination. style->colormap/style->depth will have
+ * been set at this point. Will typically chain to parent.
+ */
+ void (*realize) (GtkStyle *style);
+
+ /* Clean up for a particular colormap/depth combination. Will
+ * typically chain to parent.
+ */
+ void (*unrealize) (GtkStyle *style);
+
+ /* Make style an exact duplicate of src.
+ */
+ void (*copy) (GtkStyle *style,
+ GtkStyle *src);
+
+ /* Create an empty style of the same type as this style.
+ * The default implementation, which does
+ * g_object_new (G_OBJECT_TYPE (style), NULL);
+ * should work in most cases.
+ */
+ GtkStyle *(*clone) (GtkStyle *style);
+
+ /* Initialize the GtkStyle with the values in the GtkRcStyle.
+ * should chain to the parent implementation.
+ */
+ void (*init_from_rc) (GtkStyle *style,
+ GtkRcStyle *rc_style);
+
+ void (*set_background) (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type);
+
+ /* Drawing functions
+ */
void (*draw_hline) (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
diff --git a/gtk/gtkthemes.c b/gtk/gtkthemes.c
index 571ec6574..e79b737fa 100644
--- a/gtk/gtkthemes.c
+++ b/gtk/gtkthemes.c
@@ -37,20 +37,34 @@
#include "config.h"
#include "gtkintl.h"
-typedef struct _GtkThemeEnginePrivate GtkThemeEnginePrivate;
+typedef struct _GtkThemeEnginePlugin GtkThemeEnginePlugin;
-struct _GtkThemeEnginePrivate {
- GtkThemeEngine engine;
-
+struct _GtkThemeEngine
+{
GModule *library;
- void *name;
void (*init) (GtkThemeEngine *);
void (*exit) (void);
+ GtkRcStyle *(*create_rc_style) ();
+ gchar *name;
+
+ GSList *plugins; /* TypePlugins for this engine */
+
guint refcount;
};
+struct _GtkThemeEnginePlugin
+{
+ GTypePlugin plugin;
+
+ GtkThemeEngine *engine;
+ gchar *engine_name;
+ GTypeInfo info;
+ GType type;
+ GType parent_type;
+};
+
static GHashTable *engine_hash = NULL;
#ifdef __EMX__
@@ -67,7 +81,7 @@ static void gen_8_3_dll_name(gchar *name, gchar *fullname)
GtkThemeEngine*
gtk_theme_engine_get (const gchar *name)
{
- GtkThemeEnginePrivate *result;
+ GtkThemeEngine *result;
if (!engine_hash)
engine_hash = g_hash_table_new (g_str_hash, g_str_equal);
@@ -121,17 +135,20 @@ gtk_theme_engine_get (const gchar *name)
}
else
{
- result = g_new (GtkThemeEnginePrivate, 1);
+ result = g_new (GtkThemeEngine, 1);
result->refcount = 1;
result->name = g_strdup (name);
result->library = library;
+ result->plugins = NULL;
/* extract symbols from the lib */
if (!g_module_symbol (library, "theme_init",
(gpointer *)&result->init) ||
!g_module_symbol (library, "theme_exit",
- (gpointer *)&result->exit))
+ (gpointer *)&result->exit) ||
+ !g_module_symbol (library, "theme_create_rc_style",
+ (gpointer *)&result->create_rc_style))
{
g_warning (g_module_error());
g_free (result);
@@ -156,28 +173,171 @@ gtk_theme_engine_ref (GtkThemeEngine *engine)
{
g_return_if_fail (engine != NULL);
- ((GtkThemeEnginePrivate *)engine)->refcount++;
+ engine->refcount++;
}
void
gtk_theme_engine_unref (GtkThemeEngine *engine)
{
- GtkThemeEnginePrivate *private;
- private = (GtkThemeEnginePrivate *)engine;
+ GSList *tmp_list;
g_return_if_fail (engine != NULL);
- g_return_if_fail (private->refcount > 0);
+ g_return_if_fail (engine->refcount > 0);
- private->refcount--;
+ engine->refcount--;
- if (private->refcount == 0)
+ if (engine->refcount == 0)
{
- private->exit();
+ engine->exit();
+
+ g_hash_table_remove (engine_hash, engine->name);
+
+ tmp_list = engine->plugins;
+ while (tmp_list)
+ {
+ GtkThemeEnginePlugin *plugin = tmp_list->data;
+ plugin->engine = NULL;
+
+ tmp_list = tmp_list->next;
+ }
+ g_slist_free (engine->plugins);
- g_hash_table_remove (engine_hash, private->name);
+ g_module_close (engine->library);
+ g_free (engine->name);
+ g_free (engine);
+ }
+}
+
+GtkRcStyle *
+gtk_theme_engine_create_rc_style (GtkThemeEngine *engine)
+{
+ g_return_val_if_fail (engine != NULL, NULL);
+
+ return engine->create_rc_style ();
+}
+
+static void
+gtk_theme_engine_plugin_ref (GTypePlugin *plugin)
+{
+ GtkThemeEnginePlugin *theme_plugin = (GtkThemeEnginePlugin *)plugin;
+
+ if (theme_plugin->engine == NULL)
+ {
+ gtk_theme_engine_get (theme_plugin->engine_name);
+ if (!theme_plugin->engine)
+ {
+ g_warning ("An attempt to create an instance of a type from\n"
+ "a previously loaded theme engine was made after the engine\n"
+ "was unloaded, but the engine could not be reloaded or no longer\n"
+ "implements the type. Bad things will happen.\n");
+ }
+ }
+ else
+ gtk_theme_engine_ref (theme_plugin->engine);
+}
+
+static void
+gtk_theme_engine_plugin_unref (GTypePlugin *plugin)
+{
+ GtkThemeEnginePlugin *theme_plugin = (GtkThemeEnginePlugin *)plugin;
+
+ g_return_if_fail (theme_plugin->engine != NULL);
+
+ gtk_theme_engine_unref (theme_plugin->engine);
+}
+
+static void
+gtk_theme_engine_complete_type_info (GTypePlugin *plugin,
+ GType g_type,
+ GTypeInfo *info,
+ GTypeValueTable *value_table)
+{
+ GtkThemeEnginePlugin *theme_plugin = (GtkThemeEnginePlugin *)plugin;
+
+ *info = theme_plugin->info;
+}
+
+static GTypePluginVTable gtk_theme_engine_plugin_vtable = {
+ gtk_theme_engine_plugin_ref,
+ gtk_theme_engine_plugin_unref,
+ gtk_theme_engine_complete_type_info,
+ NULL
+};
+
+/**
+ * gtk_theme_engine_register_type:
+ * @engine: a #GtkThemeEngine
+ * @parent_type: the type for the parent class
+ * @type_name: name for the type
+ * @type_info: type information structure
+ *
+ * Looks up or registers a type that is implemented with a particular
+ * theme engine. If a type with name @type_name is already registered,
+ * the #GType identifier for the type is returned, otherwise the type
+ * is newly registered, and the resulting #GType identifier returned.
+ *
+ * As long as any instances of the type exist, the a reference will be
+ * held to the theme engine and the theme engine will not be unloaded.
+ *
+ * Return value: the type identifier for the class.
+ **/
+GType
+gtk_theme_engine_register_type (GtkThemeEngine *engine,
+ GType parent_type,
+ const gchar *type_name,
+ const GTypeInfo *type_info)
+{
+ GtkThemeEnginePlugin *plugin;
+ GType type;
+
+ g_return_val_if_fail (engine != NULL, 0);
+ g_return_val_if_fail (type_name != NULL, 0);
+ g_return_val_if_fail (type_info != NULL, 0);
+
+ type = g_type_from_name (type_name);
+ if (type)
+ plugin = (GtkThemeEnginePlugin *)g_type_get_plugin (type);
+ else
+ {
+ plugin = g_new (GtkThemeEnginePlugin, 1);
+
+ plugin->plugin.vtable = &gtk_theme_engine_plugin_vtable;
+ plugin->engine = NULL;
+ plugin->engine_name = NULL;
+ plugin->parent_type = parent_type;
+ plugin->type = g_type_register_dynamic (parent_type, type_name, (GTypePlugin *)plugin);
+ }
+
+ if (plugin->engine)
+ {
+ if (plugin->engine != engine)
+ {
+ g_warning ("Two different theme engines tried to register '%s'.", type_name);
+ return 0;
+ }
+
+ if (plugin->parent_type != parent_type)
+ {
+ g_warning ("Type '%s' recreated with different parent type.\n"
+ "(was '%s', now '%s')", type_name,
+ g_type_name (plugin->parent_type),
+ g_type_name (parent_type));
+ return 0;
+ }
+ }
+ else
+ {
+ plugin->engine = engine;
+ if (plugin->engine_name)
+ g_free (plugin->engine_name);
+
+ plugin->engine_name = g_strdup (engine->name);
- g_module_close (private->library);
- g_free (private->name);
- g_free (private);
+ plugin->info = *type_info;
+
+ engine->plugins = g_slist_prepend (engine->plugins, plugin);
}
+
+ return plugin->type;
}
+
diff --git a/gtk/gtkthemes.h b/gtk/gtkthemes.h
index a9903606b..66111afc6 100644
--- a/gtk/gtkthemes.h
+++ b/gtk/gtkthemes.h
@@ -37,56 +37,15 @@
extern "C" {
#endif /* __cplusplus */
-
-struct _GtkThemeEngine {
- /* Fill in engine_data pointer in a GtkRcStyle by parsing contents
- * of brackets. Returns G_TOKEN_NONE if succesfull, otherwise returns
- * the token it expected but didn't get.
- */
- guint (*parse_rc_style) (GScanner *scanner, GtkRcStyle *rc_style);
-
- /* Combine RC style data from src into dest. If
- * dest->engine_data is NULL, it should be initialized to default
- * values.
- */
- void (*merge_rc_style) (GtkRcStyle *dest, GtkRcStyle *src);
-
- /* Fill in style->engine_data from rc_style->engine_data */
- void (*rc_style_to_style) (GtkStyle *style, GtkRcStyle *rc_style);
-
- /* Duplicate engine_data from src to dest. The engine_data will
- * not subsequently be modified except by a call to realize_style()
- * so if realize_style() does nothing, refcounting is appropriate.
- */
- void (*duplicate_style) (GtkStyle *dest, GtkStyle *src);
-
- /* If style needs to initialize for a particular colormap/depth
- * combination, do it here. style->colormap/style->depth will have
- * been set at this point, and style itself initialized for
- * the colormap
- */
- void (*realize_style) (GtkStyle *new_style);
-
- /* If style needs to clean up for a particular colormap/depth
- * combination, do it here.
- */
- void (*unrealize_style) (GtkStyle *new_style);
-
- /* Clean up rc_style->engine_data before rc_style is destroyed */
- void (*destroy_rc_style) (GtkRcStyle *rc_style);
-
- /* Clean up style->engine_data before style is destroyed */
- void (*destroy_style) (GtkStyle *style);
-
- void (*set_background) (GtkStyle *style,
- GdkWindow *window,
- GtkStateType state_type);
-};
-
-GtkThemeEngine *gtk_theme_engine_get (const gchar *name);
-void gtk_theme_engine_ref (GtkThemeEngine *engine);
-void gtk_theme_engine_unref (GtkThemeEngine *engine);
-
+GtkThemeEngine * gtk_theme_engine_get (const gchar *name);
+void gtk_theme_engine_ref (GtkThemeEngine *engine);
+void gtk_theme_engine_unref (GtkThemeEngine *engine);
+GtkRcStyle * gtk_theme_engine_create_rc_style (GtkThemeEngine *engine);
+
+GType gtk_theme_engine_register_type (GtkThemeEngine *engine,
+ GType parent_type,
+ const gchar *type_name,
+ const GTypeInfo *type_info);
#ifdef __cplusplus