summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornpmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56>2007-12-13 02:03:29 +0000
committernpmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56>2007-12-13 02:03:29 +0000
commitce01955cd62a945dd5d05e2133f3bf5bec1a8b10 (patch)
tree29dfffea2b335aefb7c92a037621a77bdeff919d
parentf1f866939ab37c2bbd8fe5fbcf557333037ab85a (diff)
downloadlibproxy-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.ac95
-rw-r--r--src/plugins/Makefile.am8
-rw-r--r--src/plugins/gnome.c120
-rw-r--r--src/plugins/kde.c116
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);