diff options
author | npmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56> | 2007-12-13 02:03:29 +0000 |
---|---|---|
committer | npmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56> | 2007-12-13 02:03:29 +0000 |
commit | ce01955cd62a945dd5d05e2133f3bf5bec1a8b10 (patch) | |
tree | 29dfffea2b335aefb7c92a037621a77bdeff919d | |
parent | f1f866939ab37c2bbd8fe5fbcf557333037ab85a (diff) | |
download | libproxy-ce01955cd62a945dd5d05e2133f3bf5bec1a8b10.tar.gz |
natively code the xlsclients stuff; sacrifice application re-homing for MASSIVE performance gain
git-svn-id: http://libproxy.googlecode.com/svn/trunk@94 c587cffe-e639-0410-9787-d7902ae8ed56
-rw-r--r-- | configure.ac | 95 | ||||
-rw-r--r-- | src/plugins/Makefile.am | 8 | ||||
-rw-r--r-- | src/plugins/gnome.c | 120 | ||||
-rw-r--r-- | src/plugins/kde.c | 116 |
4 files changed, 267 insertions, 72 deletions
diff --git a/configure.ac b/configure.ac index ffc4b34..c2e7075 100644 --- a/configure.ac +++ b/configure.ac @@ -12,64 +12,117 @@ AC_PROG_LN_S AC_PROG_MAKE_SET ### Checks for libraries for plugins. +PKG_CHECK_MODULES(x11, x11, have_x11=yes, have_x11=no) +PKG_CHECK_MODULES(xmu, xmu, have_xmu=yes, have_xmu=no) +PKG_CHECK_MODULES(gconf, gconf-2.0, have_gconf=yes, have_gconf=no) +PKG_CHECK_MODULES(mozjs, firefox-js, have_mozjs=yes, have_mozjs=no) +PKG_CHECK_MODULES(MOZJS, xulrunner-js, have_mozjs=yes, + [test x$have_mozjs == xyes || have_mozjs=no]) +PKG_CHECK_MODULES(NetworkManager, NetworkManager, + have_networkmanager=yes, have_networkmanager=no) + # Environmental Variable AC_ARG_WITH([envvar], [AS_HELP_STRING([--with-envvar], - [build environmental variable configuration plugin @<:@default=yes@:>@])], + [build environmental variable configuration plugin @<:@default=yes@:>@])], [], [with_envvar=yes]) AM_CONDITIONAL([WITH_ENVVAR], [test x$with_envvar = xyes]) # File AC_ARG_WITH([file], [AS_HELP_STRING([--with-file], - [build file-based configuration plugin @<:@default=yes@:>@])], + [build file-based configuration plugin @<:@default=yes@:>@])], [], [with_file=yes]) AM_CONDITIONAL([WITH_FILE], [test x$with_envvar = xyes]) # GNOME AC_ARG_WITH([gnome], [AS_HELP_STRING([--with-gnome], - [build GNOME configuration plugin @<:@automatic@:>@])], + [build GNOME configuration plugin @<:@automatic@:>@])], [], - [PKG_CHECK_EXISTS(gconf-2.0, with_gnome=yes, with_gnome=no)]) + [test x$have_gconf == xyes && + test x$have_x11 == xyes && + test x$have_xmu == xyes && + with_gnome=yes]) if test x$with_gnome = xyes; then - PKG_CHECK_MODULES(GCONF, gconf-2.0) - AC_SUBST(GCONF_CFLAGS) - AC_SUBST(GCONF_LIBS) + if test x$have_gconf == xyes && \ + test x$have_x11 == xyes && \ + test x$have_xmu == xyes; then + GNOME_CFLAGS="$x11_CFLAGS $xmu_CFLAGS $gconf_CFLAGS" + GNOME_LIBS="$x11_LIBS $xmu_LIBS $gconf_LIBS" + + echo + echo "-------------------------------------------" + echo $GNOME_CFLAGS + echo "-------------------------------------------" + echo + + AC_SUBST(GNOME_CFLAGS) + AC_SUBST(GNOME_LIBS) + else + echo "GNOME plugin requires: x11, xmu and gconf!" + exit 1 + fi fi AM_CONDITIONAL([WITH_GNOME], [test x$with_gnome = xyes]) # KDE AC_ARG_WITH([kde], [AS_HELP_STRING([--with-kde], - [build KDE configuration plugin @<:@default=yes@:>@])], - [], [with_kde=yes]) + [build KDE configuration plugin @<:@automatic@:>@])], + [], + [test x$have_x11 == xyes && + test x$have_xmu == xyes && + with_kde=yes]) +if test x$with_kde = xyes; then + if test x$have_x11 == xyes && \ + test x$have_xmu == xyes; then + KDE_CFLAGS="$x11_CFLAGS $xmu_CFLAGS" + KDE_LIBS="$x11_LIBS $xmu_LIBS" + AC_SUBST(KDE_CFLAGS) + AC_SUBST(KDE_LIBS) + else + echo "KDE plugin requires: x11 and xmu!" + exit 1 + fi +fi AM_CONDITIONAL([WITH_KDE], [test x$with_kde = xyes]) # Mozilla Javascript AC_ARG_WITH([mozjs], [AS_HELP_STRING([--with-mozjs], - [build Mozilla JavaScript PAC runner plugin @<:@automatic@:>@])], + [build Mozilla JavaScript PAC runner plugin @<:@automatic@:>@])], [], - [PKG_CHECK_EXISTS(firefox-js, with_mozjs=yes, - PKG_CHECK_EXISTS(xulrunner-js, with_mozjs=yes, with_mozjs=no))]) + [test x$have_mozjs == xyes && with_mozjs=yes]) if test x$with_mozjs = xyes; then - PKG_CHECK_MODULES(MOZJS, firefox-js,, [PKG_CHECK_MODULES(MOZJS, xulrunner-js)]) - AC_SUBST(MOZJS_CFLAGS) - AC_SUBST(MOZJS_LIBS) + if test x$have_mozjs == xyes; then + MOZJS_CFLAGS="$mozjs_CFLAGS" + MOZJS_LIBS="$mozjs_LIBS" + AC_SUBST(MOZJS_CFLAGS) + AC_SUBST(MOZJS_LIBS) + else + echo "Mozilla JavaScript plugin requires: mozjs!" + exit 1 + fi fi AM_CONDITIONAL([WITH_MOZJS], [test x$with_mozjs = xyes]) # NetworkManager AC_ARG_WITH([networkmanager], [AS_HELP_STRING([--with-networkmanager], - [build NetworkManager plugin @<:@automatic@:>@])], + [build NetworkManager plugin @<:@automatic@:>@])], [], - [PKG_CHECK_EXISTS(NetworkManager, with_networkmanager=yes, with_networkmanager=no)]) + [test x$have_networkmanager == xyes && with_networkmanager=yes]) if test x$with_networkmanager = xyes; then - PKG_CHECK_MODULES(NETWORKMANAGER, NetworkManager) - AC_SUBST(NETWORKMANAGER_CFLAGS) - AC_SUBST(NETWORKMANAGER_LIBS) + if test x$have_networkmanager == xyes; then + NETWORKMANAGER_CFLAGS="$NetworkManager_CFLAGS" + NETWORKMANAGER_LIBS="$NetworkManager_LIBS" + AC_SUBST(NETWORKMANAGER_CFLAGS) + AC_SUBST(NETWORKMANAGER_LIBS) + else + echo "NetworkManager plugin requires: NetworkManager!" + exit 1 + fi fi AM_CONDITIONAL([WITH_NETWORKMANAGER], [test x$with_networkmanager = xyes]) @@ -77,7 +130,7 @@ AM_CONDITIONAL([WITH_NETWORKMANAGER], [test x$with_networkmanager = xyes]) # Python AC_ARG_WITH([python], [AS_HELP_STRING([--with-python], - [build Python bindings @<:@automatic@:>@])], + [build Python bindings @<:@automatic@:>@])], [AM_PATH_PYTHON([2.5], with_python=yes)], [AM_PATH_PYTHON([2.5], with_python=yes, with_python=no)]) AM_CONDITIONAL([WITH_PYTHON], [test x$with_python = xyes]) diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 15113a5..04d0c8a 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -35,15 +35,15 @@ file_la_LDFLAGS = -module -avoid-version # GConf/GNOME Config Plugin gnome_la_SOURCES = gnome.c -gnome_la_CFLAGS = -I../lib @GCONF_CFLAGS@ +gnome_la_CFLAGS = -I../lib @GNOME_CFLAGS@ gnome_la_LIBADD = ../lib/libproxy.la -gnome_la_LDFLAGS = -module -avoid-version @GCONF_LIBS@ +gnome_la_LDFLAGS = -module -avoid-version @GNOME_LIBS@ # KDE Config Plugin kde_la_SOURCES = kde.c -kde_la_CFLAGS = -I../lib +kde_la_CFLAGS = -I../lib @KDE_CFLAGS@ kde_la_LIBADD = ../lib/libproxy.la -kde_la_LDFLAGS = -module -avoid-version +kde_la_LDFLAGS = -module -avoid-version @KDE_LIBS@ # Mozilla (Spidermonkey) based PAC runner mozjs_la_SOURCES = mozjs.c diff --git a/src/plugins/gnome.c b/src/plugins/gnome.c index 9ea44c8..2c9482a 100644 --- a/src/plugins/gnome.c +++ b/src/plugins/gnome.c @@ -19,12 +19,100 @@ #include <stdlib.h> #include <string.h> +#include <stdarg.h> #include <misc.h> #include <proxy_factory.h> #include <gconf/gconf-client.h> +#include <X11/Xlib.h> +#include <X11/Xmu/WinUtil.h> + +// This function is shamelessly stolen from xlsclient... :) +/* + * + * +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * * + * Author: Jim Fulton, MIT X Consortium + */ +bool +x_has_client(char *prog, ...) +{ + va_list ap; + + // Open display + Display *display = XOpenDisplay(NULL); + if (!display) + return false; + + // For each screen... + for (int i=0; i < ScreenCount(display); i++) + { + Window dummy, *children = NULL; + unsigned int nchildren = 0; + + // Get the root window's children + if (!XQueryTree(display, RootWindow(display, i), &dummy, &dummy, &children, &nchildren)) + continue; + + // For each child on the screen... + for (int j=0; j < nchildren; j++) + { + // If we can get their client info... + Window client; + if ((client = XmuClientWindow(display, children[j])) != None) + { + int argc; + char **argv; + + // ... and if we can find out their command ... + if (!XGetCommand (display, client, &argv, &argc) || argc == 0) + continue; + + // ... check the commands against our list + va_start(ap, prog); + for (char *s = prog ; s ; s = va_arg(ap, char *)) + { + // We've found a match, return... + if (!strcmp(argv[0], s)) + { + va_end(ap); + XCloseDisplay(display); + return true; + } + } + va_end(ap); + } + } + } + + // Close the display + XCloseDisplay(display); + return false; +} + pxConfig * gconf_config_cb(pxProxyFactory *self) { @@ -116,38 +204,22 @@ gconf_config_cb(pxProxyFactory *self) return px_config_create(url, ignore); } -void -gconf_on_get_proxy(pxProxyFactory *self) -{ - // If we are running in GNOME, then make sure this plugin is registered. - // Otherwise, make sure this plugin is NOT registered. - // TODO: Don't shell out... this is a MAJOR performance bottleneck - if (!system("xlsclients 2>/dev/null | grep -q -E '[\t ]gnome-(session|panel)$'")) - px_proxy_factory_config_add(self, "gnome", PX_CONFIG_CATEGORY_SESSION, - (pxProxyFactoryPtrCallback) gconf_config_cb); - else - px_proxy_factory_config_del(self, "gnome"); - - return; -} - bool on_proxy_factory_instantiate(pxProxyFactory *self) { - // Note that we instantiate like this because SESSION config plugins - // are only suppossed to remain registered while the application - // is actually IN that session. So for instance, if the app - // was run in GNU screen and is taken out of the GNOME sesion - // it was started in, we should handle that gracefully. - g_type_init(); - px_proxy_factory_on_get_proxy_add(self, gconf_on_get_proxy); - return true; + // If we are running in GNOME, then make sure this plugin is registered. + if (x_has_client("gnome-session", "gnome-panel", NULL)) + { + g_type_init(); + return px_proxy_factory_config_add(self, "gnome", PX_CONFIG_CATEGORY_SESSION, + (pxProxyFactoryPtrCallback) gconf_config_cb); + } + return false; } void on_proxy_factory_destantiate(pxProxyFactory *self) { - px_proxy_factory_on_get_proxy_del(self, gconf_on_get_proxy); px_proxy_factory_config_del(self, "gnome"); // Close the GConf connection, if present diff --git a/src/plugins/kde.c b/src/plugins/kde.c index fac2c39..e212920 100644 --- a/src/plugins/kde.c +++ b/src/plugins/kde.c @@ -19,11 +19,99 @@ #include <stdlib.h> #include <string.h> +#include <stdarg.h> #include <misc.h> #include <proxy_factory.h> #include <config_file.h> +#include <X11/Xlib.h> +#include <X11/Xmu/WinUtil.h> + +// This function is shamelessly stolen from xlsclient... :) +/* + * + * +Copyright 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * * + * Author: Jim Fulton, MIT X Consortium + */ +bool +x_has_client(char *prog, ...) +{ + va_list ap; + + // Open display + Display *display = XOpenDisplay(NULL); + if (!display) + return false; + + // For each screen... + for (int i=0; i < ScreenCount(display); i++) + { + Window dummy, *children = NULL; + unsigned int nchildren = 0; + + // Get the root window's children + if (!XQueryTree(display, RootWindow(display, i), &dummy, &dummy, &children, &nchildren)) + continue; + + // For each child on the screen... + for (int j=0; j < nchildren; j++) + { + // If we can get their client info... + Window client; + if ((client = XmuClientWindow(display, children[j])) != None) + { + int argc; + char **argv; + + // ... and if we can find out their command ... + if (!XGetCommand (display, client, &argv, &argc) || argc == 0) + continue; + + // ... check the commands against our list + va_start(ap, prog); + for (char *s = prog ; s ; s = va_arg(ap, char *)) + { + // We've found a match, return... + if (!strcmp(argv[0], s)) + { + va_end(ap); + XCloseDisplay(display); + return true; + } + } + va_end(ap); + } + } + } + + // Close the display + XCloseDisplay(display); + return false; +} + pxConfig * kde_config_cb(pxProxyFactory *self) { @@ -80,37 +168,19 @@ kde_config_cb(pxProxyFactory *self) return px_config_create(url, ignore); } -void -kde_on_get_proxy(pxProxyFactory *self) -{ - // If we are running in KDE, then make sure this plugin is registered. - // Otherwise, make sure this plugin is NOT registered. - // TODO: Don't shell out... this is a MAJOR performance bottleneck - if (!system("xlsclients 2>/dev/null | grep -q '[\t ]kicker$'")) - px_proxy_factory_config_add(self, "kde", PX_CONFIG_CATEGORY_SESSION, - (pxProxyFactoryPtrCallback) kde_config_cb); - else - px_proxy_factory_config_del(self, "kde"); - - return; -} - bool on_proxy_factory_instantiate(pxProxyFactory *self) { - // Note that we instantiate like this because SESSION config plugins - // are only suppossed to remain registered while the application - // is actually IN that session. So for instance, if the app - // was run in GNU screen and is taken out of the GNOME sesion - // it was started in, we should handle that gracefully. - px_proxy_factory_on_get_proxy_add(self, kde_on_get_proxy); - return true; + // If we are running in KDE, then make sure this plugin is registered. + if (x_has_client("kicker", NULL)) + return px_proxy_factory_config_add(self, "kde", PX_CONFIG_CATEGORY_SESSION, + (pxProxyFactoryPtrCallback) kde_config_cb); + return false; } void on_proxy_factory_destantiate(pxProxyFactory *self) { - px_proxy_factory_on_get_proxy_del(self, kde_on_get_proxy); px_proxy_factory_config_del(self, "kde"); px_config_file_free(px_proxy_factory_misc_get(self, "kde")); px_proxy_factory_misc_set(self, "kde", NULL); |