[PATCH] Display _NET_WM_ICONs as ASCII art instead of as a big list of integers

Aaron Plattner aplattner at nvidia.com
Tue Apr 28 14:00:50 PDT 2009


(gdb) r
Starting program: /home/aaron/X/modular/app/xprop/xprop -id 0x3812f78
_NET_WM_ICON_GEOMETRY(CARDINAL) = 1399, 1576, 195, 24
XKLAVIER_STATE(INTEGER) = 0, -11254624
_COMPIZ_WINDOW_DECOR(INTEGER) = 20080529, 26311442, 5, 5, 24, 5, 0, 0, 24, 1, 98, 0, 589925, -13, -32, -78, 0, 863, 32767, 0, 0, 524389, 850, -32, -78, 0, 32767, 32767, 863, 0, 590182, -78, -32, 15, 0, 93, 32767, 957, 0, 395413, -13, 0, 0, -497, 32767, 498, 1, 34, 264341, -13, 498, 0, -497, 32767, 32767, 499, 34, 395929, -13, -497, 0, 0, 32767, 497, 997, 34, 395430, 0, 0, 15, -497, 32767, 498, 1, 49, 264358, 0, 498, 15, -497, 32767, 32767, 499, 49, 395946, 0, -497, 15, 0, 32767, 497, 997, 49, 589993, -13, 0, -464, 15, 477, 32767, 0, 66, 524457, 464, 0, -464, 15, 32767, 32767, 477, 66, 590250, -464, 0, 15, 15, 479, 32767, 957, 66
WM_STATE(WM_STATE):
		window state: Normal
		icon window: 0x0
_NET_WM_DESKTOP(CARDINAL) = 0
_NET_FRAME_EXTENTS(CARDINAL) = 5, 5, 24, 5
_NET_FRAME_WINDOW(WINDOW): window id # 0x123edc7
WM_HINTS(WM_HINTS):
		Client accepts input or input focus: True
		Initial state is Normal State.
		bitmap id # to use for icon: 0x3800028
		bitmap id # of mask for icon: 0x380002b
		window id # of group leader: 0x3800002
_NET_STARTUP_ID(UTF8_STRING) = 0x67, 0x6e, 0x6f, 0x6d, 0x65, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2f, 0x67, 0x6e, 0x6f, 0x6d, 0x65, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x2f, 0x31, 0x32, 0x31, 0x31, 0x39, 0x2d, 0x36, 0x2d, 0x73, 0x6f, 0x70, 0x72, 0x61, 0x6e, 0x6f, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x38, 0x35, 0x30, 0x33, 0x34, 0x32, 0x37, 0x30
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_STICK, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_CHANGE_DESKTOP, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW
XdndAware(ATOM) = BITMAP
_MOTIF_DRAG_RECEIVER_INFO(_MOTIF_DRAG_RECEIVER_INFO) = 0x6c, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0

Program received signal SIGSEGV, Segmentation fault.
0x00007fcba7b661fd in _IO_default_xsputn () from /lib/libc.so.6
(gdb) bt
#0  0x00007fcba7b661fd in _IO_default_xsputn () from /lib/libc.so.6
#1  0x00007fcba7b35826 in vfprintf () from /lib/libc.so.6
#2  0x00007fcba7b5af49 in vsprintf () from /lib/libc.so.6
#3  0x00007fcba7b401d8 in sprintf () from /lib/libc.so.6
#4  0x0000000000403698 in Format_Icons (icon=0x1b6f0d0, len=37232) at xprop.c:781
#5  0x0000000000403d63 in Format_Thunk (t=
      {thunk_count = 1, propname = 0x402c14 "��UH\211�H\203�\020H\211}�H\211u�H\213U�H\213}���a@", value = 37232, extra_encoding = 4221316, extra_value = 0x1b65f50 "\026", format = 0x403be5 "H\213E�H\205�t1H\213E�H\203�\bt'H\213E�H\203�\020t\035H\213E�H\203� t\023H\213u��Qm@", dformat = 0x7fffb0609638 "\204i@"}, format_char=111 'o')
    at xprop.c:967
#6  0x0000000000403e1a in Format_Thunk_I (thunks=0x1b5ba60, format=0x406984 "32o", i=0) at xprop.c:979
#7  0x0000000000404008 in Handle_Dollar_sign (dformat=0x4061d2 "\n", thunks=0x1b5ba60, format=0x406984 "32o")
    at xprop.c:1054
