]> Pileus Git - ~andy/gtk/commitdiff
Restore code to paint the background of the text area which was
authorOwen Taylor <otaylor@redhat.com>
Mon, 17 Jul 2000 23:18:29 +0000 (23:18 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Mon, 17 Jul 2000 23:18:29 +0000 (23:18 +0000)
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.)

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkentry.c
gtk/gtkrc.c
gtk/gtkrc.h
gtk/gtkstyle.c
gtk/gtkstyle.h
gtk/gtkthemes.c
gtk/gtkthemes.h

index 3d8cb6b04f7f874ef9a542c575485c11f91edf6c..7684928bf86b9e605ca3382afffb88c5f33a8b83 100644 (file)
--- 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.
index 3d8cb6b04f7f874ef9a542c575485c11f91edf6c..7684928bf86b9e605ca3382afffb88c5f33a8b83 100644 (file)
@@ -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.
index 3d8cb6b04f7f874ef9a542c575485c11f91edf6c..7684928bf86b9e605ca3382afffb88c5f33a8b83 100644 (file)
@@ -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.
index 3d8cb6b04f7f874ef9a542c575485c11f91edf6c..7684928bf86b9e605ca3382afffb88c5f33a8b83 100644 (file)
@@ -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.
index 3d8cb6b04f7f874ef9a542c575485c11f91edf6c..7684928bf86b9e605ca3382afffb88c5f33a8b83 100644 (file)
@@ -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.
index 3d8cb6b04f7f874ef9a542c575485c11f91edf6c..7684928bf86b9e605ca3382afffb88c5f33a8b83 100644 (file)
@@ -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.
index 3d8cb6b04f7f874ef9a542c575485c11f91edf6c..7684928bf86b9e605ca3382afffb88c5f33a8b83 100644 (file)
@@ -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.
index 9a3a1948a6aa6f576104ece1bbb21325b76ec315..48a91f50dd8b5f8994ccd379b623789cfeddbd34 100644 (file)
@@ -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;
index d693edfdd71661cfa2611ebf0962f6cd53107909..9fbaa444cd6265af0b4c07320de406111ef21db1 100644 (file)
@@ -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
index 8fc54b1e7b4c7534fba22ffcde5a820fdb0766bd..cba8e1f841fd18e8dfd658189e729707fe7eff26 100644 (file)
@@ -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
index 622ff7b01f98937b2611ec1e20651a50551868f6..d71387120a45659894fa7aeccacda3b31efe3058 100644 (file)
 #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,
index 45e028eacc74da9cbff7258756051967c59c8383..8fdebbc7d5c090cb9de57c72b5268c02b7b96b1e 100644 (file)
@@ -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,
index 571ec6574e1087aeb88f442cb539902e21f1a5f6..e79b737fa4f90b78f0a96f319098265a613de212 100644 (file)
 #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;
 }
+
index a9903606b7c9e66bbac73e7305e8409e387c701c..66111afc63f27641939b4b1c6b44a1088c89ce4e 100644 (file)
 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