summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--configure.in28
-rw-r--r--src/command.c117
-rw-r--r--src/feature.h4
4 files changed, 150 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 25fcd32..625d72a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5445,3 +5445,7 @@ Thu Dec 22 18:32:31 2005 Michael Jennings (mej)
Cleanups and minor enhancements.
----------------------------------------------------------------------
+Wed Jan 4 03:44:04 2006 Michael Jennings (mej)
+
+X resource tracking/debugging support.
+----------------------------------------------------------------------
diff --git a/configure.in b/configure.in
index 2fd217d..c8e4f85 100644
--- a/configure.in
+++ b/configure.in
@@ -204,8 +204,10 @@ AC_CHECK_HEADERS(fcntl.h termios.h \
sys/ioctl.h sys/select.h sys/time.h \
sys/sockio.h sys/byteorder.h malloc.h \
utmpx.h unistd.h bsd/signal.h regex.h \
-regexp.h stdarg.h X11/Xmu/Atoms.h \
-X11/Sunkeysym.h X11/Xlocale.h)
+regexp.h stdarg.h X11/X.h X11/Xlib.h \
+X11/Xmu/Atoms.h X11/Sunkeysym.h \
+X11/Xlocale.h \
+)
AC_HEADER_TIME
dnl# Missing typedefs and replacements
@@ -219,7 +221,8 @@ AC_TYPE_SIGNAL
AC_CHECK_FUNCS(atexit _exit unsetenv setutent \
seteuid memmove putenv strsep setresuid setresgid \
memmem usleep snprintf strcasestr strcasechr \
-strcasepbrk strrev nl_langinfo)
+strcasepbrk strrev nl_langinfo \
+)
# NOTE: The following line is NOT NOT NOT NOT NOT a typo!
# If you are having problems with it, libast.m4 is not installed
@@ -872,6 +875,25 @@ if test "$XIM" = "TRUE"; then
AC_CHECK_LIB(X11, XRegisterIMInstantiateCallback, AC_DEFINE(USE_X11R6_XIM, , [Define if we have X11R6 XIM.]))
fi
+# Check for XResource extension
+AC_CHECK_HEADER([X11/extensions/XRes.h],
+ [
+ AC_DEFINE([HAVE_X11_EXTENSIONS_XRES_H], [], [Define if we have X11/extensions/XRes.h])
+ ], [],
+ [
+#ifdef HAVE_X11_X_H
+# include <X11/X.h>
+#endif
+#ifdef HAVE_X11_XLIB_H
+# include <X11/Xlib.h>
+#endif
+ ])
+AC_CHECK_LIB(XRes, XResQueryExtension,
+ [
+ GRLIBS="$GRLIBS -lXRes"
+ AC_DEFINE(HAVE_XRES_EXT, , [Define if we have the XResource extension.])
+ ])
+
AC_MSG_CHECKING(for Greek keyboard support)
AC_ARG_ENABLE(greek,
[ --enable-greek compile with support for Greek keyboards], [
diff --git a/src/command.c b/src/command.c
index 4cf6f9f..ab8a19d 100644
--- a/src/command.c
+++ b/src/command.c
@@ -67,6 +67,9 @@ static const char cvs_ident[] = "$Id$";
#include <X11/Xos.h>
#include <X11/Xproto.h>
#include <X11/IntrinsicP.h>
+#ifdef HAVE_XRES_EXT
+# include <X11/extensions/XRes.h>
+#endif
#ifdef PTY_GRP_NAME
# include <grp.h>
#endif
@@ -147,6 +150,7 @@ TW_DECL_MAGIC(libscream_magic);
static RETSIGTYPE handle_child_signal(int);
static RETSIGTYPE handle_exit_signal(int);
static RETSIGTYPE handle_crash(int);
+static RETSIGTYPE x_resource_dump(int);
/* local variables */
int my_ruid, my_euid, my_rgid, my_egid;
@@ -1114,6 +1118,114 @@ handle_crash(int sig)
SIG_RETURN(0);
}
+#ifdef HAVE_XRES_EXT
+static RETSIGTYPE
+x_resource_dump(int sig)
+{
+ int event_base, error_base, count, i;
+ unsigned long bytes;
+ XResClient *clients = NULL;
+ XResType *types = NULL;
+ Atom pixmap_atom, gc_atom, font_atom;
+ pid_t my_pid;
+ char *title, *ptitle;
+
+ USE_VAR(sig);
+ my_pid = getpid();
+
+ /* Create type atoms for future use. */
+ pixmap_atom = XInternAtom(Xdisplay, "PIXMAP", False);
+ gc_atom = XInternAtom(Xdisplay, "GC", False);
+ gc_atom = XInternAtom(Xdisplay, "FONT", False);
+
+ /* Look at what *we* think our consumption is. */
+#if DEBUG >= DEBUG_MEM
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ PIXMAP_DUMP();
+ GC_DUMP();
+ }
+#endif
+
+ /* Make sure we have the extension loaded. */
+ if (!XResQueryExtension(Xdisplay, &event_base, &error_base)) {
+ fprintf(stderr, "XResource extension not available on current display.\n");
+ return;
+ }
+ D_X11(("Got XResource extension values: %d (0x%08x) / %d (0x%08x)\n",
+ event_base, event_base, error_base, error_base));
+
+ /* Get a list of X clients and find our window ID in the list. */
+ if (!XResQueryClients(Xdisplay, &count, &clients)) {
+ if (clients) {
+ XFree(clients);
+ }
+ D_X11((" -> Unable to query clients.\n"));
+ return;
+ }
+ D_X11((" -> Got %d clients.\n", count));
+
+ if (count == 0) {
+ D_X11((" -> Nothing to do!\n"));
+ return;
+ }
+
+ for (i = 0; i < count; i++) {
+ Window win;
+
+ win = clients[i].resource_base & (~clients[i].resource_mask);
+ D_X11(("Checking client: base %d, mask %d, window 0x%08x\n", clients[i].resource_base,
+ clients[i].resource_mask, win));
+ if ((TermWin.parent & (~clients[i].resource_mask)) == win) {
+ break;
+ }
+ }
+ if (i == count) {
+ D_X11((" -> No client found with window 0x%08x (0x%08x\n", TermWin.parent,
+ (TermWin.parent & (~clients[i].resource_mask))));
+ return;
+ }
+
+ /* Request resource info for our client ID. */
+ if (!XResQueryClientResources(Xdisplay, clients[i].resource_base, &count, &types)
+ || !XResQueryClientPixmapBytes(Xdisplay, clients[i].resource_base, &bytes)) {
+ if (types) {
+ XFree(types);
+ }
+ D_X11((" -> Unable to query resources.\n"));
+ return;
+ }
+ D_X11((" -> Got %d types.\n", count));
+
+ /* Get and sanitize window title for easier identification. */
+ XFetchName(Xdisplay, TermWin.parent, &title);
+ if (title) {
+ for (ptitle = title; *ptitle; ptitle++) {
+ if (!isprint(*ptitle)) {
+ *ptitle = ' ';
+ }
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ if (types[i].resource_type == pixmap_atom) {
+ fprintf(stderr, "Process %lu, window 0x%08x (%s): %d pixmaps (%d bytes).\n", my_pid, TermWin.parent,
+ NONULL(title), types[i].count, bytes);
+ } else if (types[i].resource_type == gc_atom) {
+ fprintf(stderr, "Process %lu, window 0x%08x (%s): %d GC's (%d bytes).\n", my_pid, TermWin.parent,
+ NONULL(title), types[i].count, types[i].count * (sizeof(XGCValues) + sizeof(GC)));
+ } else if (types[i].resource_type == font_atom) {
+ fprintf(stderr, "Process %lu, window 0x%08x (%s): %d fonts (%d bytes).\n", my_pid, TermWin.parent,
+ NONULL(title), types[i].count, types[i].count * (sizeof(XFontStruct) + sizeof(Font)));
+ }
+ }
+ XFree(clients);
+ XFree(types);
+ if (title) {
+ XFree(title);
+ }
+}
+#endif
+
void
install_handlers(void)
{
@@ -1133,6 +1245,11 @@ install_handlers(void)
signal(SIGILL, handle_crash);
signal(SIGSYS, handle_crash);
signal(SIGPIPE, SIG_IGN);
+#ifdef HAVE_XRES_EXT
+ signal(SIGUSR1, x_resource_dump);
+#else
+ signal(SIGUSR1, SIG_IGN);
+#endif
}
/* Exit gracefully, clearing the utmp entry and restoring tty attributes */
diff --git a/src/feature.h b/src/feature.h
index 798022a..891cd97 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -300,6 +300,10 @@ inline void *memmove(void *, const void *, size_t);
# define NO_DELETE_KEY /* These systems seem to be anal this way*/
#endif
+#if !defined(HAVE_X11_EXTENSIONS_XRES_H)
+# undef HAVE_XRES_EXT
+#endif
+
#ifndef PATH_ENV
# define PATH_ENV "ETERMPATH"
#endif