diff options
author | Owen Taylor <otaylor@redhat.com> | 2000-07-17 23:18:29 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2000-07-17 23:18:29 +0000 |
commit | b8dcd76c998315201651d7caf6452c10d1b6f9b4 (patch) | |
tree | 7b218deb9d49c935e1513291b60bd62aeb3c4f61 | |
parent | 2465ad85f9d97f15841b7d22a87fe08afc19a815 (diff) | |
download | gtk+-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-- | ChangeLog | 29 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 29 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 29 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 29 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 29 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 29 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 29 | ||||
-rw-r--r-- | gtk/gtkentry.c | 9 | ||||
-rw-r--r-- | gtk/gtkrc.c | 284 | ||||
-rw-r--r-- | gtk/gtkrc.h | 32 | ||||
-rw-r--r-- | gtk/gtkstyle.c | 396 | ||||
-rw-r--r-- | gtk/gtkstyle.h | 47 | ||||
-rw-r--r-- | gtk/gtkthemes.c | 198 | ||||
-rw-r--r-- | gtk/gtkthemes.h | 59 |
14 files changed, 852 insertions, 376 deletions
@@ -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 3d8cb6b04f..7684928bf8 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 3d8cb6b04f..7684928bf8 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 3d8cb6b04f..7684928bf8 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 3d8cb6b04f..7684928bf8 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 3d8cb6b04f..7684928bf8 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 3d8cb6b04f..7684928bf8 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 9a3a1948a6..48a91f50dd 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 d693edfdd7..9fbaa444cd 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 8fc54b1e7b..cba8e1f841 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 622ff7b01f..d71387120a 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 45e028eacc..8fdebbc7d5 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 571ec6574e..e79b737fa4 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 = >k_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 a9903606b7..66111afc63 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 |