diff options
author | David Reveman <davidr@novell.com> | 2007-05-18 15:58:14 -0400 |
---|---|---|
committer | David Reveman <davidr@novell.com> | 2007-05-18 15:58:14 -0400 |
commit | 21be0fb19201f80caf9a1c3acf968f91a997aa83 (patch) | |
tree | 5c19af49e317975c9083cd20f52d792a5428f65a | |
parent | 02ba5d7bf879fb2b2ca07507810a2bd502e076bb (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.ac | 14 | ||||
-rw-r--r-- | metadata/Makefile.am | 1 | ||||
-rw-r--r-- | metadata/glib.xml.in | 6 | ||||
-rw-r--r-- | plugins/Makefile.am | 8 | ||||
-rw-r--r-- | plugins/glib.c | 264 | ||||
-rw-r--r-- | po/POTFILES.in | 1 |
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 |