From e39e3f1ce9ecde39c96aa67113130d23c002dca3 Mon Sep 17 00:00:00 2001 From: Michael Jennings Date: Wed, 4 Jan 2006 08:44:14 +0000 Subject: [PATCH] Wed Jan 4 03:44:04 2006 Michael Jennings (mej) X resource tracking/debugging support. ---------------------------------------------------------------------- SVN revision: 19520 --- ChangeLog | 4 ++ configure.in | 28 ++++++++++-- src/command.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/feature.h | 4 ++ 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 +#endif +#ifdef HAVE_X11_XLIB_H +# include +#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 #include #include +#ifdef HAVE_XRES_EXT +# include +#endif #ifdef PTY_GRP_NAME # include #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