/** * Copyright (C) 2004 Billy Biggs . * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * 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 AUTHORS OR COPYRIGHT HOLDERS * 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. */ #include #include #include #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef ENABLE_NLS # define _(string) gettext (string) # include "gettext.h" #else # define _(string) string #endif #include #include "xresview.h" static Atom wm_state; static Atom res_pixmap; static Atom res_window; static Atom res_gc; static Atom res_font; static Atom res_glyphset; static Atom res_picture; static Atom res_cursor; static Atom res_colormap_entry; static Atom res_passive_grab; static int atoms_loaded = 0; /** * Cache every atom we need. This minimizes round trips to the server. * The number of atoms and their position is hardcoded, but it's small. * Making this look pretty I think would be too annoying to be worth it. */ static void load_atoms( Display *dpy ) { static char *atom_names[] = { "WM_STATE", "PIXMAP", "WINDOW", "GC", "FONT", "PICTURE", "CURSOR", "GLYPHSET", "COLORMAP_ENTRY", "PASSIVE_GRAB" }; Atom atoms_return[ 10 ]; if( atoms_loaded ) return; XInternAtoms( dpy, atom_names, 10, False, atoms_return ); wm_state = atoms_return[ 0 ]; res_pixmap = atoms_return[ 1 ]; res_window = atoms_return[ 2 ]; res_gc = atoms_return[ 3 ]; res_font = atoms_return[ 4 ]; res_picture = atoms_return[ 5 ]; res_cursor = atoms_return[ 6 ]; res_glyphset = atoms_return[ 7 ]; res_colormap_entry = atoms_return[ 8 ]; res_passive_grab = atoms_return[ 9 ]; atoms_loaded = 1; } struct xresview_s { GtkWidget *scrolled; GtkWidget *main; GtkWidget *name; GtkWidget *pixmap_bytes; GtkWidget *pixmaps; GtkWidget *windows; GtkWidget *glyphsets; GtkWidget *gcs; GtkWidget *fonts; GtkWidget *pictures; GtkWidget *pgrabs; GtkWidget *colormaps; GtkWidget *cursors; XResClient *clients; int numclients; }; xresview_t *xresview_new( void ) { xresview_t *rv = malloc( sizeof( xresview_t ) ); GtkWidget *vbox; GtkWidget *table; GtkWidget *label; GtkWidget *align; int row = 0; rv->clients = 0; vbox = gtk_vbox_new( FALSE, 2 ); align = gtk_alignment_new( 0.5, 0.0, 0.95, 0.0 ); table = gtk_table_new( 1, 2, FALSE ); gtk_container_add( GTK_CONTAINER( align ), table ); gtk_box_pack_start( GTK_BOX( vbox ), align, TRUE, TRUE, 2 ); /* label = gtk_label_new( "Name:" ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->name = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->name ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->name, 1, 2, row, row + 1 ); row++; */ label = gtk_label_new( _("Pixmaps:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->pixmaps = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->pixmaps ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->pixmaps, 1, 2, row, row + 1 ); row++; label = gtk_label_new( _("Pixmap Bytes:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->pixmap_bytes = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->pixmap_bytes ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->pixmap_bytes, 1, 2, row, row + 1 ); row++; label = gtk_label_new( _("Windows:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->windows = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->windows ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->windows, 1, 2, row, row + 1 ); row++; label = gtk_label_new( _("Cursors:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->cursors = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->cursors ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->cursors, 1, 2, row, row + 1 ); row++; label = gtk_label_new( _("Graphics Contexts:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->gcs = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->gcs ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->gcs, 1, 2, row, row + 1 ); row++; label = gtk_label_new( _("Fonts:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->fonts = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->fonts ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->fonts, 1, 2, row, row + 1 ); row++; label = gtk_label_new( _("Pictures:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->pictures = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->pictures ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->pictures, 1, 2, row, row + 1 ); row++; label = gtk_label_new( _("Glyphsets:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->glyphsets = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->glyphsets ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->glyphsets, 1, 2, row, row + 1 ); row++; label = gtk_label_new( _("Colormap Entries:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->colormaps = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->colormaps ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->colormaps, 1, 2, row, row + 1 ); row++; label = gtk_label_new( _("Passive Grabs:") ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0 ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row + 1, GTK_SHRINK, GTK_SHRINK, 2, 2 ); rv->pgrabs = gtk_entry_new(); gtk_entry_set_editable( GTK_ENTRY( rv->pgrabs ), FALSE ); gtk_table_attach_defaults( GTK_TABLE( table ), rv->pgrabs, 1, 2, row, row + 1 ); row++; rv->main = vbox; return rv; } void xresview_delete( xresview_t *rv ) { free( rv ); } void xresview_clear( xresview_t *rv, Display *dpy, Window root ) { gtk_entry_set_text( GTK_ENTRY( rv->pixmaps ), "" ); gtk_entry_set_text( GTK_ENTRY( rv->pixmap_bytes ), "" ); gtk_entry_set_text( GTK_ENTRY( rv->windows ), "" ); gtk_entry_set_text( GTK_ENTRY( rv->gcs ), "" ); gtk_entry_set_text( GTK_ENTRY( rv->fonts ), "" ); gtk_entry_set_text( GTK_ENTRY( rv->pictures ), "" ); gtk_entry_set_text( GTK_ENTRY( rv->glyphsets ), "" ); gtk_entry_set_text( GTK_ENTRY( rv->cursors ), "" ); gtk_entry_set_text( GTK_ENTRY( rv->colormaps ), "" ); gtk_entry_set_text( GTK_ENTRY( rv->pgrabs ), "" ); if( rv->clients ) { XFree( rv->clients ); } XResQueryClients( dpy, &rv->numclients, &rv->clients ); } static int is_application_window( Display *dpy, Window win ) { Atom type_return; int format_return; unsigned long bytes_after_return; unsigned long nitems_return; unsigned char *prop_return = 0; if( XGetWindowProperty( dpy, win, wm_state, 0, 4, False, AnyPropertyType, &type_return, &format_return, &nitems_return, &bytes_after_return, &prop_return ) != Success ) { return 0; } if( nitems_return ) { XFree( prop_return ); } if( !type_return ) { return 0; } return 1; } void xresview_load( xresview_t *rv, Display *dpy, Window win, Window root ) { Atom type_return; int format_return; unsigned long bytes_after_return; unsigned long nitems_return; unsigned char *prop_return = 0; int i; load_atoms( dpy ); if( !is_application_window( dpy, win ) ) { return; } for( i = 0; i < rv->numclients; i++ ) { unsigned int match_xid; match_xid = (rv->clients[ i ].resource_base & ~rv->clients[ i ].resource_mask); if( (win & ~rv->clients[ i ].resource_mask) == match_xid ) { XResType *types; char text[ 256 ]; unsigned long bytes; int numtypes; int j; XResQueryClientPixmapBytes( dpy, win, &bytes ); sprintf( text, "%ld", bytes ); gtk_entry_set_text( GTK_ENTRY( rv->pixmap_bytes ), text ); XResQueryClientResources( dpy, win, &numtypes, &types ); for( j = 0; j < numtypes; j++ ) { if( types[ j ].resource_type == res_pixmap ) { sprintf( text, "%u", types[ j ].count ); gtk_entry_set_text( GTK_ENTRY( rv->pixmaps ), text ); } else if( types[ j ].resource_type == res_window ) { sprintf( text, "%u", types[ j ].count ); gtk_entry_set_text( GTK_ENTRY( rv->windows ), text ); } else if( types[ j ].resource_type == res_gc ) { sprintf( text, "%u", types[ j ].count ); gtk_entry_set_text( GTK_ENTRY( rv->gcs ), text ); } else if( types[ j ].resource_type == res_font ) { sprintf( text, "%u", types[ j ].count ); gtk_entry_set_text( GTK_ENTRY( rv->fonts ), text ); } else if( types[ j ].resource_type == res_picture ) { sprintf( text, "%u", types[ j ].count ); gtk_entry_set_text( GTK_ENTRY( rv->pictures ), text ); } else if( types[ j ].resource_type == res_glyphset ) { sprintf( text, "%u", types[ j ].count ); gtk_entry_set_text( GTK_ENTRY( rv->glyphsets ), text ); } else if( types[ j ].resource_type == res_colormap_entry ) { sprintf( text, "%u", types[ j ].count ); gtk_entry_set_text( GTK_ENTRY( rv->colormaps ), text ); } else if( types[ j ].resource_type == res_passive_grab ) { sprintf( text, "%u", types[ j ].count ); gtk_entry_set_text( GTK_ENTRY( rv->pgrabs ), text ); } else if( types[ j ].resource_type == res_cursor ) { sprintf( text, "%u", types[ j ].count ); gtk_entry_set_text( GTK_ENTRY( rv->cursors ), text ); } } if( numtypes ) { XFree( types ); } return; } } } GtkWidget *xresview_get_widget( xresview_t *rv ) { return rv->main; }