* Themes added by The Rasterman <raster@redhat.com>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
+ * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public
+ * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include "config.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <gmodule.h>
#include "gtkthemes.h"
-#include "gtkmain.h"
#include "gtkrc.h"
-#include "gtkselection.h"
-#include "gtksignal.h"
-#include "gtkwidget.h"
-#include "config.h"
#include "gtkintl.h"
+#include "gtkdebug.h"
+
-typedef struct _GtkThemeEnginePrivate GtkThemeEnginePrivate;
+typedef struct _GtkThemeEngineClass GtkThemeEngineClass;
-struct _GtkThemeEnginePrivate {
- GtkThemeEngine engine;
+struct _GtkThemeEngine
+{
+ GTypeModule parent_instance;
GModule *library;
- void *name;
- void (*init) (GtkThemeEngine *);
+ void (*init) (GTypeModule *);
void (*exit) (void);
+ GtkRcStyle *(*create_rc_style) ();
+
+ gchar *name;
+};
- guint refcount;
+struct _GtkThemeEngineClass
+{
+ GTypeModuleClass parent_class;
};
static GHashTable *engine_hash = NULL;
-#ifdef __EMX__
-static void gen_8_3_dll_name(gchar *name, gchar *fullname)
+static gboolean
+gtk_theme_engine_load (GTypeModule *module)
{
- /* 8.3 dll filename restriction */
- fullname[0] = '_';
- strncpy (fullname + 1, name, 7);
- fullname[8] = '\0';
- strcat (fullname, ".dll");
-}
-#endif
+ GtkThemeEngine *engine = GTK_THEME_ENGINE (module);
+
+ gchar *engine_path;
+
+ engine_path = gtk_rc_find_module_in_path (engine->name);
+
+ if (!engine_path)
+ {
+ g_warning (_("Unable to locate theme engine in module_path: \"%s\","),
+ engine->name);
+ return FALSE;
+ }
+
+ /* load the lib */
+
+ GTK_NOTE (MISC, g_message ("Loading Theme %s\n", engine_path));
+
+ engine->library = g_module_open (engine_path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+ g_free(engine_path);
+ if (!engine->library)
+ {
+ g_warning ("%s", g_module_error());
+ return FALSE;
+ }
+
+ /* extract symbols from the lib */
+ if (!g_module_symbol (engine->library, "theme_init",
+ (gpointer *)&engine->init) ||
+ !g_module_symbol (engine->library, "theme_exit",
+ (gpointer *)&engine->exit) ||
+ !g_module_symbol (engine->library, "theme_create_rc_style",
+ (gpointer *)&engine->create_rc_style))
+ {
+ g_warning ("%s", g_module_error());
+ g_module_close (engine->library);
+
+ return FALSE;
+ }
+
+ /* call the theme's init (theme_init) function to let it */
+ /* setup anything it needs to set up. */
+ engine->init (module);
+
+ return TRUE;
+}
+
+static void
+gtk_theme_engine_unload (GTypeModule *module)
+{
+ GtkThemeEngine *engine = GTK_THEME_ENGINE (module);
+
+ engine->exit();
+
+ g_module_close (engine->library);
+ engine->library = NULL;
+
+ engine->init = NULL;
+ engine->exit = NULL;
+ engine->create_rc_style = NULL;
+}
+
+static void
+gtk_theme_engine_class_init (GtkThemeEngineClass *class)
+{
+ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
+
+ module_class->load = gtk_theme_engine_load;
+ module_class->unload = gtk_theme_engine_unload;
+}
+
+GType
+gtk_theme_engine_get_type (void)
+{
+ static GType theme_engine_type = 0;
+
+ if (!theme_engine_type)
+ {
+ const GTypeInfo theme_engine_info = {
+ sizeof (GtkThemeEngineClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) gtk_theme_engine_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkThemeEngine),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ };
+
+ theme_engine_type =
+ g_type_register_static (G_TYPE_TYPE_MODULE, I_("GtkThemeEngine"),
+ &theme_engine_info, 0);
+ }
+
+ return theme_engine_type;
+}
GtkThemeEngine*
-gtk_theme_engine_get (gchar *name)
+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);
- /* get the library name for the theme */
-
+ /* get the library name for the theme
+ */
result = g_hash_table_lookup (engine_hash, name);
if (!result)
{
- gchar *fullname;
- gchar *engine_path;
- GModule *library;
-
-#ifndef __EMX__
- fullname = g_module_build_path (NULL, name);
-#else
- fullname = g_malloc (13);
- gen_8_3_dll_name(name, fullname);
-#endif
- engine_path = gtk_rc_find_module_in_path (fullname);
-#ifdef __EMX__
- if (!engine_path)
- {
- /* try theme name without prefix '_' */
- memmove(fullname, fullname + 1, strlen(fullname));
- engine_path = gtk_rc_find_module_in_path (fullname);
- }
-#endif
-
- if (!engine_path)
- {
- g_warning (_("Unable to locate loadable module in module_path: \"%s\","),
- fullname);
-
- g_free (fullname);
- return NULL;
- }
- g_free (fullname);
-
- /* load the lib */
+ result = g_object_new (GTK_TYPE_THEME_ENGINE, NULL);
+ g_type_module_set_name (G_TYPE_MODULE (result), name);
+ result->name = g_strdup (name);
- GTK_NOTE (MISC, g_message ("Loading Theme %s\n", engine_path));
-
- library = g_module_open (engine_path, 0);
- g_free(engine_path);
- if (!library)
- {
- g_warning (g_module_error());
- return NULL;
- }
- else
- {
- result = g_new (GtkThemeEnginePrivate, 1);
-
- result->refcount = 1;
- result->name = g_strdup (name);
- result->library = library;
-
- /* extract symbols from the lib */
- if (!g_module_symbol (library, "theme_init",
- (gpointer *)&result->init) ||
- !g_module_symbol (library, "theme_exit",
- (gpointer *)&result->exit))
- {
- g_warning (g_module_error());
- g_free (result);
- return NULL;
- }
-
- /* call the theme's init (theme_init) function to let it */
- /* setup anything it needs to set up. */
- result->init((GtkThemeEngine *)result);
-
- g_hash_table_insert (engine_hash, result->name, result);
- }
+ g_hash_table_insert (engine_hash, result->name, result);
}
- else
- result->refcount++;
- return (GtkThemeEngine *)result;
-}
+ if (!g_type_module_use (G_TYPE_MODULE (result)))
+ return NULL;
-void
-gtk_theme_engine_ref (GtkThemeEngine *engine)
-{
- g_return_if_fail (engine != NULL);
-
- ((GtkThemeEnginePrivate *)engine)->refcount++;
+ return result;
}
-void
-gtk_theme_engine_unref (GtkThemeEngine *engine)
+GtkRcStyle *
+gtk_theme_engine_create_rc_style (GtkThemeEngine *engine)
{
- GtkThemeEnginePrivate *private;
-
- g_return_if_fail (engine != NULL);
-
- private = (GtkThemeEnginePrivate *)engine;
- private->refcount--;
+ g_return_val_if_fail (engine != NULL, NULL);
- if (private->refcount == 0)
- {
- g_hash_table_remove (engine_hash, private->name);
-
- g_module_close (private->library);
- g_free (private->name);
- g_free (private);
- }
+ return engine->create_rc_style ();
}