Use GString for appending strings
[dana/openbox.git] / tools / obxprop / obxprop.c
index 6ea8a4d..1f6e353 100644 (file)
@@ -12,7 +12,7 @@ gint fail(const gchar *s) {
     else
         fprintf
             (stderr,
-             "Usage: obxprop [OPTIONS]\n\n"
+             "Usage: obxprop [OPTIONS] [--] [PROPERTIES ...]\n\n"
              "Options:\n"
              "    --help              Display this help and exit\n"
              "    --display DISPLAY   Connect to this X display\n"
@@ -28,14 +28,15 @@ gint parse_hex(gchar *s) {
         if (*s >= '0' && *s <='9')
             add = *s-'0';
         else if (*s >= 'A' && *s <='F')
-            add = *s-'A';
+            add = *s-'A'+10;
         else if (*s >= 'a' && *s <='f')
-            add = *s-'a';
+            add = *s-'a'+10;
         else
             break;
 
         result *= 16;
         result += add;
+        ++s;
     }
     return result;
 }
@@ -97,41 +98,38 @@ static gboolean get_all(Display *d, Window win, Atom prop,
                 default:
                     g_assert_not_reached(); /* unhandled size */
                 }
-            *num = ret_items;
-            ret = TRUE;
         }
+        *num = ret_items;
+        ret = TRUE;
         XFree(xdata);
     }
     return ret;
 }
 
-gchar *append_string(gchar *before, gchar *after, gboolean quote)
+GString *append_string(GString *before, gchar *after, gboolean quote)
 {
-    gchar *tmp;
     const gchar *q = quote ? "\"" : "";
     if (before)
-        tmp = g_strdup_printf("%s, %s%s%s", before, q, after, q);
+        g_string_append_printf(before, ", %s%s%s", q, after, q);
     else
-        tmp = g_strdup_printf("%s%s%s", q, after, q);
-    g_free(before);
-    return tmp;
+        g_string_append_printf(before = g_string_new(NULL), "%s%s%s", q, after, q);
+    return before;
 }
 
-gchar *append_int(gchar *before, guint after)
+GString *append_int(GString *before, guint after)
 {
-    gchar *tmp;
     if (before)
-        tmp = g_strdup_printf("%s, %u", before, after);
+        g_string_append_printf(before, ", %u", after);
     else
-        tmp = g_strdup_printf("%u", after);
-    g_free(before);
-    return tmp;
+        g_string_append_printf(before = g_string_new(NULL), "%u", after);
+    return before;
 }
 
 gchar* read_strings(gchar *val, guint n, gboolean utf8)
 {
     GSList *strs = NULL, *it;
-    gchar *ret, *p;
+    GString *ret;
+    gchar *p;
     guint i;
 
     p = val;
@@ -161,23 +159,27 @@ gchar* read_strings(gchar *val, guint n, gboolean utf8)
         g_free(strs->data);
         strs = g_slist_delete_link(strs, strs);
     }
-    return ret;
+    if (ret)
+        return g_string_free(ret, FALSE);
+    return NULL;
 }
 
 gchar* read_atoms(Display *d, guchar *val, guint n)
 {
-    gchar *ret;
+    GString *ret;
     guint i;
 
     ret = NULL;
     for (i = 0; i < n; ++i)
         ret = append_string(ret, XGetAtomName(d, ((guint32*)val)[i]), FALSE);
-    return ret;
+    if (ret)
+        return g_string_free(ret, FALSE);
+    return NULL;
 }
 
 gchar* read_numbers(guchar *val, guint n, guint size)
 {
-    gchar *ret;
+    GString *ret;
     guint i;
 
     ret = NULL;
@@ -196,7 +198,9 @@ gchar* read_numbers(guchar *val, guint n, guint size)
             g_assert_not_reached(); /* unhandled size */
         }
 
-    return ret;
+    if (ret)
+        return g_string_free(ret, FALSE);
+    return NULL;
 }
 
 gboolean read_prop(Display *d, Window w, Atom prop, const gchar **type, gchar **val)
@@ -227,7 +231,7 @@ gboolean read_prop(Display *d, Window w, Atom prop, const gchar **type, gchar **
     return FALSE;
 }
 
-void show_properties(Display *d, Window w)
+void show_properties(Display *d, Window w, int argc, char **argv)
 {
     Atom* props;
     int i, n;
@@ -241,7 +245,19 @@ void show_properties(Display *d, Window w)
         name = XGetAtomName(d, props[i]);
 
         if (read_prop(d, w, props[i], &type, &val)) {
-            g_print("%s(%s) = %s\n", name, type, val);
+            int found = 1;
+            if (argc) {
+                int i;
+
+                found = 0;
+                for (i = 0; i < argc; i++)
+                    if (!strcmp(name, argv[i])) {
+                        found = 1;
+                        break;
+                    }
+            }
+            if (found)
+                g_print("%s(%s) = %s\n", name, type, (val ? val : ""));
             g_free(val);
         }
 
@@ -261,13 +277,13 @@ int main(int argc, char **argv)
 
     for (i = 1; i < argc; ++i) {
         if (!strcmp(argv[i], "--help")) {
-            return fail(0);
+            return fail(NULL);
         }
         else if (!strcmp(argv[i], "--root"))
             root = TRUE;
         else if (!strcmp(argv[i], "--id")) {
             if (++i == argc)
-                return fail(0);
+                return fail(NULL);
             if (argv[i][0] == '0' && argv[i][1] == 'x') {
                 /* hex */
                 userid = parse_hex(argv[i]+2);
@@ -276,13 +292,22 @@ int main(int argc, char **argv)
                 /* decimal */
                 userid = atoi(argv[i]);
             }
-            break;
+            if (!userid)
+                return fail("Unable to parse argument to --id.");
         }
         else if (!strcmp(argv[i], "--display")) {
             if (++i == argc)
-                return fail(0);
+                return fail(NULL);
             dname = argv[i];
         }
+        else if (*argv[i] != '-')
+            break;
+        else if (!strcmp(argv[i], "--")) {
+            i++;
+            break;
+        }
+        else
+            return fail(NULL);
     }
 
     d = XOpenDisplay(dname);
@@ -295,12 +320,13 @@ int main(int argc, char **argv)
         userid = RootWindow(d, DefaultScreen(d));
 
     if (userid == None) {
-        i = XGrabPointer(d, RootWindow(d, DefaultScreen(d)),
+        int j;
+        j = XGrabPointer(d, RootWindow(d, DefaultScreen(d)),
                          False, ButtonPressMask,
                          GrabModeAsync, GrabModeAsync,
                          None, XCreateFontCursor(d, XC_crosshair),
                          CurrentTime);
-        if (i != GrabSuccess)
+        if (j != GrabSuccess)
             return fail("Unable to grab the pointer device");
         while (1) {
             XEvent ev;
@@ -312,14 +338,15 @@ int main(int argc, char **argv)
                 break;
             }
         }
+        id = find_client(d, userid);
     }
-
-    id = find_client(d, userid);
+    else
+        id = userid; /* they picked this one */
 
     if (id == None)
         return fail("Unable to find window with the requested ID");
 
-    show_properties(d, id);
+    show_properties(d, id, argc - i, &argv[i]);
     
     XCloseDisplay(d);