summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2007-05-18 15:58:14 -0400
committerDavid Reveman <davidr@novell.com>2007-05-18 15:58:14 -0400
commit21be0fb19201f80caf9a1c3acf968f91a997aa83 (patch)
tree5c19af49e317975c9083cd20f52d792a5428f65a
parent02ba5d7bf879fb2b2ca07507810a2bd502e076bb (diff)
Add glib plugin.
This plugin properly integrates the GLib main loop and makes sure that any plugins that use the default GLib main loop will be dispatched efficiently.
-rw-r--r--configure.ac14
-rw-r--r--metadata/Makefile.am1
-rw-r--r--metadata/glib.xml.in6
-rw-r--r--plugins/Makefile.am8
-rw-r--r--plugins/glib.c264
-rw-r--r--po/POTFILES.in1
6 files changed, 294 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 8ebc1d90..07442f4a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,6 +128,19 @@ if test -z "$XSLTPROC"; then
AC_MSG_ERROR([Couldn't find xsltproc])
fi
+AC_ARG_ENABLE(glib,
+ [ --disable-glib Disable glib plugin],
+ [use_glib=$enableval], [use_glib=yes])
+
+if test "x$use_glib" = "xyes"; then
+ PKG_CHECK_MODULES(GLIB, glib-2.0)
+fi
+
+AM_CONDITIONAL(USE_GLIB, test "x$use_glib" = "xyes")
+if test "$use_glib" = yes; then
+ AC_DEFINE(USE_GLIB, 1, [Build glib plugin])
+fi
+
AC_ARG_ENABLE(gconf,
[ --disable-gconf Disable gconf plugin],
[use_gconf=$enableval], [use_gconf=yes])
@@ -454,6 +467,7 @@ metadata/Makefile
echo ""
echo "the following optional plugins will be compiled:"
+echo " glib: $use_glib"
echo " gconf: $use_gconf"
echo " place: $use_place"
echo " dbus: $use_dbus"
diff --git a/metadata/Makefile.am b/metadata/Makefile.am
index 6ea5725f..23ca4a9d 100644
--- a/metadata/Makefile.am
+++ b/metadata/Makefile.am
@@ -10,6 +10,7 @@ xml_in_files = \
fade.xml.in \
fs.xml.in \
gconf.xml.in \
+ glib.xml.in \
ini.xml.in \
inotify.xml.in \
minimize.xml.in \
diff --git a/metadata/glib.xml.in b/metadata/glib.xml.in
new file mode 100644
index 00000000..6f053ece
--- /dev/null
+++ b/metadata/glib.xml.in
@@ -0,0 +1,6 @@
+<compiz>
+ <plugin name="glib">
+ <_short>GLib</_short>
+ <_long>GLib main loop support</_long>
+ </plugin>
+</compiz>
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 96cfc926..1b5ae1f3 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -79,6 +79,13 @@ libannotate_la_SOURCES = annotate.c
libannotate_module = libannotate.la
endif
+if USE_GLIB
+libglib_la_LDFLAGS = -module -avoid-version -no-undefined
+libglib_la_LIBADD = @GLIB_LIBS@
+libglib_la_SOURCES = glib.c
+libglib_module = libglib.la
+endif
+
if USE_GCONF
libgconf_la_LDFLAGS = -module -avoid-version -no-undefined
libgconf_la_LIBADD = @GCONF_LIBS@
@@ -132,6 +139,7 @@ INCLUDES = \
moduledir = $(plugindir)
module_LTLIBRARIES = \
+ $(libglib_module) \
$(libgconf_module) \
libdecoration.la \
libwobbly.la \
diff --git a/plugins/glib.c b/plugins/glib.c
new file mode 100644
index 00000000..53bc8cce
--- /dev/null
+++ b/plugins/glib.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright © 2007 Novell, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Novell, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * Novell, Inc. makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#include <glib.h>
+#include <compiz.h>
+
+static CompMetadata glibMetadata;
+
+static int displayPrivateIndex;
+
+typedef struct _GLibWatch {
+ CompWatchFdHandle handle;
+ int index;
+ CompDisplay *display;
+} GLibWatch;
+
+typedef struct _GConfDisplay {
+ CompTimeoutHandle timeoutHandle;
+ gint maxPriority;
+ GPollFD *fds;
+ gint fdsSize;
+ gint nFds;
+ GLibWatch *watch;
+} GLibDisplay;
+
+#define GET_GLIB_DISPLAY(d) \
+ ((GLibDisplay *) (d)->privates[displayPrivateIndex].ptr)
+
+#define GLIB_DISPLAY(d) \
+ GLibDisplay *gd = GET_GLIB_DISPLAY (d)
+
+static void
+glibDispatch (CompDisplay *display,
+ GMainContext *context)
+{
+ int i;
+
+ GLIB_DISPLAY (display);
+
+ g_main_context_check (context, gd->maxPriority, gd->fds, gd->nFds);
+ g_main_context_dispatch (context);
+
+ for (i = 0; i < gd->nFds; i++)
+ compRemoveWatchFd (gd->watch[i].handle);
+}
+
+static void
+glibPrepare (CompDisplay *display,
+ GMainContext *context);
+
+static Bool
+glibDispatchAndPrepare (void *closure)
+{
+ CompDisplay *display = (CompDisplay *) closure;
+ GMainContext *context = g_main_context_default ();
+
+ glibDispatch (display, context);
+ glibPrepare (display, context);
+
+ return FALSE;
+}
+
+static Bool
+glibCollectEvents (void *closure)
+{
+ GLibWatch *watch = (GLibWatch *) closure;
+ CompDisplay *display = watch->display;
+
+ GLIB_DISPLAY (display);
+
+ gd->fds[watch->index].revents |= compWatchFdEvents (watch->handle);
+
+ if (gd->timeoutHandle)
+ {
+ compRemoveTimeout (gd->timeoutHandle);
+ compAddTimeout (0, glibDispatchAndPrepare, (void *) display);
+
+ gd->timeoutHandle = 0;
+ }
+
+ return TRUE;
+}
+
+static void
+glibPrepare (CompDisplay *display,
+ GMainContext *context)
+{
+ int nFds = 0;
+ int timeout = -1;
+ int i;
+
+ GLIB_DISPLAY (display);
+
+ g_main_context_prepare (context, &gd->maxPriority);
+
+ do
+ {
+ if (nFds > gd->fdsSize)
+ {
+ if (gd->fds)
+ free (gd->fds);
+
+ gd->fds = malloc ((sizeof (GPollFD) + sizeof (GLibWatch)) * nFds);
+ if (!gd->fds)
+ {
+ nFds = 0;
+ break;
+ }
+
+ gd->watch = (GLibWatch *) (gd->fds + nFds);
+ gd->fdsSize = nFds;
+ }
+
+ nFds = g_main_context_query (context,
+ gd->maxPriority,
+ &timeout,
+ gd->fds,
+ gd->fdsSize);
+ } while (nFds > gd->fdsSize);
+
+ if (timeout < 0)
+ timeout = INT_MAX;
+
+ for (i = 0; i < nFds; i++)
+ {
+ gd->watch[i].display = display;
+ gd->watch[i].index = i;
+ gd->watch[i].handle = compAddWatchFd (gd->fds[i].fd,
+ gd->fds[i].events,
+ glibCollectEvents,
+ &gd->watch[i]);
+ }
+
+ gd->nFds = nFds;
+ gd->timeoutHandle =
+ compAddTimeout (timeout, glibDispatchAndPrepare, display);
+}
+
+static Bool
+glibInitDisplay (CompPlugin *p,
+ CompDisplay *d)
+{
+ GLibDisplay *gd;
+
+ gd = malloc (sizeof (GLibDisplay));
+ if (!gd)
+ return FALSE;
+
+ gd->fds = NULL;
+ gd->fdsSize = 0;
+ gd->timeoutHandle = 0;
+
+ d->privates[displayPrivateIndex].ptr = gd;
+
+ glibPrepare (d, g_main_context_default ());
+
+ return TRUE;
+}
+
+static void
+glibFiniDisplay (CompPlugin *p,
+ CompDisplay *d)
+{
+ GLIB_DISPLAY (d);
+
+ if (gd->timeoutHandle)
+ compRemoveTimeout (gd->timeoutHandle);
+
+ glibDispatch (d, g_main_context_default ());
+
+ if (gd->fds)
+ free (gd->fds);
+
+ free (gd);
+}
+
+static Bool
+glibInit (CompPlugin *p)
+{
+ if (!compInitPluginMetadataFromInfo (&glibMetadata, p->vTable->name,
+ 0, 0, 0, 0))
+ return FALSE;
+
+ displayPrivateIndex = allocateDisplayPrivateIndex ();
+ if (displayPrivateIndex < 0)
+ {
+ compFiniMetadata (&glibMetadata);
+ return FALSE;
+ }
+
+ compAddMetadataFromFile (&glibMetadata, p->vTable->name);
+
+ return TRUE;
+}
+
+static void
+glibFini (CompPlugin *p)
+{
+ freeDisplayPrivateIndex (displayPrivateIndex);
+ compFiniMetadata (&glibMetadata);
+}
+
+static int
+glibGetVersion (CompPlugin *plugin,
+ int version)
+{
+ return ABIVERSION;
+}
+
+static CompMetadata *
+glibGetMetadata (CompPlugin *plugin)
+{
+ return &glibMetadata;
+}
+
+CompPluginVTable glibVTable = {
+ "glib",
+ glibGetVersion,
+ glibGetMetadata,
+ glibInit,
+ glibFini,
+ glibInitDisplay,
+ glibFiniDisplay,
+ 0, /* InitScreen */
+ 0, /* FiniScreen */
+ 0, /* InitWindow */
+ 0, /* FiniWindow */
+ 0, /* GetDisplayOptions */
+ 0, /* SetDisplayOption */
+ 0, /* GetScreenOptions */
+ 0, /* SetScreenOption */
+ 0, /* Deps */
+ 0, /* nDeps */
+ 0, /* Features */
+ 0 /* nFeatures */
+};
+
+CompPluginVTable *
+getCompPluginInfo (void)
+{
+ return &glibVTable;
+}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 57662830..dbfc1e32 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,6 +12,7 @@ metadata/decoration.xml.in
metadata/fade.xml.in
metadata/fs.xml.in
metadata/gconf.xml.in
+metadata/glib.xml.in
metadata/ini.xml.in
metadata/inotify.xml.in
metadata/minimize.xml.in