]> Pileus Git - ~andy/gtk/blob - gtk/gtkthemes.c
6bb3e7e636f6ec654960f0056bc77b4563cee704
[~andy/gtk] / gtk / gtkthemes.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * Themes added by The Rasterman <raster@redhat.com>
5  * 
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free
18  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <gmodule.h>
31 #include "gtkthemes.h"
32 #include "gtkrc.h"
33 #include "config.h"
34 #include "gtkintl.h"
35
36 typedef struct _GtkThemeEngineClass GtkThemeEngineClass;
37
38 struct _GtkThemeEngine
39 {
40   GTypeModule parent_instance;
41   
42   GModule *library;
43
44   void (*init) (GTypeModule *);
45   void (*exit) (void);
46   GtkRcStyle *(*create_rc_style) ();
47
48   gchar *name;
49 };
50
51 struct _GtkThemeEngineClass
52 {
53   GTypeModuleClass parent_class;
54 };
55
56 static GHashTable *engine_hash = NULL;
57
58 static gboolean
59 gtk_theme_engine_load (GTypeModule *module)
60 {
61   GtkThemeEngine *engine = GTK_THEME_ENGINE (module);
62   
63   gchar *fullname;
64   gchar *engine_path;
65       
66   fullname = g_module_build_path (NULL, engine->name);
67   engine_path = gtk_rc_find_module_in_path (fullname);
68   
69   if (!engine_path)
70     {
71       g_warning (_("Unable to locate theme engine in module_path: \"%s\","),
72                  fullname);
73       
74       g_free (fullname);
75       return FALSE;
76     }
77     
78   g_free (fullname);
79        
80   /* load the lib */
81   
82   GTK_NOTE (MISC, g_message ("Loading Theme %s\n", engine_path));
83        
84   engine->library = g_module_open (engine_path, 0);
85   g_free(engine_path);
86   if (!engine->library)
87     {
88       g_warning (g_module_error());
89       return FALSE;
90     }
91   
92   /* extract symbols from the lib */
93   if (!g_module_symbol (engine->library, "theme_init",
94                         (gpointer *)&engine->init) ||
95       !g_module_symbol (engine->library, "theme_exit", 
96                         (gpointer *)&engine->exit) ||
97       !g_module_symbol (engine->library, "theme_create_rc_style", 
98                         (gpointer *)&engine->create_rc_style))
99     {
100       g_warning (g_module_error());
101       g_module_close (engine->library);
102       
103       return FALSE;
104     }
105             
106   /* call the theme's init (theme_init) function to let it */
107   /* setup anything it needs to set up. */
108   engine->init (module);
109
110   return TRUE;
111 }
112
113 static void
114 gtk_theme_engine_unload (GTypeModule *module)
115 {
116   GtkThemeEngine *engine = GTK_THEME_ENGINE (module);
117
118   engine->exit();
119
120   g_module_close (engine->library);
121   engine->library = NULL;
122
123   engine->init = NULL;
124   engine->exit = NULL;
125   engine->create_rc_style = NULL;
126 }
127
128 static void
129 gtk_theme_engine_class_init (GtkThemeEngineClass *class)
130 {
131   GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
132
133   module_class->load = gtk_theme_engine_load;
134   module_class->unload = gtk_theme_engine_unload;
135 }
136
137 GType
138 gtk_theme_engine_get_type (void)
139 {
140   static GType theme_engine_type = 0;
141
142   if (!theme_engine_type)
143     {
144       static const GTypeInfo theme_engine_info = {
145         sizeof (GtkThemeEngineClass),
146         NULL,           /* base_init */
147         NULL,           /* base_finalize */
148         (GClassInitFunc) gtk_theme_engine_class_init,
149         NULL,           /* class_finalize */
150         NULL,           /* class_data */
151         sizeof (GtkThemeEngine),
152         0,              /* n_preallocs */
153         NULL,           /* instance_init */
154       };
155
156       theme_engine_type = g_type_register_static (G_TYPE_TYPE_MODULE, "GtkThemeEngine", &theme_engine_info, 0);
157     }
158   
159   return theme_engine_type;
160 }
161
162 GtkThemeEngine*
163 gtk_theme_engine_get (const gchar *name)
164 {
165   GtkThemeEngine *result;
166   
167   if (!engine_hash)
168     engine_hash = g_hash_table_new (g_str_hash, g_str_equal);
169
170   /* get the library name for the theme
171    */
172   result = g_hash_table_lookup (engine_hash, name);
173
174   if (!result)
175     {
176       result = GTK_THEME_ENGINE (g_object_new (GTK_TYPE_THEME_ENGINE, NULL));
177       g_type_module_set_name (G_TYPE_MODULE (result), name);
178       result->name = g_strdup (name);
179
180       g_hash_table_insert (engine_hash, result->name, result);
181     }
182
183   if (!g_type_module_use (G_TYPE_MODULE (result)))
184     return NULL;
185
186   return result;
187 }
188
189 GtkRcStyle *
190 gtk_theme_engine_create_rc_style (GtkThemeEngine *engine)
191 {
192   g_return_val_if_fail (engine != NULL, NULL);
193
194   return engine->create_rc_style ();
195 }