diff options
author | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-04-21 21:13:16 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-04-28 18:49:47 -0400 |
commit | 11fb62d5aa6304d1813b56a372b8b662f0016f92 (patch) | |
tree | 452aec56a94be4bf6a9987d7b86094d530fb7aac | |
parent | 1b89edb419ee103d0ef834433b16a3822398a519 (diff) |
Display _NET_WM_ICONs as ASCII art instead of as a big list of integers
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | dsimple.c | 12 | ||||
-rw-r--r-- | dsimple.h | 1 | ||||
-rw-r--r-- | xprop.c | 132 |
4 files changed, 144 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac index bba437b..6087c3b 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,7 @@ AC_PROG_INSTALL XORG_CWARNFLAGS -AC_CHECK_HEADERS([wchar.h wctype.h]) +AC_CHECK_HEADERS([wchar.h wctype.h langinfo.h]) # Checks for pkg-config packages PKG_CHECK_MODULES(XPROP, x11) @@ -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) @@ -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 **); @@ -45,6 +45,9 @@ from The Open Group. #include <wctype.h> #endif #include <locale.h> +#ifdef HAVE_LANGINFO_H +#include <langinfo.h> +#endif #ifndef HAVE_WCTYPE_H #define iswprint(x) isprint(x) @@ -416,6 +419,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 +744,113 @@ Format_Len_String (const char *string, int len) return result; } +static int +is_utf8_locale (void) +{ +#ifdef HAVE_LANGINFO_H + char *charmap = nl_langinfo (CODESET); + + return charmap && strcmp (charmap, "UTF-8") == 0; +#else + return 0; +#endif +} + +static const char * +Format_Icons (const unsigned long *icon, int len) +{ + char *result = NULL, *tail = NULL; + int alloced; + const unsigned long *end = icon + len / sizeof (unsigned long); + + alloced = 0; + + while (icon < end) + { + unsigned long width, height; + int w, h; + int offset; + + width = *icon++; + height = *icon++; + + offset = (tail - result); + + alloced += 80; /* For the header */ + alloced += (width*4 + 8) * height; /* For the rows (plus padding) */ + + result = Realloc (result, alloced); + tail = &result[offset]; + + 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 +970,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 +1225,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 +1257,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++; |