#8  0x00000000004043b9 in Display_Property (thunks=0x1b5ba60, dformat=0x4061d0 "0+\n", format=0x406984 "32o")
    at xprop.c:1155
#9  0x0000000000404afc in Show_Prop (format=0x406984 "32o", dformat=0x4061cc " = $0+\n", 
    prop=0x406977 "_NET_WM_ICON") at xprop.c:1385
#10 0x0000000000404b63 in Show_All_Props () at xprop.c:1399
#11 0x0000000000404beb in Handle_Prop_Requests (argc=0, argv=0x7fffb0609a20) at xprop.c:1417
#12 0x0000000000405d3e in main (argc=0, argv=0x7fffb0609a20) at xprop.c:1874


On Tue, Apr 28, 2009 at 01:29:38PM -0700, Soeren Sandmann wrote:
> ---
>  Makefile.am |    2 +-
>  dsimple.c   |   12 +++++-
>  dsimple.h   |    1 +
>  xprop.c     |  125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  4 files changed, 137 insertions(+), 3 deletions(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index 454ab86..2913783 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -22,7 +22,7 @@
>  bin_PROGRAMS = xprop
>  
>  AM_CFLAGS = $(XPROP_CFLAGS)
> -xprop_LDADD = $(XPROP_LIBS)
> +xprop_LDADD = $(XPROP_LIBS) -lm
>  
>  xprop_SOURCES =	\
>          dsimple.c \
> diff --git a/dsimple.c b/dsimple.c
> index 4bd4837..cd08d7c 100644
> --- a/dsimple.c
> +++ b/dsimple.c
> @@ -72,7 +72,17 @@ char *Malloc(unsigned size)
>  
>  	return(data);
>  }
> -	
> +
> +/*
> + * Realloc: like realloc but handles out of memory using Fatal_Error:
> + */
> +char *Realloc(char *mem, unsigned size)
> +{
> +    if (!(mem = realloc (mem, size)))
> +	Fatal_Error("Out of memory!");
> +
> +    return mem;
> +}
>  
>  /*
>   * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete)
> diff --git a/dsimple.h b/dsimple.h
> index 7557571..1c09c9d 100644
> --- a/dsimple.h
> +++ b/dsimple.h
> @@ -59,6 +59,7 @@ extern int screen;                           /* The current screen */
>      /* Declarations for functions in just_display.c */
>  
>  char *Malloc(unsigned);
> +char *Realloc(char *,unsigned);
>  char *Get_Display_Name(int *, char **);
>  Display *Open_Display(const char *);
>  void Setup_Display_And_Screen(int *, char **);
> diff --git a/xprop.c b/xprop.c
> index 73a9db8..9152aec 100644
> --- a/xprop.c
> +++ b/xprop.c
> @@ -416,6 +416,7 @@ static propertyRec windowPropTable[] = {
>      {"WM_NAME",		XA_WM_NAME,	 "8t",	      0 },
>      {"WM_PROTOCOLS",		0,	 "32a",	      ": protocols  $0+\n"},
>      {"WM_SIZE_HINTS",	XA_WM_SIZE_HINTS,"32mii",     WM_SIZE_HINTS_DFORMAT },
> +    {"_NET_WM_ICON",            0,       "32o",        0 },
>      {"WM_STATE",		0,	 "32cx",      WM_STATE_DFORMAT}
>  };
>  #undef ARC_DFORMAT
> @@ -740,6 +741,109 @@ Format_Len_String (const char *string, int len)
>      return result;
>  }  
>  
> +static int
> +is_utf8_locale (void)
> +{
> +    char *locale = getenv ("LANG");
> +
> +    return locale && strstr (locale, "UTF-8");
> +}
> +
> +static const char *
> +Format_Icons (const unsigned long *icon, int len)
> +{
> +    char *result = NULL, *tail = NULL;
> +    int alloced;
> +    const unsigned long *end = icon + len / 4;
> +
> +    alloced = 0;
> +
> +    while (icon < end)
> +    {
> +	unsigned long width, height;
> +	int w, h;
> +
> +	width = *icon++;
> +	height = *icon++;
> +
> +	tail = (char *)(tail - result);
> +	
> +	alloced += 80;				/* For the header */
> +	alloced += (width*4 + 8) * height;		/* For the rows (plus padding) */
> +	
> +
> +	result = Realloc (result, alloced);
> +	tail += (unsigned)result;
> +
> +	if (end - icon < width * height)
> +	    break;
> +
> +	tail += sprintf (tail, "\tIcon (%lu x %lu):\n", width, height);
> +
> +	if (width > 144 || height > 144)
> +	{
> +	    tail += sprintf (tail, "\t(not shown)");
> +	    icon += width * height;
> +	    continue;
> +	}
> +	
> +	for (h = 0; h < height; ++h)
> +	{
> +	    tail += sprintf (tail, "\t");
> +	    
> +	    for (w = 0; w < width; ++w)
> +	    {
> +		unsigned char a, r, g, b;
> +		unsigned long pixel = *icon++;
> +		unsigned long brightness;
> +		
> +		a = (pixel & 0xff000000) >> 24;
> +		r = (pixel & 0x00ff0000) >> 16;
> +		g = (pixel & 0x0000ff00) >> 8;
> +		b = (pixel & 0x000000ff);
> +		
> +		brightness =
> +		    (a / 255.0) * (1000 - ((299 * (r / 255.0)) +
> +					   (587 * (g / 255.0)) +
> +					   (114 * (b / 255.0))));
> +
> +		if (is_utf8_locale())
> +		{
> +		    static const char palette[][4] =
> +		    {
> +			" ",
> +			"\342\226\221",		/* 25% */
> +			"\342\226\222",		/* 50% */
> +			"\342\226\223",		/* 75% */
> +			"\342\226\210",		/* 100% */
> +		    };
> +		    int idx;
> +
> +		    idx = (brightness * ((sizeof (palette)/sizeof(palette[0])) - 1)) / 1000;
> +
> +		    tail += sprintf (tail, "%s", palette[idx]);
> +		}
> +		else
> +		{
> +		    static const char palette[] =
> +			" .'`,^:\";~-_+<>i!lI?/\\|()1{}[]rcvunxzjftLCJUYXZO0Qoahkbdpqwm*WMB8&%$#@";
> +		    int idx;
> +		    
> +		    idx = (brightness * (sizeof(palette) - 2)) / 1000;
> +		    
> +		    *tail++ = palette[idx];
> +		}
> +	    }
> +
> +	    tail += sprintf (tail, "\n");
> +	}
> +
> +	tail += sprintf (tail, "\n");
> +    }
> +
> +    return result;
> +}
> +
>  static const char *
>  Format_Len_Text (const char *string, int len, Atom encoding)
>  {
> @@ -859,6 +963,8 @@ Format_Thunk (thunk t, char format_char)
>  	return Format_Mask_Word(value);
>        case 'a':
>  	return Format_Atom(value);
> +      case 'o':
> +	return Format_Icons((const unsigned long *)t.extra_value, (int)t.value);
>        default:
>  	Fatal_Error("bad format character: %c", format_char);
>      }
> @@ -1112,6 +1218,20 @@ Extract_Len_String (const char **pointer, int *length, int size, const char **st
>      return len;
>  }
>  
> +static long
> +Extract_Icon (const char **pointer, int *length, int size, const char **icon)
> +{
> +    int len = 0;
> +
> +    if (size != 32)
> +	Fatal_Error("can't use format character 'o' with any size except 32.");
> +
> +    len = *length;
> +    *icon = *pointer;
> +    *length = 0;
> +    return len;
> +}
> +
>  static thunk *
>  Break_Down_Property (const char *pointer, int length, Atom type, const char *format, int size)
>  {
> @@ -1130,7 +1250,10 @@ Break_Down_Property (const char *pointer, int length, Atom type, const char *for
>  	else if (format_char == 't') {
>  	    t.extra_encoding = type;
>  	    t.value = Extract_Len_String(&pointer,&length,size,&t.extra_value);
> -	} else
> +	}
> +	else if (format_char == 'o')
> +	    t.value = Extract_Icon (&pointer,&length,size,&t.extra_value);
> +	else
>  	    t.value = Extract_Value(&pointer,&length,size,format_char=='i');
>  	thunks = Add_Thunk(thunks, t);
>  	i++;
> -- 
> 1.6.2.2
> 
> _______________________________________________
> xorg-devel mailing list
> xorg-devel at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-devel
> 


More information about the xorg-devel mailing list