summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2010-06-15 17:10:52 +0100
committerBastien Nocera <hadess@hadess.net>2010-06-16 18:18:59 +0100
commit7bf399f1365f8e9f76edb08007b10a9c756f650b (patch)
treeab736fed739b8f8ace84ae9b52e294cfe686d809
parentdc894da891c37c30b0acb648da9d49e2bc9c6d61 (diff)
downloadtotem-7bf399f1365f8e9f76edb08007b10a9c756f650b.tar.gz
Port to libpeas for plugin handling
https://bugzilla.gnome.org/show_bug.cgi?id=604830
-rw-r--r--.gitignore1
-rw-r--r--bindings/python/Makefile.am24
-rw-r--r--bindings/python/__init__.py50
-rw-r--r--bindings/python/override_common.c2
-rw-r--r--bindings/python/totem.defs70
-rw-r--r--bindings/python/totem.override47
-rw-r--r--bindings/python/totemmodule.c230
-rw-r--r--bindings/vala/totem.vapi2
-rw-r--r--configure.in19
-rw-r--r--docs/reference/Makefile.am3
-rw-r--r--src/Makefile.am21
-rw-r--r--src/plugins/Makefile.am42
-rw-r--r--src/plugins/totem-dirs.c182
-rw-r--r--src/plugins/totem-dirs.h (renamed from src/plugins/totem-python-plugin.h)43
-rw-r--r--src/plugins/totem-module.c173
-rw-r--r--src/plugins/totem-module.h56
-rw-r--r--src/plugins/totem-plugin-manager.c533
-rw-r--r--src/plugins/totem-plugin-manager.h78
-rw-r--r--src/plugins/totem-plugins-engine.c845
-rw-r--r--src/plugins/totem-plugins-engine.h48
-rw-r--r--src/plugins/totem-python-module.c566
-rw-r--r--src/plugins/totem-python-module.h61
-rw-r--r--src/plugins/totem-python-plugin.c282
-rw-r--r--src/plugins/totem/Makefile.am4
-rw-r--r--src/plugins/totem/__init__.py6
-rw-r--r--src/plugins/tracker/Makefile.am1
-rw-r--r--src/plugins/tracker/totem-tracker.c15
-rw-r--r--src/plugins/youtube/Makefile.am1
-rw-r--r--src/plugins/youtube/totem-youtube.c14
-rw-r--r--src/totem-interface.c4
-rw-r--r--src/totem-interface.h3
-rw-r--r--src/totem-menu.c4
-rw-r--r--src/totem-object.c14
-rw-r--r--src/totem-private.h2
-rw-r--r--src/totem.h2
35 files changed, 805 insertions, 2643 deletions
diff --git a/.gitignore b/.gitignore
index 5646fde1e..64429a282 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,7 @@ stamp*
*.gmo
*.mo
*.omf
+*.totem-plugin
.deps
.libs
diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am
index ab6077d0a..abb7e4f33 100644
--- a/bindings/python/Makefile.am
+++ b/bindings/python/Makefile.am
@@ -1,33 +1,41 @@
## Process this file with automake to produce Makefile.in
-noinst_LTLIBRARIES = totem-python.la
+plugindir = $(PLUGINDIR)/python/totem
+plugin_PYTHON = __init__.py
-nodist_totem_python_la_SOURCES = totem.c
+pymoduledir = $(libdir)/totem/plugins/python/totem
+pymodule_LTLIBRARIES = _totem.la
-totem_python_la_SOURCES = override_common.c override_common.h
+nodist__totem_la_SOURCES = totem.c
-totem_python_la_LDFLAGS = \
- -module -avoid-version
+_totem_la_SOURCES = override_common.c override_common.h totemmodule.c
-totem_python_la_LIBADD = \
+_totem_la_LDFLAGS = \
+ -module -avoid-version \
+ -export-symbol-regex init_totem
+
+_totem_la_LIBADD = \
$(DEPENDENCY_LIBS) \
$(PYTHON_LIBS) \
$(PYTHON_EXTRA_LIBS) \
$(PYGTK_LIBS)
-totem_python_la_CFLAGS = \
+_totem_la_CFLAGS = \
-I$(top_srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/plugins \
$(DEPENDENCY_CFLAGS) \
+ $(PEAS_CFLAGS) \
$(PYGTK_CFLAGS) \
$(PYTHON_CFLAGS) \
$(AM_CFLAGS) \
- $(WNOERROR_CFLAGS)
+ $(WNOERROR_CFLAGS) \
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\"
totem.c: totem.defs totem.override
( cd $(srcdir) && $(PYGTK_CODEGEN) \
--register $(PYGTK_DEFSDIR)/gtk-types.defs \
+ --register $(PYGTK_DEFSDIR)/libpeas.defs \
--override $*.override \
--prefix py$* $(<F) ) > $@
diff --git a/bindings/python/__init__.py b/bindings/python/__init__.py
new file mode 100644
index 000000000..4933c72c2
--- /dev/null
+++ b/bindings/python/__init__.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+# ex:set ts=4 et sw=4 ai:
+#
+# Totem Python bindings
+# Copyright (C) 2009 Steve Frécinaux
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Import everything from the binary module
+from totem._totem import *
+
+import gobject
+from totem import _totem
+
+def _method_is_overriden(plugin, method_name):
+ child_method = getattr(plugin.__class__, method_name, None)
+ parent_method = getattr(_totem.Plugin, method_name, None)
+ return child_method != parent_method
+
+def _proxy_plugin_method(method_name):
+ def method(self, window):
+ if _method_is_overriden(self, method_name):
+ return getattr(self, method_name)(window)
+ return method
+
+class Plugin(_totem.Plugin):
+ do_activate = _proxy_plugin_method('activate')
+ do_deactivate = _proxy_plugin_method('deactivate')
+ do_update_ui = _proxy_plugin_method('update_ui')
+
+ def do_is_configurable(self):
+ return _method_is_overriden(self, 'create_configure_dialog')
+
+ def do_create_configure_dialog(self):
+ if _method_is_overriden(self, 'create_configure_dialog'):
+ return self.create_configure_dialog()
+
+gobject.type_register(Plugin)
diff --git a/bindings/python/override_common.c b/bindings/python/override_common.c
index 99931e738..719f5e470 100644
--- a/bindings/python/override_common.c
+++ b/bindings/python/override_common.c
@@ -28,7 +28,7 @@
#include "config.h"
-#define NO_IMPORT_PYGOBJECT
+//#define NO_IMPORT_PYGOBJECT
#include "pygobject.h"
#include <pygtk/pygtk.h>
diff --git a/bindings/python/totem.defs b/bindings/python/totem.defs
index ade52e577..fd90c3d13 100644
--- a/bindings/python/totem.defs
+++ b/bindings/python/totem.defs
@@ -3,11 +3,21 @@
(define-object Plugin
(in-module "Totem")
- (parent "GObject")
+ (parent "PeasPlugin")
(c-name "TotemPlugin")
(gtype-id "TOTEM_TYPE_PLUGIN")
)
+(define-virtual is_configurable
+ (of-object "TotemPlugin")
+ (return-type "gboolean")
+)
+
+(define-virtual create_configure_dialog
+ (of-object "TotemPlugin")
+ (return-type "GtkWidget*")
+)
+
(define-object Object
(in-module "Totem")
(parent "GObject")
@@ -45,15 +55,6 @@
)
)
-(define-enum PluginError
- (in-module "Totem")
- (c-name "TotemPluginError")
- (gtype-id "TOTEM_TYPE_PLUGIN_ERROR")
- (values
- '("n" "TOTEM_PLUGIN_ERROR_ACTIVATION")
- )
-)
-
(define-enum RemoteCommand
(in-module "Totem")
(c-name "TotemRemoteCommand")
@@ -105,49 +106,9 @@
;; From totem-plugin.h
-(define-function totem_plugin_error_quark
- (c-name "totem_plugin_error_quark")
- (return-type "GQuark")
-)
-
-(define-method activate
- (of-object "TotemPlugin")
- (c-name "totem_plugin_activate")
- (return-type "gboolean")
- (parameters
- '("TotemObject*" "totem")
- '("GError**" "error")
- )
-)
-
-(define-method deactivate
- (of-object "TotemPlugin")
- (c-name "totem_plugin_deactivate")
- (return-type "none")
- (parameters
- '("TotemObject*" "totem")
- )
-)
-
-(define-method is_configurable
- (of-object "TotemPlugin")
- (c-name "totem_plugin_is_configurable")
- (return-type "gboolean")
-)
-
-(define-method create_configure_dialog
- (of-object "TotemPlugin")
- (c-name "totem_plugin_create_configure_dialog")
- (return-type "GtkWidget*")
-)
-
-(define-method find_file
- (of-object "TotemPlugin")
- (c-name "totem_plugin_find_file")
- (return-type "char*")
- (parameters
- '("const-char*" "file")
- )
+(define-function totem_plugin_get_type
+ (c-name "totem_plugin_get_type")
+ (return-type "GType")
)
(define-method load_interface
@@ -162,7 +123,6 @@
)
)
-
;; From totem.h
(define-method plugins_init
@@ -553,7 +513,7 @@
'("const-char*" "reason")
'("const-char*" "uri")
'("const-char*" "label")
- '("GtkWindow" "parent")
+ '("GtkWindow*" "parent")
)
)
diff --git a/bindings/python/totem.override b/bindings/python/totem.override
index 610e3e297..7ad72e488 100644
--- a/bindings/python/totem.override
+++ b/bindings/python/totem.override
@@ -37,21 +37,12 @@ import gtk.Window as PyGtkWindow_Type
import gtk.gdk.Pixbuf as PyGdkPixbuf_Type
import gtk.ComboBox as PyGtkComboBox_Type
import gtk.CellRenderer as PyGtkCellRenderer_Type
+import libpeas.Plugin as PyPeasPlugin_Type
%%
ignore-glob
*_get_type
*_quark
%%
-override totem_object_plugins_shutdown noargs
-static PyObject *
-_wrap_totem_object_plugins_shutdown (PyGObject *self)
-{
- totem_object_plugins_shutdown ();
-
- Py_INCREF (Py_None);
- return Py_None;
-}
-%%
override totem_action_error kwargs
static PyObject *
_wrap_totem_action_error (PyGObject *self, PyObject *args, PyObject *kwargs)
@@ -79,7 +70,7 @@ _wrap_totem_interface_error_with_link (PyGObject *self, PyObject *args, PyObject
if (!PyArg_ParseTupleAndKeywords (args, kwargs, "ssssO!:TotemObject.interface_error_with_link", kwlist, &title, &reason, &uri, &label, &PyGtkWindow_Type, &parent))
return NULL;
- totem_interface_error_with_link (title, reason, uri, label, GTK_WINDOW(parent->obj), TOTEM_OBJECT(self->obj));
+ totem_interface_error_with_link (title, reason, uri, label, GTK_WINDOW(parent->obj));
Py_INCREF (Py_None);
return Py_None;
@@ -89,26 +80,26 @@ override totem_plugin_load_interface kwargs
static PyObject *
_wrap_totem_plugin_load_interface (PyGObject *self, PyObject *args, PyObject *kwargs)
{
- static char *kwlist[] = { "name", "fatal", "parent", "user_data", NULL };
- char *name;
- gboolean fatal;
- GtkWindow *parent;
- gpointer user_data;
- GtkBuilder *builder;
- PyObject *py_parent;
+ static char *kwlist[] = { "name", "fatal", "parent", "user_data", NULL };
+ char *name;
+ gboolean fatal;
+ GtkWindow *parent;
+ gpointer user_data;
+ GtkBuilder *builder;
+ PyObject *py_parent;
- if (!PyArg_ParseTupleAndKeywords (args, kwargs,"sbOO:TotemPlugin.load_interface", kwlist, &name, &fatal, &py_parent, &user_data))
- return NULL;
- if (pygobject_check (py_parent, &PyGtkWindow_Type)) {
- parent = GTK_WINDOW (pygobject_get (py_parent));
- } else {
- PyErr_SetString (PyExc_TypeError, "parent should be a GtkWindow");
- return NULL;
- }
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs,"sbOO:TotemPlugin.load_interface", kwlist, &name, &fatal, &py_parent, &user_data))
+ return NULL;
+ if (pygobject_check (py_parent, &PyGtkWindow_Type)) {
+ parent = GTK_WINDOW (pygobject_get (py_parent));
+ } else {
+ PyErr_SetString (PyExc_TypeError, "parent should be a GtkWindow");
+ return NULL;
+ }
- builder = totem_plugin_load_interface (TOTEM_PLUGIN (self->obj), name, fatal, parent, user_data);
+ builder = totem_plugin_load_interface (TOTEM_PLUGIN (self->obj), name, fatal, parent, user_data);
- return pygobject_new ((GObject *)builder);
+ return pygobject_new ((GObject *)builder);
}
%%
override totem_get_version noargs
diff --git a/bindings/python/totemmodule.c b/bindings/python/totemmodule.c
new file mode 100644
index 000000000..6d6c91f93
--- /dev/null
+++ b/bindings/python/totemmodule.c
@@ -0,0 +1,230 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * heavily based on code from Rhythmbox and Gedit
+ *
+ * Copyright (C) 2002-2005 Paolo Maggi
+ * Copyright (C) 2007 Bastien Nocera <hadess@hadess.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Sunday 13th May 2007: Bastien Nocera: Add exception clause.
+ * See license_change file for details.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Python.h>
+#include <pygobject.h>
+#include <pygtk/pygtk.h>
+
+#if PY_VERSION_HEX < 0x02050000
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif /* PY_VERSION_HEX */
+
+/* Exported by Totem Python module */
+void pytotem_register_classes (PyObject *d);
+void pytotem_add_constants (PyObject *module, const gchar *strip_prefix);
+extern PyMethodDef pytotem_functions[];
+
+/* We retrieve this to check for correct class hierarchy */
+static PyTypeObject *PyTotemPlugin_Type;
+
+DL_EXPORT (void)
+init_totem (void)
+{
+ PyObject *pygtk, *mdict, *require;
+ PyObject *totem, *gtk, *pygtk_version, *pygtk_required_version;
+ PyObject *gettext, *install, *gettext_args;
+// PyObject *sys_path;
+ struct sigaction old_sigint;
+ gint res;
+ char *argv[] = { "totem", NULL };
+// char **paths;
+// guint i;
+
+ g_message ("inittotem is called");
+#if 0
+ if (Py_IsInitialized ()) {
+ g_warning ("Python should only be initialized once, since it's in class_init");
+ g_return_if_reached ();
+ }
+
+ /* Hack to make python not overwrite SIGINT: this is needed to avoid
+ * the crash reported on gedit bug #326191 */
+
+ /* Save old handler */
+ res = sigaction (SIGINT, NULL, &old_sigint);
+ if (res != 0) {
+ g_warning ("Error initializing Python interpreter: cannot get "
+ "handler to SIGINT signal (%s)",
+ strerror (errno));
+
+ return;
+ }
+
+ /* Python initialization */
+ Py_Initialize ();
+
+ /* Restore old handler */
+ res = sigaction (SIGINT, &old_sigint, NULL);
+ if (res != 0) {
+ g_warning ("Error initializing Python interpreter: cannot restore "
+ "handler to SIGINT signal (%s)",
+ strerror (errno));
+ return;
+ }
+
+ PySys_SetArgv (1, argv);
+#endif
+ /* pygtk.require("2.8") */
+ pygtk = PyImport_ImportModule ("pygtk");
+ if (pygtk == NULL) {
+ g_warning ("Could not import pygtk");
+ PyErr_Print();
+ return;
+ }
+
+ mdict = PyModule_GetDict (pygtk);
+ require = PyDict_GetItemString (mdict, "require");
+ PyObject_CallObject (require, Py_BuildValue ("(S)", PyString_FromString ("2.8")));
+
+ /* import gobject */
+ init_pygobject ();
+
+ /* disable pyg* log hooks, since ours is more interesting */
+#ifdef pyg_disable_warning_redirections
+ pyg_disable_warning_redirections ();
+#endif
+
+ /* import gtk */
+ init_pygtk ();
+
+ pyg_enable_threads ();
+
+ gtk = PyImport_ImportModule ("gtk");
+ if (gtk == NULL) {
+ g_warning ("Could not import gtk");
+ PyErr_Print();
+ return;
+ }
+
+ mdict = PyModule_GetDict (gtk);
+ pygtk_version = PyDict_GetItemString (mdict, "pygtk_version");
+ pygtk_required_version = Py_BuildValue ("(iii)", 2, 12, 0);
+ if (PyObject_Compare (pygtk_version, pygtk_required_version) == -1) {
+ g_warning("PyGTK %s required, but %s found.",
+ PyString_AsString (PyObject_Repr (pygtk_required_version)),
+ PyString_AsString (PyObject_Repr (pygtk_version)));
+ Py_DECREF (pygtk_required_version);
+ return;
+ }
+ Py_DECREF (pygtk_required_version);
+
+#if 0
+ /* import totem */
+ paths = totem_get_plugin_paths ();
+ sys_path = PySys_GetObject ("path");
+ for (i = 0; paths[i] != NULL; i++) {
+ PyObject *path;
+
+ path = PyString_FromString (paths[i]);
+ if (PySequence_Contains (sys_path, path) == 0) {
+ PyList_Insert (sys_path, 0, path);
+ }
+ Py_DECREF (path);
+ }
+ g_strfreev (paths);
+#endif
+ PyObject *mdict2, *tuple;
+
+ /* import gedit */
+ totem = Py_InitModule ("totem._totem", pytotem_functions);
+ mdict = PyModule_GetDict (totem);
+ pytotem_register_classes (mdict);
+ pytotem_add_constants (totem, "TOTEM_");
+
+ /* Set version */
+#if 0
+ tuple = Py_BuildValue ("(iii)",
+ GEDIT_MAJOR_VERSION,
+ GEDIT_MINOR_VERSION,
+ GEDIT_MICRO_VERSION);
+ PyDict_SetItemString (mdict, "version", tuple);
+ Py_DECREF (tuple);
+#endif
+#if 0
+ totem = PyImport_ImportModule ("totem");
+
+ if (totem == NULL) {
+ g_warning ("Could not import Python module 'totem'");
+ PyErr_Print ();
+ return;
+ }
+
+ /* add pytotem_functions */
+ for (res = 0; pytotem_functions[res].ml_name != NULL; res++) {
+ PyObject *func;
+
+ func = PyCFunction_New (&pytotem_functions[res], totem);
+ if (func == NULL) {
+ g_warning ("unable object for function '%s' create", pytotem_functions[res].ml_name);
+ PyErr_Print ();
+ return;
+ }
+ if (PyModule_AddObject (totem, pytotem_functions[res].ml_name, func) < 0) {
+ g_warning ("unable to insert function '%s' in 'totem' module", pytotem_functions[res].ml_name);
+ PyErr_Print ();
+ return;
+ }
+ }
+ mdict = PyModule_GetDict (totem);
+
+ pytotem_register_classes (mdict);
+ pytotem_add_constants (totem, "TOTEM_");
+#endif
+ /* Retrieve the Python type for totem.Plugin */
+ PyTotemPlugin_Type = (PyTypeObject *) PyDict_GetItemString (mdict, "Plugin");
+ if (PyTotemPlugin_Type == NULL) {
+ PyErr_Print ();
+ return;
+ }
+
+ /* i18n support */
+ gettext = PyImport_ImportModule ("gettext");
+ if (gettext == NULL) {
+ g_warning ("Could not import gettext");
+ PyErr_Print();
+ return;
+ }
+
+ mdict = PyModule_GetDict (gettext);
+ install = PyDict_GetItemString (mdict, "install");
+ gettext_args = Py_BuildValue ("ss", GETTEXT_PACKAGE, GNOMELOCALEDIR);
+ PyObject_CallObject (install, gettext_args);
+ Py_DECREF (gettext_args);
+
+ /* ideally totem should clean up the python stuff again at some point,
+ * for which we'd need to save the result of SaveThread so we can then
+ * restore the state in a class_finalize or so, but since totem doesn't
+ * do any clean-up at this point, we'll just skip this as well */
+// PyEval_SaveThread();
+}
+
diff --git a/bindings/vala/totem.vapi b/bindings/vala/totem.vapi
index d67f39375..e8ed670f0 100644
--- a/bindings/vala/totem.vapi
+++ b/bindings/vala/totem.vapi
@@ -102,7 +102,7 @@ namespace Totem {
}
[CCode (cheader_filename = "totem-plugin.h")]
- public abstract class Plugin : GLib.Object {
+ public abstract class Plugin :Peas.Plugin {
[CCode (has_construct_function = false)]
protected Plugin ();
diff --git a/configure.in b/configure.in
index 3dd9f9bf4..b9551b2cb 100644
--- a/configure.in
+++ b/configure.in
@@ -258,6 +258,13 @@ fi
AM_CONDITIONAL(HAVE_XVIDMODE, [test x$have_xvidmode = xyes])
dnl ================================================================
+dnl Plugins support
+dnl ================================================================
+
+PKG_CHECK_MODULES(PEAS, libpeas-1.0)
+PKG_CHECK_MODULES(PEASUI, libpeasui-1.0)
+
+dnl ================================================================
dnl Python plugins
dnl ================================================================
@@ -346,10 +353,6 @@ if test "x$have_python" != "xno"; then
AC_SUBST([PYGTK_CODEGEN])
AC_SUBST([PYGTK_H2DEF])
-dnl uncomment when http://bugzilla.gnome.org/show_bug.cgi?id=351072 fixed
-dnl PKG_CHECK_EXISTS([pygobject-2.0 >= X.XX.X],
-dnl AC_DEFINE([PYGOBJECT_CAN_MARSHAL_GVALUE]))
-
dnl Check for -fno-strict-aliasing
FLAGS="-fno-strict-aliasing"
save_CFLAGS="$CFLAGS"
@@ -377,8 +380,8 @@ dnl ================================================================
AC_MSG_CHECKING([whether Vala plugin support is requested])
AC_ARG_ENABLE([vala],
AS_HELP_STRING([--enable-vala],[Enable Vala plugin support]),
- [enable_vala=$enableval have_vala=$enableval],
- [enable_vala=autodetect have_vala=yes])
+ [enable_vala=$enableval],
+ [enable_vala=no])
AC_MSG_RESULT([$enable_vala])
if test "x$enable_vala" != "xno"; then
AM_PROG_VALAC([$VALA_REQS])
@@ -502,7 +505,8 @@ for plugin in ${used_plugins}; do
fi
;;
publish)
- PKG_CHECK_MODULES(LIBEPC, libepc-ui-1.0 >= 0.3.0, [HAVE_LIBEPC=yes], [HAVE_LIBEPC=no])
+ # FIXME
+ PKG_CHECK_MODULES(LIBEPC, libepc-ui-1.0 >= 0.3.0, [HAVE_LIBEPC=no], [HAVE_LIBEPC=no])
if test "${HAVE_LIBEPC}" != "yes" ; then
plugin_error_or_ignore "you need the easy-publish-and-consume library installed for the publish plugin"
add_plugin="0"
@@ -821,7 +825,6 @@ src/plugins/skipto/Makefile
src/plugins/sample-python/Makefile
src/plugins/sample-vala/Makefile
src/plugins/thumbnail/Makefile
-src/plugins/totem/Makefile
src/plugins/tracker/Makefile
src/plugins/youtube/Makefile
src/plugins/pythonconsole/Makefile
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index 3add362d9..a947590e7 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -138,7 +138,8 @@ GTKDOC_CFLAGS = \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/backend \
-I$(top_srcdir)/src/plugins \
- $(DEPENDENCY_CFLAGS)
+ $(DEPENDENCY_CFLAGS) \
+ $(PEAS_CFLAGS)
GTKDOC_LIBS = \
$(top_builddir)/src/libtotem_main.la \
$(DEPENDENCY_LIBS)
diff --git a/src/Makefile.am b/src/Makefile.am
index b9194a8bc..5b82995e7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,10 +1,9 @@
SUBDIRS = plugins backend
bin_PROGRAMS = totem totem-video-thumbnailer totem-video-indexer totem-audio-preview
+lib_LTLIBRARIES = libtotem_main.la
libexec_PROGRAMS =
-noinst_LTLIBRARIES = \
- libtotem_player.la \
- libtotem_main.la
+noinst_LTLIBRARIES = libtotem_player.la
common_defines = \
-D_REENTRANT \
@@ -102,9 +101,11 @@ libtotem_main_la_CFLAGS = \
$(DBUS_CFLAGS) \
$(MISSING_PLUGINS_CFLAGS) \
$(UNIQUE_CFLAGS) \
+ $(PEASUI_CFLAGS) \
$(AM_CFLAGS)
-libtotem_main_la_LDFLAGS = \
+libtotem_main_la_LDFLAGS = \
+ -export_dynamic \
$(AM_LDFLAGS)
libtotem_main_la_LIBADD = \
@@ -112,6 +113,8 @@ libtotem_main_la_LIBADD = \
backend/libbaconvideowidget.la \
plugins/libtotemmodule.la \
$(UNIQUE_LIBS) \
+ $(PEASUI_LIBS) \
+ $(DEPENDENCY_LIBS) \
$(DBUS_LIBS) \
$(XVIDMODE_LIBS) \
$(XTEST_LIBS) \
@@ -141,12 +144,6 @@ libtotem_main_la_SOURCES += eggsmclient-osx.c
endif
endif
-if ENABLE_PYTHON
-libtotem_main_la_LIBADD += \
- $(PYTHON_LIBS) \
- $(top_builddir)/bindings/python/totem-python.la
-endif
-
# Totem
TOTEMMARSHALFILES = \
@@ -174,17 +171,19 @@ totem_SOURCES = totem.c
totem_CPPFLAGS = \
-I$(top_srcdir)/ \
-I$(srcdir)/backend \
+ -I$(srcdir)/plugins \
$(common_defines) \
-DG_LOG_DOMAIN=\""Totem"\" \
$(AM_CPPFLAGS)
totem_CFLAGS = \
$(UNIQUE_CFLAGS) \
+ $(PEAS_CFLAGS) \
$(WARN_CFLAGS) \
$(DEPENDENCY_CFLAGS) \
$(AM_CFLAGS)
-totem_LDFLAGS = \
+totem_LDFLAGS = \
$(AM_LDFLAGS)
totem_LDADD = \
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 25abd3083..e4feb24cb 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -1,9 +1,10 @@
-SUBDIRS = $(PLUGINS)
-DIST_SUBDIRS = $(ALL_PLUGINS) totem
+SUBDIRS = screenshot
+#SUBDIRS = $(PLUGINS)
+#DIST_SUBDIRS = $(ALL_PLUGINS)
noinst_LTLIBRARIES = libtotemmodule.la
-common_defines = \
+common_defines = \
-D_REENTRANT \
-DDBUS_API_SUBJECT_TO_CHANGE \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
@@ -18,21 +19,20 @@ common_defines = \
modules_flags = -export_dynamic -avoid-version -module
libtotemmodule_la_SOURCES = \
- totem-module.c \
- totem-module.h \
- totem-plugin.c \
- totem-plugin.h \
totem-plugins-engine.c \
totem-plugins-engine.h \
- totem-plugin-manager.c \
- totem-plugin-manager.h
+ totem-dirs.c \
+ totem-dirs.h
libtotemmodule_la_CPPFLAGS = \
$(common_defines) \
$(AM_CPPFLAGS)
+libtotemmodule_la_LDFLAGS = $(AM_LDFLAGS) $(modules_flags)
+
libtotemmodule_la_CFLAGS = \
$(DEPENDENCY_CFLAGS) \
+ $(PEAS_CFLAGS) \
$(WARN_CFLAGS) \
$(DBUS_CFLAGS) \
$(AM_CFLAGS) \
@@ -43,27 +43,3 @@ libtotemmodule_la_CFLAGS = \
-I$(top_srcdir)/src/backend \
-I$(top_srcdir)/src/plugins
-libtotemmodule_la_LDFLAGS = \
- $(AM_LDFLAGS)
-
-if ENABLE_PYTHON
-
-SUBDIRS += totem
-
-libtotemmodule_la_LIBADD = \
- $(DEPENDENCY_LIBS) \
- $(PYTHON_LIBS) \
- $(PYTHON_EXTRA_LIBS) \
- $(PYGTK_LIBS)
-
-libtotemmodule_la_SOURCES += \
- totem-python-module.c \
- totem-python-module.h \
- totem-python-plugin.c \
- totem-python-plugin.h
-
-libtotemmodule_la_CFLAGS += \
- $(NO_STRICT_ALIASING_CFLAGS) \
- $(PYGTK_CFLAGS) \
- $(PYTHON_CFLAGS)
-endif
diff --git a/src/plugins/totem-dirs.c b/src/plugins/totem-dirs.c
new file mode 100644
index 000000000..4209096e6
--- /dev/null
+++ b/src/plugins/totem-dirs.c
@@ -0,0 +1,182 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * heavily based on code from Rhythmbox and Gedit
+ *
+ * Copyright (C) 2002-2005 Paolo Maggi
+ * Copyright (C) 2007 Bastien Nocera <hadess@hadess.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Sunday 13th May 2007: Bastien Nocera: Add exception clause.
+ * See license_change file for details.
+ *
+ */
+
+/**
+ * SECTION:totem-plugin
+ * @short_description: base plugin class and loading/unloading functions
+ * @stability: Unstable
+ * @include: totem-plugin.h
+ *
+ * #TotemPlugin is a general-purpose architecture for adding plugins to Totem, with
+ * derived support for different programming languages.
+ **/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gconf/gconf-client.h>
+
+#include "totem-dirs.h"
+#include "totem-plugins-engine.h"
+#include "totem-uri.h"
+#include "totem-interface.h"
+
+#define UNINSTALLED_PLUGINS_LOCATION "plugins"
+
+char **
+totem_get_plugin_paths (void)
+{
+ GPtrArray *paths;
+ char *path;
+ GConfClient *client;
+ gboolean uninstalled;
+
+ paths = g_ptr_array_new ();
+ uninstalled = FALSE;
+
+#ifdef TOTEM_RUN_IN_SOURCE_TREE
+ path = g_build_filename (UNINSTALLED_PLUGINS_LOCATION, NULL);
+ if (g_file_test (path, G_FILE_TEST_IS_DIR) != FALSE) {
+ uninstalled = TRUE;
+ g_ptr_array_add (paths, path);
+ }
+#endif
+
+ client = gconf_client_get_default ();
+ if (gconf_client_get_bool (client, GCONF_PREFIX"/disable_user_plugins", NULL) == FALSE) {
+ path = g_build_filename (totem_data_dot_dir (), "plugins", NULL);
+ g_ptr_array_add (paths, path);
+ }
+
+ if (uninstalled == FALSE) {
+ path = g_strdup (TOTEM_PLUGIN_DIR);
+ g_ptr_array_add (paths, path);
+ }
+
+ /* And null-terminate the array */
+ g_ptr_array_add (paths, NULL);
+
+ return (char **) g_ptr_array_free (paths, FALSE);
+}
+
+/**
+ * totem_plugin_find_file:
+ * @plugin_name: the plugin name
+ * @file: the file to find
+ *
+ * Finds the specified @file by looking in the plugin paths
+ * listed by totem_get_plugin_paths() and then in the system
+ * Totem data directory.
+ *
+ * This should be used by plugins to find plugin-specific
+ * resource files.
+ *
+ * Return value: a newly-allocated absolute path for the file, or %NULL
+ **/
+char *
+totem_plugin_find_file (const char *plugin_name,
+ const char *file)
+{
+ TotemPluginsEngine *engine;
+ PeasPluginInfo *info;
+ const char *dir;
+ char *tmp;
+ char *ret = NULL;
+
+ engine = totem_plugins_engine_get_default (NULL);
+ info = peas_engine_get_plugin_info (PEAS_ENGINE (engine), plugin_name);
+
+ dir = peas_plugin_info_get_module_dir (info);
+ tmp = g_build_filename (dir, file, NULL);
+ if (g_file_test (tmp, G_FILE_TEST_EXISTS))
+ ret = tmp;
+ else
+ g_free (tmp);
+
+ if (ret == NULL) {
+ dir = peas_plugin_info_get_data_dir (info);
+ tmp = g_build_filename (dir, file, NULL);
+ if (g_file_test (tmp, G_FILE_TEST_EXISTS))
+ ret = tmp;
+ else
+ g_free (tmp);
+ }
+
+ /* global data files */
+ if (ret == NULL)
+ ret = totem_interface_get_full_path (file);
+
+ //FIXME
+#if 0
+ /* ensure it's an absolute path, so doesn't confuse rb_glade_new et al */
+ if (ret && ret[0] != '/') {
+ char *pwd = g_get_current_dir ();
+ char *path = g_strconcat (pwd, G_DIR_SEPARATOR_S, ret, NULL);
+ g_free (ret);
+ g_free (pwd);
+ ret = path;
+ }
+#endif
+ return ret;
+}
+
+/**
+ * totem_plugin_load_interface:
+ * @plugin_name: the plugin name
+ * @name: interface filename
+ * @fatal: %TRUE if it's a fatal error if the interface can't be loaded
+ * @parent: the interface's parent #GtkWindow
+ * @user_data: a pointer to be passed to each signal handler in the interface when they're called
+ *
+ * Loads an interface file (GtkBuilder UI file) for a plugin, given its filename and
+ * assuming it's installed in the plugin's data directory.
+ *
+ * This should be used instead of attempting to load interfaces manually in plugins.
+ *
+ * Return value: the #GtkBuilder instance for the interface
+ **/
+GtkBuilder *
+totem_plugin_load_interface (const char *plugin_name,
+ const char *name,
+ gboolean fatal,
+ GtkWindow *parent,
+ gpointer user_data)
+{
+ GtkBuilder *builder = NULL;
+ char *filename;
+
+ filename = totem_plugin_find_file (plugin_name, name);
+ builder = totem_interface_load_with_full_path (filename,
+ fatal,
+ parent,
+ user_data);
+ g_free (filename);
+
+ return builder;
+}
diff --git a/src/plugins/totem-python-plugin.h b/src/plugins/totem-dirs.h
index 442e3e9e7..57ce86076 100644
--- a/src/plugins/totem-python-plugin.h
+++ b/src/plugins/totem-dirs.h
@@ -1,9 +1,9 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
- * Heavily based on code from Rhythmbox and Gedit.
+ * heavily based on code from Rhythmbox and Gedit
*
- * Copyright (C) 2005 Raphael Slinckx
- * Copyright (C) 2007 Philip Withnall
+ * Copyright (C) 2002-2005 Paolo Maggi
+ * Copyright (C) 2007 Bastien Nocera <hadess@hadess.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,33 +20,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
- * Saturday 19th May 2007: Philip Withnall: Add exception clause.
+ * Sunday 13th May 2007: Bastien Nocera: Add exception clause.
* See license_change file for details.
+ *
*/
-#ifndef TOTEM_PYTHON_OBJECT_H
-#define TOTEM_PYTHON_OBJECT_H
-
-#include <Python.h>
-#include <glib-object.h>
-#include "totem-plugin.h"
-
-G_BEGIN_DECLS
-
-typedef struct
-{
- TotemPlugin parent_slot;
- PyObject *instance;
-} TotemPythonObject;
-
-typedef struct
-{
- TotemPluginClass parent_slot;
- PyObject *type;
-} TotemPythonObjectClass;
-
-GType totem_python_object_get_type (GTypeModule *module, PyObject *type);
+#include <glib.h>
+#include <gtk/gtk.h>
-G_END_DECLS
+char ** totem_get_plugin_paths (void);
+char * totem_plugin_find_file (const char *plugin_name,
+ const char *file);
+GtkBuilder * totem_plugin_load_interface (const char *plugin_name,
+ const char *name,
+ gboolean fatal,
+ GtkWindow *parent,
+ gpointer user_data);
-#endif
diff --git a/src/plugins/totem-module.c b/src/plugins/totem-module.c
deleted file mode 100644
index 1ca311927..000000000
--- a/src/plugins/totem-module.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * This is a based on rb-module.c from Rhythmbox, which is based on
- * gedit-module.h from gedit, which is based on Epiphany source code.
- *
- * Copyright (C) 2003 Marco Pesenti Gritti
- * Copyright (C) 2003, 2004 Christian Persch
- * Copyright (C) 2005 - Paolo Maggi
- * Copyright (C) 2007 - Bastien Nocera <hadess@hadess.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Sunday 13th May 2007: Bastien Nocera: Add exception clause.
- * See license_change file for details.
- *
- */
-
-#include "config.h"
-
-#include "totem-module.h"
-
-#include <gmodule.h>
-
-typedef struct _TotemModuleClass TotemModuleClass;
-
-struct _TotemModuleClass
-{
- GTypeModuleClass parent_class;
-};
-
-struct _TotemModule
-{
- GTypeModule parent_instance;
-
- GModule *library;
-
- gchar *path;
- gchar *name;
- GType type;
-};
-
-typedef GType (*TotemModuleRegisterFunc) (GTypeModule *);
-
-static GObjectClass *parent_class = NULL;
-
-G_DEFINE_TYPE (TotemModule, totem_module, G_TYPE_TYPE_MODULE)
-
-static gboolean
-totem_module_load (GTypeModule *gmodule)
-{
- TotemModule *module = TOTEM_MODULE (gmodule);
- TotemModuleRegisterFunc register_func;
-
- module->library = g_module_open (module->path, 0);
-
- if (module->library == NULL) {
- g_warning ("%s", g_module_error());
- return FALSE;
- }
-
- /* extract symbols from the lib */
- if (!g_module_symbol (module->library, "register_totem_plugin", (void *)&register_func)) {
- g_warning ("%s", g_module_error ());
- g_module_close (module->library);
- return FALSE;
- }
-
- g_assert (register_func);
-
- module->type = register_func (gmodule);
- if (module->type == 0) {
- g_warning ("Invalid totem plugin contained by module %s", module->path);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-totem_module_unload (GTypeModule *gmodule)
-{
- TotemModule *module = TOTEM_MODULE (gmodule);
-
- g_module_close (module->library);
-
- module->library = NULL;
- module->type = 0;
-}
-
-const gchar *
-totem_module_get_path (TotemModule *module)
-{
- g_return_val_if_fail (TOTEM_IS_MODULE (module), NULL);
-
- return module->path;
-}
-
-GObject *
-totem_module_new_object (TotemModule *module)
-{
- GObject *obj;
-
- if (module->type == 0) {
- return NULL;
- }
-
- obj = g_object_new (module->type,
- "name", module->name,
- NULL);
- return obj;
-}
-
-static void
-totem_module_init (TotemModule *module)
-{
-
-}
-
-static void
-totem_module_finalize (GObject *object)
-{
- TotemModule *module = TOTEM_MODULE (object);
-
- g_free (module->path);
- g_free (module->name);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-totem_module_class_init (TotemModuleClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
-
- parent_class = (GObjectClass *) g_type_class_peek_parent (class);
-
- object_class->finalize = totem_module_finalize;
-
- module_class->load = totem_module_load;
- module_class->unload = totem_module_unload;
-}
-
-TotemModule *
-totem_module_new (const gchar *path, const char *module)
-{
- TotemModule *result;
-
- if (path == NULL || path[0] == '\0') {
- return NULL;
- }
-
- result = g_object_new (TOTEM_TYPE_MODULE, NULL);
-
- g_type_module_set_name (G_TYPE_MODULE (result), path);
- result->path = g_strdup (path);
- result->name = g_strdup (module);
-
- return result;
-}
-
diff --git a/src/plugins/totem-module.h b/src/plugins/totem-module.h
deleted file mode 100644
index d485f40d1..000000000
--- a/src/plugins/totem-module.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This is a based on rb-module.h from Rhythmbox, which is based on
- * gedit-module.h from gedit, which is based on Epiphany source code.
- *
- * Copyright (C) 2003 Marco Pesenti Gritti
- * Copyright (C) 2003, 2004 Christian Persch
- * Copyright (C) 2005 - Paolo Maggi
- * Copyright (C) 2007 - Bastien Nocera <hadess@hadess.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Sunday 13th May 2007: Bastien Nocera: Add exception clause.
- * See license_change file for details.
- *
- */
-
-#ifndef TOTEM_MODULE_H
-#define TOTEM_MODULE_H
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define TOTEM_TYPE_MODULE (totem_module_get_type ())
-#define TOTEM_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TOTEM_TYPE_MODULE, TotemModule))
-#define TOTEM_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TOTEM_TYPE_MODULE, TotemModuleClass))
-#define TOTEM_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TOTEM_TYPE_MODULE))
-#define TOTEM_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TOTEM_TYPE_MODULE))
-#define TOTEM_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TOTEM_TYPE_MODULE, TotemModuleClass))
-
-typedef struct _TotemModule TotemModule;
-
-GType totem_module_get_type (void) G_GNUC_CONST;;
-
-TotemModule *totem_module_new (const gchar *path, const char *module);
-
-const gchar *totem_module_get_path (TotemModule *module);
-
-GObject *totem_module_new_object (TotemModule *module);
-
-G_END_DECLS
-
-#endif
diff --git a/src/plugins/totem-plugin-manager.c b/src/plugins/totem-plugin-manager.c
deleted file mode 100644
index 26331b021..000000000
--- a/src/plugins/totem-plugin-manager.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * heavily based on code from Rhythmbox and Gedit
- *
- * Copyright (C) 2002 Paolo Maggi and James Willcox
- * Copyright (C) 2003-2005 Paolo Maggi
- * Copyright (C) 2007 Bastien Nocera <hadess@hadess.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Sunday 13th May 2007: Bastien Nocera: Add exception clause.
- * See license_change file for details.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include "totem-interface.h"
-#include "totem-plugin-manager.h"
-#include "totem-plugins-engine.h"
-#include "totem-plugin.h"
-
-enum
-{
- ACTIVE_COLUMN,
- VISIBLE_COLUMN,
- INFO_COLUMN,
- N_COLUMNS
-};
-
-#define PLUGIN_MANAGER_NAME_TITLE _("Plugin")
-#define PLUGIN_MANAGER_ACTIVE_TITLE _("Enabled")
-
-#define TOTEM_PLUGIN_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), TOTEM_TYPE_PLUGIN_MANAGER, TotemPluginManagerPrivate))
-
-struct _TotemPluginManagerPrivate
-{
- GList *plugins;
- GtkWidget *tree;
- GtkTreeModel *plugin_model;
-
- GtkWidget *configure_button;
- GtkWidget *header_hbox;
- GtkWidget *plugin_icon;
- GtkWidget *site_text;
- GtkWidget *copyright_text;
- GtkWidget *authors_text;
- GtkWidget *description_text;
- GtkWidget *plugin_title;
-};
-
-G_DEFINE_TYPE(TotemPluginManager, totem_plugin_manager, GTK_TYPE_VBOX)
-
-static void totem_plugin_manager_finalize (GObject *o);
-static TotemPluginInfo *plugin_manager_get_selected_plugin (TotemPluginManager *pm);
-static void plugin_manager_toggle_active (GtkTreeIter *iter, GtkTreeModel *model, TotemPluginManager *pm);
-static void plugin_manager_toggle_all (TotemPluginManager *pm);
-
-/* Callback functions for GtkBuilder */
-G_MODULE_EXPORT void configure_button_cb (GtkWidget *button, TotemPluginManager *pm);
-
-static void
-totem_plugin_manager_class_init (TotemPluginManagerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = totem_plugin_manager_finalize;
-
- g_type_class_add_private (object_class, sizeof (TotemPluginManagerPrivate));
-}
-
-void
-configure_button_cb (GtkWidget *button,
- TotemPluginManager *pm)
-{
- TotemPluginInfo *info;
- GtkWindow *toplevel;
-
- info = plugin_manager_get_selected_plugin (pm);
-
- g_return_if_fail (info != NULL);
-
- toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (pm)));
-
- totem_plugins_engine_configure_plugin (info, toplevel);
-}
-
-static void
-plugin_manager_view_cell_cb (GtkTreeViewColumn *tree_column,
- GtkCellRenderer *cell,
- GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gpointer data)
-{
- TotemPluginInfo *info;
-
- g_return_if_fail (tree_model != NULL);
- g_return_if_fail (tree_column != NULL);
-
- gtk_tree_model_get (tree_model, iter, INFO_COLUMN, &info, -1);
-
- if (info == NULL)
- return;
-
- g_return_if_fail (totem_plugins_engine_get_plugin_name (info) != NULL);
-
- g_object_set (G_OBJECT (cell),
- "text",
- totem_plugins_engine_get_plugin_name (info),
- NULL);
-}
-
-static void
-active_toggled_cb (GtkCellRendererToggle *cell,
- gchar *path_str,
- TotemPluginManager *pm)
-{
- GtkTreeIter iter;
- GtkTreePath *path;
- GtkTreeModel *model;
-
- path = gtk_tree_path_new_from_string (path_str);
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
- g_return_if_fail (model != NULL);
-
- if (gtk_tree_model_get_iter (model, &iter, path))
- plugin_manager_toggle_active (&iter, model, pm);
-
- gtk_tree_path_free (path);
-}
-
-static void
-cursor_changed_cb (GtkTreeSelection *selection,
- gpointer data)
-{
- TotemPluginManager *pm = data;
- GtkTreeView *view;
- TotemPluginInfo *info;
- char *string;
- GdkPixbuf *icon;
-
- view = gtk_tree_selection_get_tree_view (selection);
- info = plugin_manager_get_selected_plugin (pm);
-
- if (info == NULL)
- return;
-
- /* update info widgets */
- string = g_strdup_printf ("<span size=\"x-large\">%s</span>",
- totem_plugins_engine_get_plugin_name (info));
- gtk_label_set_markup (GTK_LABEL (pm->priv->plugin_title), string);
- g_free (string);
- gtk_label_set_text (GTK_LABEL (pm->priv->description_text),
- totem_plugins_engine_get_plugin_description (info));
- gtk_label_set_text (GTK_LABEL (pm->priv->copyright_text),
- totem_plugins_engine_get_plugin_copyright (info));
- gtk_label_set_text (GTK_LABEL (pm->priv->site_text),
- totem_plugins_engine_get_plugin_website (info));
-
- string = g_strjoinv ("\n", (gchar**)totem_plugins_engine_get_plugin_authors (info));
- gtk_label_set_text (GTK_LABEL (pm->priv->authors_text), string);
- g_free (string);
-
- icon = totem_plugins_engine_get_plugin_icon (info);
- if (icon != NULL) {
- /* rescale icon to fit header if needed */
- GdkPixbuf *icon_scaled;
- gint width, height, header_height;
- GtkAllocation allocation;
-
- width = gdk_pixbuf_get_width (icon);
- height = gdk_pixbuf_get_height (icon);
- gtk_widget_get_allocation (pm->priv->header_hbox, &allocation);
- header_height = allocation.height;
- if (height > header_height) {
- icon_scaled = gdk_pixbuf_scale_simple (icon,
- (gfloat)width/height*header_height, header_height,
- GDK_INTERP_BILINEAR);
- gtk_image_set_from_pixbuf (GTK_IMAGE (pm->priv->plugin_icon), icon_scaled);
- g_object_unref (G_OBJECT (icon_scaled));
- } else {
- gtk_image_set_from_pixbuf (GTK_IMAGE (pm->priv->plugin_icon), icon);
- }
- } else {
- gtk_image_set_from_pixbuf (GTK_IMAGE (pm->priv->plugin_icon), NULL);
- }
-
- gtk_widget_set_sensitive (GTK_WIDGET (pm->priv->configure_button),
- (info != NULL) &&
- totem_plugins_engine_plugin_is_configurable (info));
-}
-
-static void
-row_activated_cb (GtkTreeView *tree_view,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- gpointer data)
-{
- TotemPluginManager *pm = data;
- GtkTreeIter iter;
- GtkTreeModel *model;
- gboolean found;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
- g_return_if_fail (model != NULL);
-
- found = gtk_tree_model_get_iter (model, &iter, path);
- g_return_if_fail (found);
-
- plugin_manager_toggle_active (&iter, model, pm);
-}
-
-static void
-column_clicked_cb (GtkTreeViewColumn *tree_column,
- gpointer data)
-{
- TotemPluginManager *pm = TOTEM_PLUGIN_MANAGER (data);
-
- plugin_manager_toggle_all (pm);
-}
-
-static void
-plugin_manager_populate_lists (TotemPluginManager *pm)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- GList *p;
-
- for (p = pm->priv->plugins; p != NULL; p = g_list_next (p)) {
- TotemPluginInfo *info;
- info = (TotemPluginInfo *)p->data;
-
- gtk_list_store_append (GTK_LIST_STORE (pm->priv->plugin_model), &iter);
- gtk_list_store_set (GTK_LIST_STORE (pm->priv->plugin_model), &iter,
- ACTIVE_COLUMN, totem_plugins_engine_plugin_is_active (info),
- VISIBLE_COLUMN, totem_plugins_engine_plugin_is_visible (info),
- INFO_COLUMN, info,
- -1);
- }
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter)) {
- GtkTreeSelection *selection;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
- g_return_if_fail (selection != NULL);
-
- gtk_tree_selection_select_iter (selection, &iter);
- }
-}
-
-static void
-plugin_manager_set_active (GtkTreeIter *iter,
- GtkTreeModel *model,
- gboolean active,
- TotemPluginManager *pm)
-{
- TotemPluginInfo *info;
- GtkTreeIter child_iter;
-
- gtk_tree_model_get (model, iter, INFO_COLUMN, &info, -1);
-
- g_return_if_fail (info != NULL);
-
- if (active) {
- /* activate the plugin */
- if (!totem_plugins_engine_activate_plugin (info)) {
- active ^= 1;
- }
- } else {
- /* deactivate the plugin */
- if (!totem_plugins_engine_deactivate_plugin (info)) {
- active ^= 1;
- }
- }
-
- /* set new value */
- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
- &child_iter, iter);
- gtk_list_store_set (GTK_LIST_STORE (pm->priv->plugin_model),
- &child_iter,
- ACTIVE_COLUMN,
- totem_plugins_engine_plugin_is_active (info),
- -1);
-
- /* cause the configure button sensitivity to be updated */
- cursor_changed_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree)), pm);
-}
-
-static void
-plugin_manager_toggle_active (GtkTreeIter *iter,
- GtkTreeModel *model,
- TotemPluginManager *pm)
-{
- gboolean active, visible;
-
- gtk_tree_model_get (model, iter,
- ACTIVE_COLUMN, &active,
- VISIBLE_COLUMN, &visible,
- -1);
-
- if (visible) {
- active ^= 1;
- plugin_manager_set_active (iter, model, active, pm);
- }
-}
-
-static TotemPluginInfo *
-plugin_manager_get_selected_plugin (TotemPluginManager *pm)
-{
- TotemPluginInfo *info = NULL;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreeSelection *selection;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
- g_return_val_if_fail (model != NULL, NULL);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
- g_return_val_if_fail (selection != NULL, NULL);
-
- if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
- gtk_tree_model_get (model, &iter, INFO_COLUMN, &info, -1);
- }
-
- return info;
-}
-
-static void
-plugin_manager_toggle_all (TotemPluginManager *pm)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- static gboolean active;
-
- active ^= 1;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (pm->priv->tree));
-
- g_return_if_fail (model != NULL);
-
- if (gtk_tree_model_get_iter_first (model, &iter)) {
- do {
- plugin_manager_set_active (&iter, model, active, pm);
- } while (gtk_tree_model_iter_next (model, &iter));
- }
-}
-
-/* Callback used as the interactive search comparison function */
-static gboolean
-name_search_cb (GtkTreeModel *model,
- gint column,
- const gchar *key,
- GtkTreeIter *iter,
- gpointer data)
-{
- TotemPluginInfo *info;
- gchar *normalized_string;
- gchar *normalized_key;
- gchar *case_normalized_string;
- gchar *case_normalized_key;
- gint key_len;
- gboolean retval;
-
- gtk_tree_model_get (model, iter, INFO_COLUMN, &info, -1);
- if (!info)
- return FALSE;
-
- normalized_string = g_utf8_normalize (totem_plugins_engine_get_plugin_name (info), -1, G_NORMALIZE_ALL);
- normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
- case_normalized_string = g_utf8_casefold (normalized_string, -1);
- case_normalized_key = g_utf8_casefold (normalized_key, -1);
-
- key_len = strlen (case_normalized_key);
-
- /* Oddly enough, this callback must return whether to stop the search
- * because we found a match, not whether we actually matched.
- */
- retval = (strncmp (case_normalized_key, case_normalized_string, key_len) != 0);
-
- g_free (normalized_key);
- g_free (normalized_string);
- g_free (case_normalized_key);
- g_free (case_normalized_string);
-
- return retval;
-}
-
-static void
-plugin_manager_construct_tree (TotemPluginManager *pm)
-{
- GtkTreeViewColumn *column;
- GtkCellRenderer *cell;
- GtkTreeModel *filter;
- GtkTreeSelection *selection;
-
- pm->priv->plugin_model = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_POINTER));
- filter = gtk_tree_model_filter_new (pm->priv->plugin_model, NULL);
- gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), VISIBLE_COLUMN);
- gtk_tree_view_set_model (GTK_TREE_VIEW (pm->priv->tree), filter);
- g_object_unref (filter);
-
- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (pm->priv->tree), TRUE);
- gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (pm->priv->tree), TRUE);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pm->priv->tree));
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
-
- /* first column */
- cell = gtk_cell_renderer_toggle_new ();
- g_signal_connect (cell,
- "toggled",
- G_CALLBACK (active_toggled_cb),
- pm);
- column = gtk_tree_view_column_new_with_attributes (PLUGIN_MANAGER_ACTIVE_TITLE,
- cell,
- "active",
- ACTIVE_COLUMN,
- NULL);
- gtk_tree_view_column_set_clickable (column, TRUE);
- gtk_tree_view_column_set_resizable (column, TRUE);
- g_signal_connect (column, "clicked", G_CALLBACK (column_clicked_cb), pm);
- gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column);
-
- /* second column */
- cell = gtk_cell_renderer_text_new ();
- column = gtk_tree_view_column_new_with_attributes (PLUGIN_MANAGER_NAME_TITLE, cell, NULL);
- gtk_tree_view_column_set_resizable (column, TRUE);
- gtk_tree_view_column_set_cell_data_func (column, cell, plugin_manager_view_cell_cb,
- pm, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (pm->priv->tree), column);
-
- /* Enable search for our non-string column */
- gtk_tree_view_set_search_column (GTK_TREE_VIEW (pm->priv->tree), INFO_COLUMN);
- gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (pm->priv->tree),
- name_search_cb,
- NULL,
- NULL);
-
- g_signal_connect (selection,
- "changed",
- G_CALLBACK (cursor_changed_cb),
- pm);
- g_signal_connect (pm->priv->tree,
- "row_activated",
- G_CALLBACK (row_activated_cb),
- pm);
-
- gtk_widget_show (pm->priv->tree);
-}
-
-static int
-plugin_name_cmp (gconstpointer a, gconstpointer b)
-{
- TotemPluginInfo *lhs = (TotemPluginInfo*)a;
- TotemPluginInfo *rhs = (TotemPluginInfo*)b;
- return strcmp (totem_plugins_engine_get_plugin_name (lhs),
- totem_plugins_engine_get_plugin_name (rhs));
-}
-
-static void
-totem_plugin_manager_init (TotemPluginManager *pm)
-{
- GtkBuilder *xml;
- GtkWidget *plugins_window;
-
- pm->priv = TOTEM_PLUGIN_MANAGER_GET_PRIVATE (pm);
-
- xml = totem_interface_load ("plugins.ui", TRUE, NULL, pm);
-
- gtk_container_add (GTK_CONTAINER (pm), GTK_WIDGET (gtk_builder_get_object (xml, "plugins_vbox")));
-
- gtk_box_set_spacing (GTK_BOX (pm), 6);
-
- pm->priv->tree = gtk_tree_view_new ();
- plugins_window = GTK_WIDGET (gtk_builder_get_object (xml, "plugins_list_window"));
- gtk_container_add (GTK_CONTAINER (plugins_window), pm->priv->tree);
-
- pm->priv->configure_button = GTK_WIDGET (gtk_builder_get_object (xml, "configure_button"));
- pm->priv->header_hbox = GTK_WIDGET (gtk_builder_get_object (xml, "header_hbox"));
- pm->priv->plugin_title = GTK_WIDGET (gtk_builder_get_object (xml, "plugin_title"));
-
- pm->priv->plugin_icon = GTK_WIDGET (gtk_builder_get_object (xml, "plugin_icon"));
- pm->priv->site_text = GTK_WIDGET (gtk_builder_get_object (xml, "site_text"));
- pm->priv->copyright_text = GTK_WIDGET (gtk_builder_get_object (xml, "copyright_text"));
- pm->priv->authors_text = GTK_WIDGET (gtk_builder_get_object (xml, "authors_text"));
- pm->priv->description_text = GTK_WIDGET (gtk_builder_get_object (xml, "description_text"));
-
- plugin_manager_construct_tree (pm);
-
- /* get the list of available plugins (or installed) */
- pm->priv->plugins = totem_plugins_engine_get_plugins_list ();
- pm->priv->plugins = g_list_sort (pm->priv->plugins, plugin_name_cmp);
- plugin_manager_populate_lists (pm);
- g_object_unref (xml);
-}
-
-GtkWidget *
-totem_plugin_manager_new (void)
-{
- return g_object_new (TOTEM_TYPE_PLUGIN_MANAGER, 0);
-}
-
-static void
-totem_plugin_manager_finalize (GObject *o)
-{
- TotemPluginManager *pm = TOTEM_PLUGIN_MANAGER (o);
-
- g_list_free (pm->priv->plugins);
-
- G_OBJECT_CLASS (totem_plugin_manager_parent_class)->finalize (o);
-}
diff --git a/src/plugins/totem-plugin-manager.h b/src/plugins/totem-plugin-manager.h
deleted file mode 100644
index 6db825b7c..000000000
--- a/src/plugins/totem-plugin-manager.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * heavily based on code from Rhythmbox and Gedit
- *
- * Copyright (C) 2002 Paolo Maggi and James Willcox
- * Copyright (C) 2003-2005 Paolo Maggi
- * Copyright (C) 2007 Bastien Nocera <hadess@hadess.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Sunday 13th May 2007: Bastien Nocera: Add exception clause.
- * See license_change file for details.
- *
- */
-
-#ifndef __TOTEM_PLUGIN_MANAGER_H__
-#define __TOTEM_PLUGIN_MANAGER_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-/*
- * Type checking and casting macros
- */
-#define TOTEM_TYPE_PLUGIN_MANAGER (totem_plugin_manager_get_type())
-#define TOTEM_PLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TOTEM_TYPE_PLUGIN_MANAGER, TotemPluginManager))
-#define TOTEM_PLUGIN_MANAGER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TOTEM_TYPE_PLUGIN_MANAGER, TotemPluginManager const))
-#define TOTEM_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TOTEM_TYPE_PLUGIN_MANAGER, TotemPluginManagerClass))
-#define TOTEM_IS_PLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TOTEM_TYPE_PLUGIN_MANAGER))
-#define TOTEM_IS_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TOTEM_TYPE_PLUGIN_MANAGER))
-#define TOTEM_PLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TOTEM_TYPE_PLUGIN_MANAGER, TotemPluginManagerClass))
-
-/* Private structure type */
-typedef struct _TotemPluginManagerPrivate TotemPluginManagerPrivate;
-
-/*
- * Main object structure
- */
-typedef struct
-{
- GtkVBox vbox;
-
- /*< private > */
- TotemPluginManagerPrivate *priv;
-} TotemPluginManager;
-
-/*
- * Class definition
- */
-typedef struct
-{
- GtkVBoxClass parent_class;
-} TotemPluginManagerClass;
-
-/*
- * Public methods
- */
-GType totem_plugin_manager_get_type (void) G_GNUC_CONST;
-
-GtkWidget *totem_plugin_manager_new (void);
-
-G_END_DECLS
-
-#endif /* __TOTEM_PLUGIN_MANAGER_H__ */
diff --git a/src/plugins/totem-plugins-engine.c b/src/plugins/totem-plugins-engine.c
index 16e3c33be..7972838b6 100644
--- a/src/plugins/totem-plugins-engine.c
+++ b/src/plugins/totem-plugins-engine.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Plugin engine for Totem, heavily based on the code from Rhythmbox,
- * which is based heavily on the code from gedit.
+ * which is based heavily on the code from totem.
*
* Copyright (C) 2002-2005 Paolo Maggi
* 2006 James Livingston <jrl@ids.org.au>
@@ -36,744 +36,275 @@
#include <glib/gi18n.h>
#include <glib.h>
#include <gconf/gconf-client.h>
+#include <girepository.h>
+#include <libpeas/peas-activatable.h>
+#include <libpeas/peas-extension-set.h>
-#include "totem-plugin.h"
-
-#include "totem-module.h"
-#include "totem-interface.h"
-
-#ifdef ENABLE_PYTHON
-#include "totem-python-module.h"
-#endif
-
+#include "totem-dirs.h"
#include "totem-plugins-engine.h"
-#define PLUGIN_EXT ".totem-plugin"
#define GCONF_PREFIX_PLUGINS GCONF_PREFIX"/plugins"
#define GCONF_PREFIX_PLUGIN GCONF_PREFIX"/plugins/%s"
#define GCONF_PLUGIN_ACTIVE GCONF_PREFIX_PLUGINS"/%s/active"
#define GCONF_PLUGIN_HIDDEN GCONF_PREFIX_PLUGINS"/%s/hidden"
-typedef enum
-{
- TOTEM_PLUGIN_LOADER_C,
- TOTEM_PLUGIN_LOADER_PY
-} TotemPluginLang;
-
-struct _TotemPluginInfo
-{
- gchar *file;
-
- gchar *location;
- TotemPluginLang lang;
- GTypeModule *module;
-
- gchar *name;
- gchar *desc;
- gchar **authors;
- gchar *copyright;
- gchar *website;
-
- gchar *icon_name;
- GdkPixbuf *icon_pixbuf;
-
- TotemPlugin *plugin;
-
- gboolean builtin;
- gboolean active;
- gboolean visible;
- guint active_notification_id;
- guint visible_notification_id;
-};
-
-static void totem_plugin_info_free (TotemPluginInfo *info);
-static void totem_plugins_engine_plugin_active_cb (GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- TotemPluginInfo *info);
-static void totem_plugins_engine_plugin_visible_cb (GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- TotemPluginInfo *info);
-static gboolean totem_plugins_engine_activate_plugin_real (TotemPluginInfo *info,
- TotemObject *totem,
- GError **error);
-static void totem_plugins_engine_deactivate_plugin_real (TotemPluginInfo *info,
- TotemObject *totem);
-
-static GHashTable *totem_plugins = NULL;
-guint garbage_collect_id = 0;
-TotemObject *totem_plugins_object = NULL;
-static GConfClient *client = NULL;
-
-static TotemPluginInfo *
-totem_plugins_engine_load (const gchar *file)
-{
- TotemPluginInfo *info;
- GKeyFile *plugin_file = NULL;
- GError *err = NULL;
- gchar *str;
-
- g_return_val_if_fail (file != NULL, NULL);
-
- info = g_new0 (TotemPluginInfo, 1);
- info->file = g_strdup (file);
-
- plugin_file = g_key_file_new ();
- if (!g_key_file_load_from_file (plugin_file, file, G_KEY_FILE_NONE, NULL)) {
- g_warning ("Bad plugin file: %s", file);
- goto error;
- }
-
- if (!g_key_file_has_key (plugin_file,
- "Totem Plugin",
- "IAge",
- NULL)) {
- goto error;
- }
-
- /* Check IAge=1 */
- if (g_key_file_get_integer (plugin_file,
- "Totem Plugin",
- "IAge",
- NULL) != 1) {
- goto error;
- }
-
- /* Get Location */
- str = g_key_file_get_string (plugin_file,
- "Totem Plugin",
- "Module",
- NULL);
- if (str) {
- info->location = str;
- } else {
- g_warning ("Could not find 'Module' in %s", file);
- goto error;
- }
-
- /* Get the loader for this plugin */
- str = g_key_file_get_string (plugin_file,
- "Totem Plugin",
- "Loader",
- NULL);
- if (str && strcmp(str, "python") == 0) {
- info->lang = TOTEM_PLUGIN_LOADER_PY;
-#ifndef ENABLE_PYTHON
- g_warning ("Cannot load Python extension '%s', Totem was not compiled with Python support", file);
- g_free (str);
- goto error;
-#endif
- } else {
- info->lang = TOTEM_PLUGIN_LOADER_C;
- }
- g_free (str);
-
- /* Get Name */
- str = g_key_file_get_locale_string (plugin_file,
- "Totem Plugin",
- "Name",
- NULL, NULL);
- if (str) {
- info->name = str;
- } else {
- g_warning ("Could not find 'Name' in %s", file);
- goto error;
- }
-
- /* Get Description */
- str = g_key_file_get_locale_string (plugin_file,
- "Totem Plugin",
- "Description",
- NULL, NULL);
- if (str) {
- info->desc = str;
- } else {
- info->desc = g_strdup ("");
- }
-
- /* Get icon name */
- str = g_key_file_get_string (plugin_file,
- "Totem Plugin",
- "Icon",
- NULL);
- if (str) {
- info->icon_name = str;
- } else {
- info->icon_name = g_strdup ("");
- }
-
- /* Get Authors */
- info->authors = g_key_file_get_string_list (plugin_file,
- "Totem Plugin",
- "Authors",
- NULL, NULL);
-
- /* Get Copyright */
- str = g_key_file_get_string (plugin_file,
- "Totem Plugin",
- "Copyright",
- NULL);
- if (str) {
- info->copyright = str;
- } else {
- info->copyright = g_strdup ("");
- }
-
- /* Get Copyright */
- str = g_key_file_get_string (plugin_file,
- "Totem Plugin",
- "Website",
- NULL);
- if (str) {
- info->website = str;
- } else {
- info->website = g_strdup ("");
-
- }
-
- /* Get Builtin */
- info->builtin = g_key_file_get_boolean (plugin_file,
- "Totem Plugin",
- "Builtin",
- &err);
- if (err != NULL) {
- info->builtin = FALSE;
- g_error_free (err);
- }
-
- g_key_file_free (plugin_file);
-
- return info;
-
-error:
- g_warning ("Failed to load plugin file: %s", file);
- g_free (info->file);
- g_free (info->location);
- g_free (info->name);
- g_free (info);
- g_key_file_free (plugin_file);
-
- return NULL;
-}
-
-static void
-totem_plugins_engine_load_file (const char *plugin_file)
-{
- TotemPluginInfo *info;
- char *key_name;
- GConfValue *activate_value;
- gboolean activate;
-
- if (g_str_has_suffix (plugin_file, PLUGIN_EXT) == FALSE)
- return;
-
- info = totem_plugins_engine_load (plugin_file);
- if (info == NULL)
- return;
-
- if (g_hash_table_lookup (totem_plugins, info->location)) {
- totem_plugin_info_free (info);
- return;
- }
-
- g_hash_table_insert (totem_plugins, info->location, info);
-
- key_name = g_strdup_printf (GCONF_PREFIX_PLUGIN, info->location);
- gconf_client_add_dir (client, key_name, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
- g_free (key_name);
-
- key_name = g_strdup_printf (GCONF_PLUGIN_ACTIVE, info->location);
- info->active_notification_id = gconf_client_notify_add (client,
- key_name,
- (GConfClientNotifyFunc)totem_plugins_engine_plugin_active_cb,
- info,
- NULL,
- NULL);
- activate_value = gconf_client_get (client, key_name, NULL);
- g_free (key_name);
-
- if (activate_value == NULL) {
- /* Builtin plugins are activated by default; other plugins aren't */
- activate = info->builtin;
- } else {
- activate = gconf_value_get_bool (activate_value);
- gconf_value_free (activate_value);
- }
-
- if (info->builtin == FALSE) {
- /* Builtin plugins are *always* invisible */
- key_name = g_strdup_printf (GCONF_PLUGIN_HIDDEN, info->location);
- info->visible_notification_id = gconf_client_notify_add (client,
- key_name,
- (GConfClientNotifyFunc)totem_plugins_engine_plugin_visible_cb,
- info,
- NULL,
- NULL);
- info->visible = !gconf_client_get_bool (client, key_name, NULL);
- g_free (key_name);
- }
-
- if (activate)
- totem_plugins_engine_activate_plugin (info);
-}
-
-static void
-totem_plugins_engine_load_dir (const gchar *path)
-{
- GDir *dir;
- const char *name;
-
- dir = g_dir_open (path, 0, NULL);
- if (dir == NULL)
- return;
-
- while ((name = g_dir_read_name (dir)) != NULL) {
- char *filename;
-
- filename = g_build_filename (path, name, NULL);
- if (g_file_test (filename, G_FILE_TEST_IS_DIR) != FALSE) {
- totem_plugins_engine_load_dir (filename);
- } else {
- totem_plugins_engine_load_file (filename);
- }
- g_free (filename);
- }
- g_dir_close (dir);
-}
-
-static void
-totem_plugins_engine_load_all (void)
-{
- GList *paths;
-
- paths = totem_get_plugin_paths ();
- while (paths != NULL) {
- totem_plugins_engine_load_dir (paths->data);
- g_free (paths->data);
- paths = g_list_delete_link (paths, paths);
- }
-}
-
+typedef struct _TotemPluginsEnginePrivate{
+ PeasExtensionSet *activatable_extensions;
+ TotemObject *totem;
+ GConfClient *client;
+ guint notification_id;
+ guint garbage_collect_id;
+} _TotemPluginsEnginePrivate;
+
+G_DEFINE_TYPE(TotemPluginsEngine, totem_plugins_engine, PEAS_TYPE_ENGINE)
+
+static void totem_plugins_engine_finalize (GObject *object);
+static void totem_plugins_engine_gconf_cb (GConfClient *gconf_client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ TotemPluginsEngine *engine);
#if 0
-#ifdef ENABLE_PYTHON
+static void totem_plugins_engine_activate_plugin (PeasEngine *engine,
+ PeasPluginInfo *info);
+static void totem_plugins_engine_deactivate_plugin (PeasEngine *engine,
+ PeasPluginInfo *info);
+#endif
static gboolean
garbage_collect_cb (gpointer data)
{
- /* Commented out due to line 387 being commented out. More's commented out in totem-python-module.c. */
- totem_plugins_engine_garbage_collect ();
+ TotemPluginsEngine *engine = (TotemPluginsEngine *) data;
+ peas_engine_garbage_collect (PEAS_ENGINE (engine));
return TRUE;
}
-#endif
-#endif
-
-gboolean
-totem_plugins_engine_init (TotemObject *totem)
-{
- g_return_val_if_fail (totem_plugins == NULL, FALSE);
-
- if (!g_module_supported ())
- {
- g_warning ("Totem is not able to initialize the plugins engine.");
- return FALSE;
- }
- totem_plugins = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)totem_plugin_info_free);
-
- totem_plugins_object = totem;
- g_object_ref (G_OBJECT (totem_plugins_object));
-
- client = gconf_client_get_default ();
-
- totem_plugins_engine_load_all ();
-
-#if 0
-#ifdef ENABLE_PYTHON
- /* Commented out because it's a no-op. A further section is commented out below, and more's commented out
- * in totem-python-module.c. */
- garbage_collect_id = g_timeout_add_seconds_full (G_PRIORITY_LOW, 20, garbage_collect_cb, NULL, NULL);
-#endif
-#endif
-
- return TRUE;
-}
-
-void
-totem_plugins_engine_garbage_collect (void)
-{
-#ifdef ENABLE_PYTHON
- totem_python_garbage_collect ();
-#endif
-}
static void
-totem_plugin_info_free (TotemPluginInfo *info)
+totem_plugins_engine_class_init (TotemPluginsEngineClass *klass)
{
- if (info->active)
- totem_plugins_engine_deactivate_plugin_real (info, totem_plugins_object);
-
- if (info->plugin != NULL) {
- g_object_unref (info->plugin);
-
- /* info->module must not be unref since it is not possible to finalize
- * a type module */
- }
-
- if (info->active_notification_id > 0)
- gconf_client_notify_remove (client, info->active_notification_id);
- if (info->visible_notification_id > 0)
- gconf_client_notify_remove (client, info->visible_notification_id);
-
- g_free (info->file);
- g_free (info->location);
- g_free (info->name);
- g_free (info->desc);
- g_free (info->website);
- g_free (info->copyright);
- g_free (info->icon_name);
-
- if (info->icon_pixbuf)
- g_object_unref (info->icon_pixbuf);
- g_strfreev (info->authors);
-
- g_free (info);
-}
-
-void
-totem_plugins_engine_shutdown (void)
-{
- if (totem_plugins != NULL)
- g_hash_table_destroy (totem_plugins);
- totem_plugins = NULL;
-
- if (totem_plugins_object != NULL)
- g_object_unref (totem_plugins_object);
- totem_plugins_object = NULL;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
-#if 0
-#ifdef ENABLE_PYTHON
- if (garbage_collect_id > 0)
- g_source_remove (garbage_collect_id);
- totem_plugins_engine_garbage_collect ();
-#endif
-#endif
-
- if (client != NULL)
- g_object_unref (client);
- client = NULL;
-
-#ifdef ENABLE_PYTHON
- totem_python_shutdown ();
-#endif
-}
-
-static void
-collate_values_cb (gpointer key, gpointer value, GList **list)
-{
- *list = g_list_prepend (*list, value);
-}
-
-GList *
-totem_plugins_engine_get_plugins_list (void)
-{
- GList *list = NULL;
-
- if (totem_plugins == NULL)
- return NULL;
-
- g_hash_table_foreach (totem_plugins, (GHFunc)collate_values_cb, &list);
- list = g_list_reverse (list);
-
- return list;
+ object_class->finalize = totem_plugins_engine_finalize;
+ g_type_class_add_private (klass, sizeof (TotemPluginsEnginePrivate));
}
static gboolean
-load_plugin_module (TotemPluginInfo *info)
+plugin_is_builtin (PeasPluginInfo *info)
{
- gchar *path;
- gchar *dirname;
-
- g_return_val_if_fail (info != NULL, FALSE);
- g_return_val_if_fail (info->file != NULL, FALSE);
- g_return_val_if_fail (info->location != NULL, FALSE);
- g_return_val_if_fail (info->plugin == NULL, FALSE);
-
- switch (info->lang) {
- case TOTEM_PLUGIN_LOADER_C:
- dirname = g_path_get_dirname (info->file);
- g_return_val_if_fail (dirname != NULL, FALSE);
-
- path = g_module_build_path (dirname, info->location);
-#ifdef TOTEM_RUN_IN_SOURCE_TREE
- if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
- char *temp;
-
- g_free (path);
- temp = g_build_filename (dirname, ".libs", NULL);
-
- path = g_module_build_path (temp, info->location);
- g_free (temp);
- }
-#endif
-
- g_free (dirname);
- g_return_val_if_fail (path != NULL, FALSE);
-
- info->module = G_TYPE_MODULE (totem_module_new (path, info->location));
- g_free (path);
- break;
- case TOTEM_PLUGIN_LOADER_PY:
-#ifdef ENABLE_PYTHON
- info->module = G_TYPE_MODULE (totem_python_module_new (info->file, info->location));
-#else
- g_warning ("Cannot load plugin %s, Python plugin support is disabled", info->location);
-#endif
- break;
- default:
- g_assert_not_reached ();
- }
-
- if (g_type_module_use (info->module) == FALSE) {
- g_warning ("Could not load plugin %s\n", info->location);
-
- g_object_unref (G_OBJECT (info->module));
- info->module = NULL;
+ const GHashTable *keys;
+ const GValue *value;
+ gboolean builtin;
+ keys = peas_plugin_info_get_keys (info);
+ if (keys == NULL)
+ return FALSE;
+ value = g_hash_table_lookup ((GHashTable *) keys, "Builtin");
+ if (value == NULL)
return FALSE;
- }
-
- switch (info->lang) {
- case TOTEM_PLUGIN_LOADER_C:
- info->plugin = TOTEM_PLUGIN (totem_module_new_object (TOTEM_MODULE (info->module)));
- break;
- case TOTEM_PLUGIN_LOADER_PY:
-#ifdef ENABLE_PYTHON
- info->plugin = TOTEM_PLUGIN (totem_python_module_new_object (TOTEM_PYTHON_MODULE (info->module)));
-#endif
- break;
- default:
- g_assert_not_reached ();
- }
-
- return TRUE;
-}
-
-static gboolean
-totem_plugins_engine_activate_plugin_real (TotemPluginInfo *info, TotemObject *totem, GError **error)
-{
- gboolean res = TRUE;
-
- if (info->plugin == NULL)
- res = load_plugin_module (info);
- if (res)
- res = totem_plugin_activate (info->plugin, totem, error);
- else
- g_warning ("Error, impossible to activate plugin '%s'", info->name);
+ builtin = g_value_get_boolean (value);
+ if (builtin != FALSE)
+ peas_plugin_info_set_visible (info, FALSE);
- return res;
+ return builtin;
}
-gboolean
-totem_plugins_engine_activate_plugin (TotemPluginInfo *info)
+static void
+totem_plugins_engine_load_all (TotemPluginsEngine *engine)
{
- char *msg;
- GError *error = NULL;
- gboolean ret;
+ const GList *list, *l;
+ GPtrArray *activate;
- g_return_val_if_fail (info != NULL, FALSE);
+ g_message ("totem_plugins_engine_load_all");
- if (info->active)
- return TRUE;
-
- ret = totem_plugins_engine_activate_plugin_real (info, totem_plugins_object, &error);
- if (info->visible != FALSE || ret != FALSE) {
+ activate = g_ptr_array_new ();
+ list = peas_engine_get_plugin_list (PEAS_ENGINE (engine));
+ for (l = list; l != NULL; l = l->next) {
+ PeasPluginInfo *info = l->data;
char *key_name;
- key_name = g_strdup_printf (GCONF_PLUGIN_ACTIVE, info->location);
- gconf_client_set_bool (client, key_name, ret, NULL);
- g_free (key_name);
- }
-
- info->active = ret;
+ g_message ("checking peas_plugin_info_get_module_name (info) %s", peas_plugin_info_get_module_name (info));
- if (ret != FALSE)
- return TRUE;
+ /* Builtin plugins are activated by default; other plugins aren't */
+ if (plugin_is_builtin (info)) {
+ g_ptr_array_add (activate, (gpointer) peas_plugin_info_get_module_name (info));
+ g_message ("peas_plugin_info_get_module_name (info) %s, to activate", peas_plugin_info_get_module_name (info));
+ continue;
+ }
+ key_name = g_strdup_printf (GCONF_PLUGIN_ACTIVE, peas_plugin_info_get_module_name (info));
+ if (gconf_client_get_bool (engine->priv->client, key_name, NULL) != FALSE) {
+ g_message ("peas_plugin_info_get_module_name (info) %s, to activate", peas_plugin_info_get_module_name (info));
+ g_ptr_array_add (activate, (gpointer) peas_plugin_info_get_module_name (info));
+ }
+ g_free (key_name);
- if (error != NULL) {
- msg = g_strdup_printf (_("Unable to activate plugin %s.\n%s"), info->name, error->message);
- g_error_free (error);
- } else {
- msg = g_strdup_printf (_("Unable to activate plugin %s"), info->name);
+ key_name = g_strdup_printf (GCONF_PLUGIN_HIDDEN, peas_plugin_info_get_module_name (info));
+ if (gconf_client_get_bool (engine->priv->client, key_name, NULL) != FALSE)
+ peas_plugin_info_set_visible (info, FALSE);
+ g_free (key_name);
}
- totem_interface_error (_("Plugin Error"), msg, NULL);
- g_free (msg);
+ g_ptr_array_add (activate, NULL);
- return FALSE;
+ peas_engine_set_active_plugins (PEAS_ENGINE (engine), (const char **) activate->pdata);
+ g_ptr_array_free (activate, TRUE);
}
static void
-totem_plugins_engine_deactivate_plugin_real (TotemPluginInfo *info, TotemObject *totem)
+totem_plugins_engine_monitor (TotemPluginsEngine *engine)
{
- totem_plugin_deactivate (info->plugin, totem_plugins_object);
+ engine->priv->notification_id = gconf_client_notify_add (engine->priv->client,
+ GCONF_PREFIX_PLUGINS,
+ (GConfClientNotifyFunc)totem_plugins_engine_gconf_cb,
+ engine,
+ NULL,
+ NULL);
}
-gboolean
-totem_plugins_engine_deactivate_plugin (TotemPluginInfo *info)
+static void
+on_activatable_extension_added (PeasExtensionSet *set,
+ PeasPluginInfo *info,
+ PeasExtension *exten,
+ TotemPluginsEngine *engine)
{
- char *key_name;
-
- g_return_val_if_fail (info != NULL, FALSE);
-
- if (!info->active)
- return TRUE;
-
- totem_plugins_engine_deactivate_plugin_real (info, totem_plugins_object);
-
- /* Update plugin state */
- info->active = FALSE;
-
- key_name = g_strdup_printf (GCONF_PLUGIN_ACTIVE, info->location);
- gconf_client_set_bool (client, key_name, FALSE, NULL);
- g_free (key_name);
-
- return TRUE;
+ g_message ("on_activatable_extension_added");
+ peas_extension_call (exten, "activate", engine->priv->totem);
}
-gboolean
-totem_plugins_engine_plugin_is_active (TotemPluginInfo *info)
+static void
+on_activatable_extension_removed (PeasExtensionSet *set,
+ PeasPluginInfo *info,
+ PeasExtension *exten,
+ TotemPluginsEngine *engine)
{
- g_return_val_if_fail (info != NULL, FALSE);
-
- return info->active;
+ g_message ("on_activatable_extension_removed");
+ peas_extension_call (exten, "deactivate", engine->priv->totem);
}
-gboolean
-totem_plugins_engine_plugin_is_visible (TotemPluginInfo *info)
+TotemPluginsEngine *
+totem_plugins_engine_get_default (TotemObject *totem)
{
- g_return_val_if_fail (info != NULL, FALSE);
+ static TotemPluginsEngine *engine = NULL;
+ char **paths;
+ GPtrArray *array;
+ guint i;
- return info->visible;
-}
+ if (G_LIKELY (engine != NULL))
+ return engine;
-gboolean
-totem_plugins_engine_plugin_is_configurable (TotemPluginInfo *info)
-{
- g_return_val_if_fail (info != NULL, FALSE);
+ g_return_val_if_fail (totem != NULL, NULL);
- if ((info->plugin == NULL) || !info->active)
- return FALSE;
+ g_irepository_require (g_irepository_get_default (), "Peas", "1.0", 0, NULL);
- return totem_plugin_is_configurable (info->plugin);
-}
+ paths = totem_get_plugin_paths ();
-void
-totem_plugins_engine_configure_plugin (TotemPluginInfo *info,
- GtkWindow *parent)
-{
- GtkWidget *conf_dlg;
+ /* Totem uses the libdir even for noarch data */
+ array = g_ptr_array_new ();
+ for (i = 0; paths[i] != NULL; i++) {
+ g_ptr_array_add (array, paths[i]);
+ g_ptr_array_add (array, paths[i]);
+ }
+ g_ptr_array_add (array, NULL);
- GtkWindowGroup *wg;
+ engine = TOTEM_PLUGINS_ENGINE (g_object_new (TOTEM_TYPE_PLUGINS_ENGINE,
+ "app-name", "Totem",
+ "search-paths", array->pdata,
+ "base-module-dir", TOTEM_PLUGIN_DIR,
+ NULL));
+ g_strfreev (paths);
+ g_ptr_array_free (array, TRUE);
- g_return_if_fail (info != NULL);
+ g_object_add_weak_pointer (G_OBJECT (engine),
+ (gpointer) &engine);
- conf_dlg = totem_plugin_create_configure_dialog (info->plugin);
- g_return_if_fail (conf_dlg != NULL);
- gtk_window_set_transient_for (GTK_WINDOW (conf_dlg),
- parent);
+ engine->priv->totem = g_object_ref (totem);
- wg = gtk_window_get_group (parent);
- if (wg == NULL)
- {
- wg = gtk_window_group_new ();
- gtk_window_group_add_window (wg, parent);
- }
+ engine->priv->activatable_extensions = peas_extension_set_new (PEAS_ENGINE (engine),
+ PEAS_TYPE_ACTIVATABLE);
+ totem_plugins_engine_load_all (engine);
+ totem_plugins_engine_monitor (engine);
- gtk_window_group_add_window (wg,
- GTK_WINDOW (conf_dlg));
+ peas_extension_set_call (engine->priv->activatable_extensions, "activate", engine->priv->totem);
- gtk_window_set_modal (GTK_WINDOW (conf_dlg), TRUE);
- gtk_widget_show (conf_dlg);
-}
+ g_signal_connect (engine->priv->activatable_extensions, "extension-added",
+ G_CALLBACK (on_activatable_extension_added), engine);
+ g_signal_connect (engine->priv->activatable_extensions, "extension-removed",
+ G_CALLBACK (on_activatable_extension_removed), engine);
-static void
-totem_plugins_engine_plugin_active_cb (GConfClient *gconf_client,
- guint cnxn_id,
- GConfEntry *entry,
- TotemPluginInfo *info)
-{
- if (gconf_value_get_bool (entry->value)) {
- totem_plugins_engine_activate_plugin (info);
- } else {
- totem_plugins_engine_deactivate_plugin (info);
- }
+ return engine;
}
static void
-totem_plugins_engine_plugin_visible_cb (GConfClient *gconf_client,
- guint cnxn_id,
- GConfEntry *entry,
- TotemPluginInfo *info)
-{
- info->visible = !gconf_value_get_bool (entry->value);
-}
-
-const gchar *
-totem_plugins_engine_get_plugin_name (TotemPluginInfo *info)
+totem_plugins_engine_init (TotemPluginsEngine *engine)
{
- g_return_val_if_fail (info != NULL, NULL);
+ engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine,
+ TOTEM_TYPE_PLUGINS_ENGINE,
+ TotemPluginsEnginePrivate);
+ engine->priv->client = gconf_client_get_default ();
+ gconf_client_add_dir (engine->priv->client, GCONF_PREFIX_PLUGINS, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
- return info->name;
+ /* Commented out because it's a no-op. A further section is commented out below, and more's commented out
+ * in totem-python-module.c. */
+ engine->priv->garbage_collect_id = g_timeout_add_seconds_full (G_PRIORITY_LOW, 20, garbage_collect_cb, engine, NULL);
}
-const gchar *
-totem_plugins_engine_get_plugin_description (TotemPluginInfo *info)
+static void
+totem_plugins_engine_finalize (GObject *object)
{
- g_return_val_if_fail (info != NULL, NULL);
+ TotemPluginsEngine *engine = TOTEM_PLUGINS_ENGINE (object);
- return info->desc;
-}
-
-const gchar **
-totem_plugins_engine_get_plugin_authors (TotemPluginInfo *info)
-{
- g_return_val_if_fail (info != NULL, (const gchar **)NULL);
+ if (engine->priv->totem) {
+ peas_extension_set_call (engine->priv->activatable_extensions,
+ "deactivate", engine->priv->totem);
- return (const gchar **)info->authors;
-}
+ g_object_unref (engine->priv->totem);
+ engine->priv->totem = NULL;
+ }
-const gchar *
-totem_plugins_engine_get_plugin_website (TotemPluginInfo *info)
-{
- g_return_val_if_fail (info != NULL, NULL);
+ if (engine->priv->garbage_collect_id > 0)
+ g_source_remove (engine->priv->garbage_collect_id);
+ engine->priv->garbage_collect_id = 0;
+ peas_engine_garbage_collect (PEAS_ENGINE (engine));
- return info->website;
-}
+ if (engine->priv->notification_id > 0)
+ gconf_client_notify_remove (engine->priv->client,
+ engine->priv->notification_id);
+ engine->priv->notification_id = 0;
-const gchar *
-totem_plugins_engine_get_plugin_copyright (TotemPluginInfo *info)
-{
- g_return_val_if_fail (info != NULL, NULL);
+ if (engine->priv->client != NULL)
+ g_object_unref (engine->priv->client);
+ engine->priv->client = NULL;
- return info->copyright;
+ G_OBJECT_CLASS (totem_plugins_engine_parent_class)->finalize (object);
}
-GdkPixbuf *
-totem_plugins_engine_get_plugin_icon (TotemPluginInfo *info)
+static void
+totem_plugins_engine_gconf_cb (GConfClient *gconf_client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ TotemPluginsEngine *engine)
{
- if (info->icon_name == NULL)
- return NULL;
+ char *plugin_name;
+ char *action_name;
+ PeasPluginInfo *info;
- if (info->icon_pixbuf == NULL) {
- char *filename = NULL;
- char *dirname;
+ plugin_name = g_path_get_dirname (gconf_entry_get_key (entry));
+ info = peas_engine_get_plugin_info (PEAS_ENGINE (engine), plugin_name);
+ g_free (plugin_name);
- dirname = g_path_get_dirname (info->file);
- filename = g_build_filename (dirname, info->icon_name, NULL);
- g_free (dirname);
+ if (info == NULL)
+ return;
+
+ action_name = g_path_get_basename (gconf_entry_get_key (entry));
+ //FIXME do some checks here
- info->icon_pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
- g_free (filename);
+ if (g_str_equal (action_name, "active") != FALSE) {
+ if (gconf_value_get_bool (entry->value)) {
+ peas_engine_activate_plugin (PEAS_ENGINE (engine), info);
+ } else {
+ peas_engine_deactivate_plugin (PEAS_ENGINE (engine), info);
+ }
+ } else if (g_str_equal (action_name, "hidden") != FALSE) {
+ peas_plugin_info_set_visible (info, !gconf_value_get_bool (entry->value));
}
- return info->icon_pixbuf;
+ g_free (action_name);
}
+
diff --git a/src/plugins/totem-plugins-engine.h b/src/plugins/totem-plugins-engine.h
index ce376dbbf..2bdc4954b 100644
--- a/src/plugins/totem-plugins-engine.h
+++ b/src/plugins/totem-plugins-engine.h
@@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Plugin engine for Totem, heavily based on the code from Rhythmbox,
- * which is based heavily on the code from gedit.
+ * which is based heavily on the code from totem.
*
* Copyright (C) 2002-2005 Paolo Maggi
* 2006 James Livingston <jrl@ids.org.au>
@@ -31,35 +31,37 @@
#define __TOTEM_PLUGINS_ENGINE_H__
#include <glib.h>
+#include <libpeas/peas-engine.h>
#include <totem.h>
-typedef struct _TotemPluginInfo TotemPluginInfo;
+G_BEGIN_DECLS
-gboolean totem_plugins_engine_init (TotemObject *totem);
-void totem_plugins_engine_shutdown (void);
+#define TOTEM_TYPE_PLUGINS_ENGINE (totem_plugins_engine_get_type ())
+#define TOTEM_PLUGINS_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TOTEM_TYPE_PLUGINS_ENGINE, TotemPluginsEngine))
+#define TOTEM_PLUGINS_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TOTEM_TYPE_PLUGINS_ENGINE, TotemPluginsEngineClass))
+#define TOTEM_IS_PLUGINS_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TOTEM_TYPE_PLUGINS_ENGINE))
+#define TOTEM_IS_PLUGINS_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TOTEM_TYPE_PLUGINS_ENGINE))
+#define TOTEM_PLUGINS_ENGINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TOTEM_TYPE_PLUGINS_ENGINE, TotemPluginsEngineClass))
-void totem_plugins_engine_garbage_collect (void);
+typedef struct _TotemPluginsEngine TotemPluginsEngine;
+typedef struct _TotemPluginsEnginePrivate TotemPluginsEnginePrivate;
+typedef struct _TotemPluginsEngineClass TotemPluginsEngineClass;
-GList* totem_plugins_engine_get_plugins_list (void);
+struct _TotemPluginsEngine
+{
+ PeasEngine parent;
+ TotemPluginsEnginePrivate *priv;
+};
-gboolean totem_plugins_engine_activate_plugin (TotemPluginInfo *info);
-gboolean totem_plugins_engine_deactivate_plugin (TotemPluginInfo *info);
-gboolean totem_plugins_engine_plugin_is_active (TotemPluginInfo *info);
-gboolean totem_plugins_engine_plugin_is_visible (TotemPluginInfo *info);
+struct _TotemPluginsEngineClass
+{
+ PeasEngineClass parent_class;
+};
-gboolean totem_plugins_engine_plugin_is_configurable
- (TotemPluginInfo *info);
-void totem_plugins_engine_configure_plugin (TotemPluginInfo *info,
- GtkWindow *parent);
+GType totem_plugins_engine_get_type (void) G_GNUC_CONST;
+TotemPluginsEngine *totem_plugins_engine_get_default (TotemObject *totem);
-const gchar* totem_plugins_engine_get_plugin_name (TotemPluginInfo *info);
-const gchar* totem_plugins_engine_get_plugin_description
- (TotemPluginInfo *info);
-
-const gchar** totem_plugins_engine_get_plugin_authors (TotemPluginInfo *info);
-const gchar* totem_plugins_engine_get_plugin_website (TotemPluginInfo *info);
-const gchar* totem_plugins_engine_get_plugin_copyright
- (TotemPluginInfo *info);
-GdkPixbuf * totem_plugins_engine_get_plugin_icon (TotemPluginInfo *info);
+G_END_DECLS
#endif /* __TOTEM_PLUGINS_ENGINE_H__ */
+
diff --git a/src/plugins/totem-python-module.c b/src/plugins/totem-python-module.c
deleted file mode 100644
index 7eee97cde..000000000
--- a/src/plugins/totem-python-module.c
+++ /dev/null
@@ -1,566 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Heavily based on code from Rhythmbox and Gedit.
- *
- * Copyright (C) 2005 Raphael Slinckx
- * Copyright (C) 2007 Philip Withnall
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Saturday 19th May 2007: Philip Withnall: Add exception clause.
- * See license_change file for details.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <Python.h>
-#include <pygobject.h>
-#include <pygtk/pygtk.h>
-
-#include <signal.h>
-
-#include <gmodule.h>
-
-#include "totem-plugin.h"
-#include "totem-python-module.h"
-#include "totem-python-plugin.h"
-
-#if PY_VERSION_HEX < 0x02050000
-typedef int Py_ssize_t;
-#define PY_SSIZE_T_MAX INT_MAX
-#define PY_SSIZE_T_MIN INT_MIN
-#endif
-
-#define TOTEM_PYTHON_MODULE_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
- TOTEM_TYPE_PYTHON_MODULE, \
- TotemPythonModulePrivate))
-
-typedef struct
-{
- gchar *module;
- gchar *path;
- GType type;
-} TotemPythonModulePrivate;
-
-enum
-{
- PROP_0,
- PROP_PATH,
- PROP_MODULE
-};
-
-/* indicates whether all initializations in
- * totem_python_module_init_python were successful */
-gboolean python_initialized = FALSE;
-
-#ifndef PYGOBJECT_CAN_MARSHAL_GVALUE
-static PyObject *
-pyg_value_g_value_as_pyobject (const GValue *value)
-{
- return pyg_value_as_pyobject((GValue *)g_value_get_boxed(value), FALSE);
-}
-
-static int
-pyg_value_g_value_from_pyobject (GValue *value, PyObject *obj)
-{
- GType type;
- GValue obj_value = { 0, };
-
- type = pyg_type_from_object((PyObject *) obj->ob_type);
- if (! type) {
- PyErr_Clear();
- return -1;
- }
- g_value_init(&obj_value, type);
- if (pyg_value_from_pyobject(&obj_value, obj) == -1) {
- g_value_unset(&obj_value);
- return -1;
- }
- g_value_set_boxed(value, &obj_value);
- g_value_unset(&obj_value);
- return 0;
-}
-#endif /* PYGOBJECT_CAN_MARSHAL_GVALUE */
-
-/* Exported by Totem Python module */
-void pytotem_register_classes (PyObject *d);
-void pytotem_add_constants (PyObject *module, const gchar *strip_prefix);
-extern PyMethodDef pytotem_functions[];
-
-/* We retreive this to check for correct class hierarchy */
-static PyTypeObject *PyTotemPlugin_Type;
-
-G_DEFINE_TYPE (TotemPythonModule, totem_python_module, G_TYPE_TYPE_MODULE);
-
-static void
-totem_python_module_init_python (void)
-{
- PyObject *pygtk, *mdict, *require;
- PyObject *totem, *gtk, *pygtk_version, *pygtk_required_version;
- PyObject *gettext, *install, *gettext_args;
- PyObject *sys_path;
- struct sigaction old_sigint;
- gint res;
- char *argv[] = { "totem", NULL };
- GList *paths;
-
- if (Py_IsInitialized ()) {
- g_warning ("Python should only be initialized once, since it's in class_init");
- g_return_if_reached ();
- }
-
- /* Hack to make python not overwrite SIGINT: this is needed to avoid
- * the crash reported on gedit bug #326191 */
-
- /* Save old handler */
- res = sigaction (SIGINT, NULL, &old_sigint);
- if (res != 0) {
- g_warning ("Error initializing Python interpreter: cannot get "
- "handler to SIGINT signal (%s)",
- strerror (errno));
-
- return;
- }
-
- /* Python initialization */
- Py_Initialize ();
-
- /* Restore old handler */
- res = sigaction (SIGINT, &old_sigint, NULL);
- if (res != 0) {
- g_warning ("Error initializing Python interpreter: cannot restore "
- "handler to SIGINT signal (%s)",
- strerror (errno));
- return;
- }
-
- PySys_SetArgv (1, argv);
-
- /* pygtk.require("2.0") */
- pygtk = PyImport_ImportModule ("pygtk");
- if (pygtk == NULL) {
- g_warning ("Could not import pygtk, check your installation");
- PyErr_Print();
- return;
- }
-
- mdict = PyModule_GetDict (pygtk);
- require = PyDict_GetItemString (mdict, "require");
- PyObject_CallObject (require, Py_BuildValue ("(S)", PyString_FromString ("2.0")));
- if (PyErr_Occurred ()) {
- g_warning ("Could not get required pygtk version, check your installation");
- PyErr_Print();
- return;
- }
-
- /* import gobject */
- init_pygobject ();
-
- /* disable pyg* log hooks, since ours is more interesting */
-#ifdef pyg_disable_warning_redirections
- pyg_disable_warning_redirections ();
-#endif
-#ifndef PYGOBJECT_CAN_MARSHAL_GVALUE
- pyg_register_gtype_custom (G_TYPE_VALUE, pyg_value_g_value_as_pyobject, pyg_value_g_value_from_pyobject);
-#endif
-
- /* import gtk */
- init_pygtk ();
-
- pyg_enable_threads ();
-
- gtk = PyImport_ImportModule ("gtk");
- if (gtk == NULL) {
- g_warning ("Could not import gtk");
- PyErr_Print();
- return;
- }
-
- mdict = PyModule_GetDict (gtk);
- pygtk_version = PyDict_GetItemString (mdict, "pygtk_version");
- pygtk_required_version = Py_BuildValue ("(iii)", 2, 12, 0);
- if (PyObject_Compare (pygtk_version, pygtk_required_version) == -1) {
- g_warning("PyGTK %s required, but %s found, check your installation.",
- PyString_AsString (PyObject_Repr (pygtk_required_version)),
- PyString_AsString (PyObject_Repr (pygtk_version)));
- Py_DECREF (pygtk_required_version);
- return;
- }
- Py_DECREF (pygtk_required_version);
-
- /* import totem */
- paths = totem_get_plugin_paths ();
- sys_path = PySys_GetObject ("path");
- while (paths != NULL) {
- PyObject *path;
-
- path = PyString_FromString (paths->data);
- if (PySequence_Contains (sys_path, path) == 0) {
- PyList_Insert (sys_path, 0, path);
- }
- Py_DECREF (path);
- g_free (paths->data);
- paths = g_list_delete_link (paths, paths);
- }
-
- totem = PyImport_ImportModule ("totem");
-
- if (totem == NULL) {
- g_warning ("Could not import Python module 'totem', check your installation");
- PyErr_Print ();
- return;
- }
-
- /* add pytotem_functions */
- for (res = 0; pytotem_functions[res].ml_name != NULL; res++) {
- PyObject *func;
-
- func = PyCFunction_New (&pytotem_functions[res], totem);
- if (func == NULL) {
- g_warning ("unable object for function '%s' create", pytotem_functions[res].ml_name);
- PyErr_Print ();
- return;
- }
- if (PyModule_AddObject (totem, pytotem_functions[res].ml_name, func) < 0) {
- g_warning ("unable to insert function '%s' in 'totem' module", pytotem_functions[res].ml_name);
- PyErr_Print ();
- return;
- }
- }
- mdict = PyModule_GetDict (totem);
-
- pytotem_register_classes (mdict);
- pytotem_add_constants (totem, "TOTEM_");
-
- /* Retreive the Python type for totem.Plugin */
- PyTotemPlugin_Type = (PyTypeObject *) PyDict_GetItemString (mdict, "Plugin");
- if (PyTotemPlugin_Type == NULL) {
- PyErr_Print ();
- return;
- }
-
- /* i18n support */
- gettext = PyImport_ImportModule ("gettext");
- if (gettext == NULL) {
- g_warning ("Could not import gettext");
- PyErr_Print();
- return;
- }
-
- mdict = PyModule_GetDict (gettext);
- install = PyDict_GetItemString (mdict, "install");
- gettext_args = Py_BuildValue ("ss", GETTEXT_PACKAGE, GNOMELOCALEDIR);
- PyObject_CallObject (install, gettext_args);
- Py_DECREF (gettext_args);
-
- /* ideally totem should clean up the python stuff again at some point,
- * for which we'd need to save the result of SaveThread so we can then
- * restore the state in a class_finalize or so, but since totem doesn't
- * do any clean-up at this point, we'll just skip this as well */
- PyEval_SaveThread();
-
- /* Python and the supporting libraries were initialised
- * successfully */
- python_initialized = TRUE;
-}
-
-static gboolean
-totem_python_module_load (GTypeModule *gmodule)
-{
- TotemPythonModulePrivate *priv = TOTEM_PYTHON_MODULE_GET_PRIVATE (gmodule);
- PyGILState_STATE state;
- PyObject *main_module, *main_locals, *locals, *key, *value;
- PyObject *module, *fromlist;
- Py_ssize_t pos = 0;
- gboolean res = FALSE;
-
- g_return_val_if_fail (Py_IsInitialized (), FALSE);
- if (python_initialized == FALSE)
- return FALSE;
-
- state = pyg_gil_state_ensure();
-
- main_module = PyImport_AddModule ("__main__");
- if (main_module == NULL)
- {
- g_warning ("Could not get __main__.");
- goto done;
- }
-
- /* If we have a special path, we register it */
- if (priv->path != NULL)
- {
- PyObject *sys_path = PySys_GetObject ("path");
- PyObject *path = PyString_FromString (priv->path);
-
- if (PySequence_Contains(sys_path, path) == 0)
- PyList_Insert (sys_path, 0, path);
-
- Py_DECREF(path);
- }
-
- main_locals = PyModule_GetDict (main_module);
- /* we need a fromlist to be able to import modules with a '.' in the
- name. */
- fromlist = PyTuple_New(0);
- module = PyImport_ImportModuleEx (priv->module, main_locals,
- main_locals, fromlist);
- Py_DECREF (fromlist);
- if (!module) {
- PyErr_Print ();
- goto done;
- }
-
- locals = PyModule_GetDict (module);
- while (PyDict_Next (locals, &pos, &key, &value))
- {
- if (!PyType_Check(value))
- continue;
-
- if (PyObject_IsSubclass (value, (PyObject*) PyTotemPlugin_Type))
- {
- priv->type = totem_python_object_get_type (gmodule, value);
- res = TRUE;
- goto done;
- }
- }
-
- g_warning ("Failed to find any totem.Plugin-derived classes in Python plugin");
-
-done:
-
- pyg_gil_state_release (state);
- return res;
-}
-
-static void
-totem_python_module_unload (GTypeModule *module)
-{
- TotemPythonModulePrivate *priv = TOTEM_PYTHON_MODULE_GET_PRIVATE (module);
- g_debug ("Unloading Python module");
-
- priv->type = 0;
-}
-
-GObject *
-totem_python_module_new_object (TotemPythonModule *module)
-{
- TotemPythonModulePrivate *priv = TOTEM_PYTHON_MODULE_GET_PRIVATE (module);
- TotemPythonObject *object;
-
- if (priv->type == 0)
- return NULL;
-
- g_debug ("Creating object of type %s", g_type_name (priv->type));
- object = (TotemPythonObject*) (g_object_new (priv->type,
- "name", priv->module,
- NULL));
- if (object->instance == NULL) {
- g_warning ("Could not instantiate Python object");
- return NULL;
- }
-
- /* FIXME, HACK: this is a hack because the gobject object->instance references
- * isn't the same gobject as we think it is. Which Causes Issues.
- *
- * This still has issues, notably that it isn't safe to call any totem.Plugin methods
- * from python before we get here.
- *
- * The solution is to not have weird proxy objects.
- */
- g_object_set (((PyGObject*)(object->instance))->obj, "name", priv->module, NULL);
-
- return G_OBJECT (object);
-}
-
-static void
-totem_python_module_init (TotemPythonModule *module)
-{
- g_debug ("Init of Python module");
-}
-
-static void
-totem_python_module_finalize (GObject *object)
-{
- TotemPythonModulePrivate *priv = TOTEM_PYTHON_MODULE_GET_PRIVATE (object);
-
- if (priv && priv->type) {
- g_debug ("Finalizing Python module %s", g_type_name (priv->type));
-
- g_free (priv->module);
- g_free (priv->path);
- }
-
- G_OBJECT_CLASS (totem_python_module_parent_class)->finalize (object);
-}
-
-static void
-totem_python_module_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- /* no readable properties */
- g_return_if_reached ();
-}
-
-static void
-totem_python_module_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- TotemPythonModule *mod = TOTEM_PYTHON_MODULE (object);
-
- switch (prop_id)
- {
- case PROP_MODULE:
- TOTEM_PYTHON_MODULE_GET_PRIVATE (mod)->module = g_value_dup_string (value);
- break;
- case PROP_PATH:
- TOTEM_PYTHON_MODULE_GET_PRIVATE (mod)->path = g_value_dup_string (value);
- break;
- default:
- g_return_if_reached ();
- }
-}
-
-static void
-totem_python_module_class_init (TotemPythonModuleClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
-
- object_class->finalize = totem_python_module_finalize;
- object_class->get_property = totem_python_module_get_property;
- object_class->set_property = totem_python_module_set_property;
-
- g_object_class_install_property
- (object_class,
- PROP_MODULE,
- g_param_spec_string ("module",
- "Module Name",
- "The Python module to load for this plugin",
- NULL,
- G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class,
- PROP_PATH,
- g_param_spec_string ("path",
- "Path",
- "The Python path to use when loading this module",
- NULL,
- G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
-
- g_type_class_add_private (object_class, sizeof (TotemPythonModulePrivate));
-
- module_class->load = totem_python_module_load;
- module_class->unload = totem_python_module_unload;
-
- /* Init Python subsystem, this should happen only once
- * in the process lifetime, and doing it here is OK since
- * class_init is called once */
- totem_python_module_init_python ();
-}
-
-TotemPythonModule *
-totem_python_module_new (const gchar *path,
- const gchar *module)
-{
- TotemPythonModule *result;
- gchar *dir;
-
- if (module == NULL || module[0] == '\0')
- return NULL;
-
- dir = g_path_get_dirname (path);
- result = g_object_new (TOTEM_TYPE_PYTHON_MODULE,
- "module", module,
- "path", dir,
- NULL);
- g_free (dir);
-
- g_type_module_set_name (G_TYPE_MODULE (result), module);
-
- return result;
-}
-
-/* --- these are not module methods, they are here out of convenience --- */
-
-#if 0
-static gint idle_garbage_collect_id = 0;
-
-static gboolean
-run_gc (gpointer data)
-{
- gboolean ret = (PyGC_Collect () != 0);
-
- if (!ret)
- idle_garbage_collect_id = 0;
-
- return ret;
-}
-#endif
-
-void
-totem_python_garbage_collect (void)
-{
-#if 0
- if (Py_IsInitialized() && idle_garbage_collect_id == 0) {
- idle_garbage_collect_id = g_idle_add (run_gc, NULL);
- }
-#endif
-}
-
-#if 0
-static gboolean
-finalise_collect_cb (gpointer data)
-{
- while (PyGC_Collect ())
- ;
-
- /* Useful if Python is refusing to give up its shell reference for some reason.
- PyRun_SimpleString ("import gc, gobject\nfor o in gc.get_objects():\n\tif isinstance(o, gobject.GObject):\n\t\tprint o, gc.get_referrers(o)");
- */
-
- return TRUE;
-}
-#endif
-
-void
-totem_python_shutdown (void)
-{
-#if 0
- if (Py_IsInitialized ()) {
- if (idle_garbage_collect_id != 0) {
- g_source_remove (idle_garbage_collect_id);
- idle_garbage_collect_id = 0;
- }
-
- while (run_gc (NULL))
- /* loop */;
-
- /* This helps to force Python to give up its shell reference */
- g_idle_add (finalise_collect_cb, NULL);
-
- /* Disable for now, due to bug 334188
- Py_Finalize ();*/
- }
-#endif
-}
diff --git a/src/plugins/totem-python-module.h b/src/plugins/totem-python-module.h
deleted file mode 100644
index 31a90130c..000000000
--- a/src/plugins/totem-python-module.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Heavily based on code from Rhythmbox and Gedit.
- *
- * Copyright (C) 2005 Raphael Slinckx
- * Copyright (C) 2007 Philip Withnall
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Saturday 19th May 2007: Philip Withnall: Add exception clause.
- * See license_change file for details.
- */
-
-#ifndef TOTEM_PYTHON_MODULE_H
-#define TOTEM_PYTHON_MODULE_H
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define TOTEM_TYPE_PYTHON_MODULE (totem_python_module_get_type ())
-#define TOTEM_PYTHON_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TOTEM_TYPE_PYTHON_MODULE, TotemPythonModule))
-#define TOTEM_PYTHON_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TOTEM_TYPE_PYTHON_MODULE, TotemPythonModuleClass))
-#define TOTEM_IS_PYTHON_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TOTEM_TYPE_PYTHON_MODULE))
-#define TOTEM_IS_PYTHON_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TOTEM_TYPE_PYTHON_MODULE))
-#define TOTEM_PYTHON_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TOTEM_TYPE_PYTHON_MODULE, TotemPythonModuleClass))
-
-typedef struct
-{
- GTypeModuleClass parent_class;
-} TotemPythonModuleClass;
-
-typedef struct
-{
- GTypeModule parent_instance;
-} TotemPythonModule;
-
-GType totem_python_module_get_type (void);
-TotemPythonModule *totem_python_module_new (const gchar* path, const gchar *module);
-GObject *totem_python_module_new_object (TotemPythonModule *module);
-
-/* --- python utils --- */
-void totem_python_garbage_collect (void);
-void totem_python_shutdown (void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/plugins/totem-python-plugin.c b/src/plugins/totem-python-plugin.c
deleted file mode 100644
index 5457e2924..000000000
--- a/src/plugins/totem-python-plugin.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Heavily based on code from Rhythmbox and Gedit.
- *
- * Copyright (C) 2005 Raphael Slinckx
- * Copyright (C) 2007 Philip Withnall
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Saturday 19th May 2007: Philip Withnall: Add exception clause.
- * See license_change file for details.
- */
-
-#include <config.h>
-
-#include "totem-python-plugin.h"
-#include "totem-plugin.h"
-
-#include <pygobject.h>
-#include <string.h>
-
-static GObjectClass *parent_class;
-
-static PyObject *
-call_python_method (TotemPythonObject *object,
- TotemObject *totem,
- gchar *method)
-{
- PyGILState_STATE state;
- PyObject *py_ret = NULL;
-
- state = pyg_gil_state_ensure();
-
- g_return_val_if_fail (PyObject_HasAttrString (object->instance, method), NULL);
-
- if (totem == NULL) {
- py_ret = PyObject_CallMethod (object->instance,
- method,
- NULL);
- } else {
- py_ret = PyObject_CallMethod (object->instance,
- method,
- "(N)",
- pygobject_new (G_OBJECT (totem)));
- }
-
- if (!py_ret)
- PyErr_Print ();
-
- pyg_gil_state_release (state);
-
- return py_ret;
-}
-
-static gboolean
-check_py_object_is_gtk_widget (PyObject *py_obj)
-{
- static PyTypeObject *_PyGtkWidget_Type = NULL;
- PyGILState_STATE state;
- gboolean res = FALSE;
-
- state = pyg_gil_state_ensure();
-
- if (_PyGtkWidget_Type == NULL) {
- PyObject *module;
-
- if ((module = PyImport_ImportModule ("gtk"))) {
- PyObject *moddict = PyModule_GetDict (module);
- _PyGtkWidget_Type = (PyTypeObject *) PyDict_GetItemString (moddict, "Widget");
- }
-
- if (_PyGtkWidget_Type == NULL) {
- PyErr_SetString(PyExc_TypeError, "could not find python gtk widget type");
- PyErr_Print();
- res = FALSE;
- goto done;
- }
- }
-
- res = PyObject_TypeCheck (py_obj, _PyGtkWidget_Type) ? TRUE : FALSE;
-
-done:
- pyg_gil_state_release (state);
- return res;
-}
-
-static void
-impl_deactivate (TotemPlugin *plugin,
- TotemObject *totem)
-{
- PyGILState_STATE state = pyg_gil_state_ensure ();
- TotemPythonObject *object = (TotemPythonObject *)plugin;
-
- if (PyObject_HasAttrString (object->instance, "deactivate")) {
- PyObject *py_ret = call_python_method (object, totem, "deactivate");
-
- if (py_ret) {
- Py_XDECREF (py_ret);
- }
- } else {
- TOTEM_PLUGIN_CLASS (parent_class)->deactivate (plugin, totem);
- }
-
- pyg_gil_state_release (state);
-}
-
-static gboolean
-impl_activate (TotemPlugin *plugin,
- TotemObject *totem,
- GError **error)
-{
- PyGILState_STATE state = pyg_gil_state_ensure ();
- TotemPythonObject *object = (TotemPythonObject *)plugin;
-
- if (PyObject_HasAttrString (object->instance, "activate")) {
- PyObject *py_ret = call_python_method (object, totem, "activate");
-
- if (py_ret) {
- Py_XDECREF (py_ret);
- }
- } else {
- TOTEM_PLUGIN_CLASS (parent_class)->activate (plugin, totem, error);
- }
-
- pyg_gil_state_release (state);
-
- return TRUE;
-}
-
-static GtkWidget *
-impl_create_configure_dialog (TotemPlugin *plugin)
-{
- PyGILState_STATE state = pyg_gil_state_ensure ();
- TotemPythonObject *object = (TotemPythonObject *)plugin;
- GtkWidget *ret = NULL;
-
- if (PyObject_HasAttrString (object->instance, "create_configure_dialog")) {
- PyObject *py_ret = call_python_method (object, NULL, "create_configure_dialog");
-
- if (py_ret) {
- if (check_py_object_is_gtk_widget (py_ret)) {
- ret = GTK_WIDGET (pygobject_get (py_ret));
- g_object_ref (ret);
- } else {
- PyErr_SetString(PyExc_TypeError, "return value for create_configure_dialog is not a GtkWidget");
- PyErr_Print();
- }
-
- Py_DECREF (py_ret);
- }
- } else {
- ret = TOTEM_PLUGIN_CLASS (parent_class)->create_configure_dialog (plugin);
- }
-
- pyg_gil_state_release (state);
- return ret;
-}
-
-static gboolean
-impl_is_configurable (TotemPlugin *plugin)
-{
- PyGILState_STATE state = pyg_gil_state_ensure ();
- TotemPythonObject *object = (TotemPythonObject *) plugin;
- PyObject *dict = object->instance->ob_type->tp_dict;
- gboolean result;
-
- if (dict == NULL)
- result = FALSE;
- else if (!PyDict_Check(dict))
- result = FALSE;
- else
- result = PyDict_GetItemString(dict, "create_configure_dialog") != NULL;
-
- pyg_gil_state_release (state);
-
- return result;
-}
-
-static void
-totem_python_object_init (TotemPythonObject *object)
-{
- TotemPythonObjectClass *class;
- PyGILState_STATE state;
-
- state = pyg_gil_state_ensure();
-
- g_debug ("Creating Python plugin instance");
-
- class = (TotemPythonObjectClass*) (((GTypeInstance*) object)->g_class);
-
- object->instance = PyObject_CallObject (class->type, NULL);
- if (object->instance == NULL)
- PyErr_Print();
-
- pyg_gil_state_release (state);
-}
-
-static void
-totem_python_object_finalize (GObject *object)
-{
- g_debug ("Finalizing Python plugin instance");
-
- if (((TotemPythonObject *) object)->instance) {
- PyGILState_STATE state;
-
- state = pyg_gil_state_ensure();
- Py_DECREF (((TotemPythonObject *) object)->instance);
- pyg_gil_state_release (state);
- }
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-totem_python_object_class_init (TotemPythonObjectClass *klass,
- gpointer class_data)
-{
- TotemPluginClass *plugin_class = TOTEM_PLUGIN_CLASS (klass);
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- klass->type = (PyObject*) class_data;
-
- object_class->finalize = totem_python_object_finalize;
-
- plugin_class->activate = impl_activate;
- plugin_class->deactivate = impl_deactivate;
- plugin_class->create_configure_dialog = impl_create_configure_dialog;
- plugin_class->is_configurable = impl_is_configurable;
-}
-
-GType
-totem_python_object_get_type (GTypeModule *module,
- PyObject *type)
-{
- GType gtype;
- gchar *type_name;
-
- GTypeInfo info = {
- sizeof (TotemPythonObjectClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) totem_python_object_class_init,
- NULL, /* class_finalize */
- type, /* class_data */
- sizeof (TotemPythonObject),
- 0, /* n_preallocs */
- (GInstanceInitFunc) totem_python_object_init
- };
-
- /* no need for pyg_gil_state_ensure() here since this function is only
- * used from within totem_python_module_load() where this is already
- * done */
-
- Py_INCREF (type);
-
- type_name = g_strdup_printf ("%s+TotemPythonPlugin",
- PyString_AsString (PyObject_GetAttrString (type, "__name__")));
-
- g_debug ("Registering Python plugin instance: %s", type_name);
- gtype = g_type_module_register_type (module,
- TOTEM_TYPE_PLUGIN,
- type_name,
- &info, 0);
- g_free (type_name);
-
- return gtype;
-}
diff --git a/src/plugins/totem/Makefile.am b/src/plugins/totem/Makefile.am
deleted file mode 100644
index 8e4f524e3..000000000
--- a/src/plugins/totem/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-plugindir = $(PLUGINDIR)/totem
-plugin_PYTHON = \
- __init__.py
-
diff --git a/src/plugins/totem/__init__.py b/src/plugins/totem/__init__.py
deleted file mode 100644
index c2845c69a..000000000
--- a/src/plugins/totem/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-import gettext
-gettext.textdomain("totem")
-
-D_ = gettext.dgettext
-_ = gettext.gettext
-
diff --git a/src/plugins/tracker/Makefile.am b/src/plugins/tracker/Makefile.am
index 3a0af32d5..4cd0d0560 100644
--- a/src/plugins/tracker/Makefile.am
+++ b/src/plugins/tracker/Makefile.am
@@ -28,6 +28,7 @@ libtracker_la_CPPFLAGS = $(common_defines)
libtracker_la_CFLAGS = \
$(DEPENDENCY_CFLAGS) \
+ $(PEAS_CFLAGS) \
$(TRACKER_CFLAGS) \
$(WARN_CFLAGS) \
$(DBUS_CFLAGS) \
diff --git a/src/plugins/tracker/totem-tracker.c b/src/plugins/tracker/totem-tracker.c
index 70d545d07..2250e4796 100644
--- a/src/plugins/tracker/totem-tracker.c
+++ b/src/plugins/tracker/totem-tracker.c
@@ -60,7 +60,7 @@ typedef struct
G_MODULE_EXPORT GType register_totem_plugin (GTypeModule *module);
GType totem_tracker_plugin_get_type (void) G_GNUC_CONST;
-static gboolean impl_activate (TotemPlugin *plugin, TotemObject *totem, GError **error);
+static void impl_activate (TotemPlugin *plugin, TotemObject *totem);
static void impl_deactivate (TotemPlugin *plugin, TotemObject *totem);
TOTEM_PLUGIN_REGISTER (TotemTrackerPlugin, totem_tracker_plugin)
@@ -68,10 +68,10 @@ TOTEM_PLUGIN_REGISTER (TotemTrackerPlugin, totem_tracker_plugin)
static void
totem_tracker_plugin_class_init (TotemTrackerPluginClass *klass)
{
- TotemPluginClass *plugin_class = TOTEM_PLUGIN_CLASS (klass);
+ PeasPluginClass *plugin_class = PEAS_PLUGIN_CLASS (klass);
- plugin_class->activate = impl_activate;
- plugin_class->deactivate = impl_deactivate;
+ plugin_class->activate = (PeasFunc) impl_activate;
+ plugin_class->deactivate = (PeasFunc) impl_deactivate;
}
static void
@@ -79,18 +79,15 @@ totem_tracker_plugin_init (TotemTrackerPlugin *plugin)
{
}
-static gboolean
+static void
impl_activate (TotemPlugin *plugin,
- TotemObject *totem,
- GError **error)
+ TotemObject *totem)
{
GtkWidget *widget;
widget = totem_tracker_widget_new (totem);
gtk_widget_show (widget);
totem_add_sidebar_page (totem, "tracker", _("Local Search"), widget);
-
- return TRUE;
}
static void
diff --git a/src/plugins/youtube/Makefile.am b/src/plugins/youtube/Makefile.am
index c12af213c..574ad6c54 100644
--- a/src/plugins/youtube/Makefile.am
+++ b/src/plugins/youtube/Makefile.am
@@ -31,6 +31,7 @@ libyoutube_la_CPPFLAGS = $(common_defines)
libyoutube_la_CFLAGS = \
$(DEPENDENCY_CFLAGS) \
+ $(PEAS_CFLAGS) \
$(LIBGDATA_CFLAGS) \
$(WARN_CFLAGS) \
$(DBUS_CFLAGS) \
diff --git a/src/plugins/youtube/totem-youtube.c b/src/plugins/youtube/totem-youtube.c
index 61199bd4e..6fa5e18f9 100644
--- a/src/plugins/youtube/totem-youtube.c
+++ b/src/plugins/youtube/totem-youtube.c
@@ -89,7 +89,7 @@ typedef struct {
G_MODULE_EXPORT GType register_totem_plugin (GTypeModule *module);
GType totem_youtube_plugin_get_type (void) G_GNUC_CONST;
-static gboolean impl_activate (TotemPlugin *plugin, TotemObject *totem, GError **error);
+static void impl_activate (TotemPlugin *plugin, TotemObject *totem);
static void impl_deactivate (TotemPlugin *plugin, TotemObject *totem);
/* GtkBuilder callbacks */
@@ -108,10 +108,10 @@ TOTEM_PLUGIN_REGISTER (TotemYouTubePlugin, totem_youtube_plugin)
static void
totem_youtube_plugin_class_init (TotemYouTubePluginClass *klass)
{
- TotemPluginClass *plugin_class = TOTEM_PLUGIN_CLASS (klass);
+ PeasPluginClass *plugin_class = PEAS_PLUGIN_CLASS (klass);
- plugin_class->activate = impl_activate;
- plugin_class->deactivate = impl_deactivate;
+ plugin_class->activate = (PeasFunc) impl_activate;
+ plugin_class->deactivate = (PeasFunc) impl_deactivate;
}
static void
@@ -332,8 +332,8 @@ set_up_tree_view (TotemYouTubePlugin *self, GtkBuilder *builder, guint key)
self->cancel_button = GTK_WIDGET (gtk_builder_get_object (builder, "yt_cancel_button"));
}
-static gboolean
-impl_activate (TotemPlugin *plugin, TotemObject *totem, GError **error)
+static void
+impl_activate (TotemPlugin *plugin, TotemObject *totem)
{
TotemYouTubePlugin *self = TOTEM_YOUTUBE_PLUGIN (plugin);
GtkWindow *main_window;
@@ -363,8 +363,6 @@ impl_activate (TotemPlugin *plugin, TotemObject *totem, GError **error)
/* Add the sidebar page */
totem_add_sidebar_page (totem, "youtube", _("YouTube"), self->vbox);
g_object_unref (builder);
-
- return TRUE;
}
static void
diff --git a/src/totem-interface.c b/src/totem-interface.c
index c877cb60d..e10782bd3 100644
--- a/src/totem-interface.c
+++ b/src/totem-interface.c
@@ -47,7 +47,6 @@
#include <gconf/gconf-client.h>
#include "totem-interface.h"
-#include "totem-private.h"
static GtkWidget *
totem_interface_error_dialog (const char *title, const char *reason,
@@ -129,14 +128,13 @@ totem_interface_error_blocking (const char *title, const char *reason,
* @uri: the URI to open
* @label: a label for the URI's button, or %NULL to use @uri as the label
* @parent: the error dialogue's parent #GtkWindow
- * @totem: a #TotemObject
*
* Display a modal error dialogue like totem_interface_error(),
* but add a button which will open @uri in a browser window.
**/
void
totem_interface_error_with_link (const char *title, const char *reason,
- const char *uri, const char *label, GtkWindow *parent, Totem *totem)
+ const char *uri, const char *label, GtkWindow *parent)
{
GtkWidget *error_dialog, *link_button, *hbox;
diff --git a/src/totem-interface.h b/src/totem-interface.h
index a87e94a52..f4c374bf6 100644
--- a/src/totem-interface.h
+++ b/src/totem-interface.h
@@ -48,8 +48,7 @@ void totem_interface_error_with_link (const char *title,
const char *reason,
const char *uri,
const char *label,
- GtkWindow *parent,
- Totem *totem);
+ GtkWindow *parent);
void totem_interface_set_transient_for (GtkWindow *window,
GtkWindow *parent);
char * totem_interface_get_license (void);
diff --git a/src/totem-menu.c b/src/totem-menu.c
index 5a9cca74e..7e3b56a05 100644
--- a/src/totem-menu.c
+++ b/src/totem-menu.c
@@ -26,6 +26,7 @@
#include <glib/gi18n.h>
#include <gst/tag/tag.h>
#include <string.h>
+#include <libpeasui/peas-ui-plugin-manager.h>
#include "totem-menu.h"
#include "totem.h"
@@ -33,7 +34,6 @@
#include "totem-private.h"
#include "totem-sidebar.h"
#include "totem-statusbar.h"
-#include "totem-plugin-manager.h"
#include "bacon-video-widget.h"
#include "totem-uri.h"
@@ -1234,7 +1234,7 @@ plugins_action_callback (GtkAction *action, Totem *totem)
G_CALLBACK (totem_plugins_response_cb),
NULL, 0);
- manager = totem_plugin_manager_new ();
+ manager = peas_ui_plugin_manager_new (PEAS_ENGINE (totem->engine));
gtk_widget_show_all (GTK_WIDGET (manager));
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (totem->plugins))),
manager);
diff --git a/src/totem-object.c b/src/totem-object.c
index 31a2d4179..80494b35f 100644
--- a/src/totem-object.c
+++ b/src/totem-object.c
@@ -333,7 +333,8 @@ totem_object_get_property (GObject *object,
void
totem_object_plugins_init (TotemObject *totem)
{
- totem_plugins_engine_init (totem);
+ if (totem->engine == NULL)
+ totem->engine = totem_plugins_engine_get_default (totem);
}
/**
@@ -343,9 +344,12 @@ totem_object_plugins_init (TotemObject *totem)
* plugins.
**/
void
-totem_object_plugins_shutdown (void)
+totem_object_plugins_shutdown (TotemObject *totem)
{
- totem_plugins_engine_shutdown ();
+ if (totem->engine != NULL) {
+ g_object_unref (totem->engine);
+ totem->engine = NULL;
+ }
}
/**
@@ -962,7 +966,7 @@ totem_action_exit (Totem *totem)
/* Save the page ID before we close the plugins, otherwise
* we'll never save it properly */
page_id = totem_sidebar_get_current_page (totem);
- totem_object_plugins_shutdown ();
+ totem_object_plugins_shutdown (totem);
if (display != NULL)
gdk_display_sync (display);
@@ -1251,7 +1255,7 @@ totem_action_load_media (Totem *totem, TotemDiscMediaType type, const char *devi
g_assert_not_reached ();
}
- totem_interface_error_with_link (msg, secondary, link, link_text, GTK_WINDOW (totem->win), totem);
+ totem_interface_error_with_link (msg, secondary, link, link_text, GTK_WINDOW (totem->win));
g_free (msg);
return FALSE;
}
diff --git a/src/totem-private.h b/src/totem-private.h
index 9d5b89c44..660c53fc3 100644
--- a/src/totem-private.h
+++ b/src/totem-private.h
@@ -37,6 +37,7 @@
#include "bacon-video-widget.h"
#include "totem-open-location.h"
#include "totem-fullscreen.h"
+#include "totem-plugins-engine.h"
#define totem_signal_block_by_data(obj, data) (g_signal_handlers_block_matched (obj, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data))
#define totem_signal_unblock_by_data(obj, data) (g_signal_handlers_unblock_matched (obj, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data))
@@ -95,6 +96,7 @@ struct _TotemObject {
/* Plugins */
GtkWidget *plugins;
+ TotemPluginsEngine *engine;
/* Sidebar */
GtkWidget *sidebar;
diff --git a/src/totem.h b/src/totem.h
index 959e40e0a..8af9c3049 100644
--- a/src/totem.h
+++ b/src/totem.h
@@ -181,7 +181,7 @@ typedef struct {
GType totem_object_get_type (void);
void totem_object_plugins_init (TotemObject *totem);
-void totem_object_plugins_shutdown (void);
+void totem_object_plugins_shutdown (TotemObject *totem);
void totem_file_opened (TotemObject *totem,
const char *mrl);
void totem_file_closed (TotemObject *totem);