Merge "test : enhance accessible state information" into tizen
[platform/upstream/at-spi2-core.git] / test / at_spi2_tool.c
index 7a7b9a5..81bf021 100644 (file)
@@ -4,9 +4,12 @@
 #include <string.h>
 #include <getopt.h>
 #include <stdbool.h>
+#include <gio/gio.h>
+#include <assert.h>
+#include <stdint.h>
 
 #define ERROR_STATE -1
-#define SAFE_BUFFER_SIZE 255
+#define SAFE_BUFFER_SIZE 2048
 #define CHECK_OUTPUT_WIDTH 42
 #define MINIMAL_MODULE_WIDTH 3
 #define ATTR_WIDTH 50
 #define DUMP 0
 #define CHECK 1
 #define FIRST_MATCH 2
+#define RELATION_TABLE_COLUMN_COUNT 7
+#define ATTRIBUTE_TABLE_COLUMN_COUNT 3
+#define RELATION_TABLE_COLUMN_WIDTH 20
+#define ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH 20
 #define VERSION "1.1"
 
 static unsigned indent_width = 2;
@@ -79,12 +86,6 @@ typedef struct _Box_Size {
        char *width;
 } Box_Size;
 
-char *_strdup(const char *c)
-{
-       char *result = (char *)calloc(1, strlen(c) + 1);
-       return result ? strcpy(result, c) : result;
-}
-
 static char *_multiply_string(char c, unsigned number)
 {
        char *result = (char *)calloc(1, number + 1);
@@ -99,7 +100,7 @@ static char *_multiply_string(char c, unsigned number)
 
 static void _print_module_legend()
 {
-       printf("\n[[node role name],[attributes list],[x,y,width,height],[node name],[states list]]\n\n");
+       printf("\n[[node],[node role name],[attributes list],[x,y,width,height],[node name],[states list][relations]\n\n");
 }
 
 static void _print_atspi_states_legend()
@@ -236,33 +237,38 @@ static Box_Size *_get_box_size(AtspiAccessible *node)
        return box_size;
 }
 
-static char *_get_states(AtspiAccessible *node)
+static char *_get_states(AtspiAccessible *node, int length_limit)
 {
        AtspiStateSet *node_state_set = atspi_accessible_get_state_set(node);
        GArray *states = atspi_state_set_get_states(node_state_set);
+       if (!states) return NULL;
        g_array_sort(states, _int_sort_function);
 
        AtspiStateType state_type;
        char *state_string = NULL;
 
-       for (int i = 0; states && (i < states->len); i++) {
+       for (int i = 0; i < states->len; i++) {
                state_type = g_array_index(states, AtspiStateType, i);
 
-               char node_state_str[8];
-               sprintf(node_state_str, "(%d)", state_type);
+               char node_state_str[27] = "";
+               strncat(node_state_str, "(", sizeof(node_state_str) - strlen(node_state_str) - 1);
+               strncat(node_state_str, atspi_state_names[state_type], sizeof(node_state_str) - strlen(node_state_str) - 1);
+               strncat(node_state_str, ")", sizeof(node_state_str) - strlen(node_state_str) - 1);
+
                _combine_strings(&state_string, node_state_str);
        }
 
        g_array_free(states, 0);
        g_object_unref(node_state_set);
 
+       _truncate_string(state_string, length_limit);
+
        return state_string;
 }
 
-static char *_get_attributes(AtspiAccessible *node)
+static char *_get_attributes(AtspiAccessible *node, int length_limit, bool *attributes_are_too_long)
 {
-       GHashTable *attributes = NULL;
-       attributes = atspi_accessible_get_attributes(node, NULL);
+       GHashTable *attributes = atspi_accessible_get_attributes(node, NULL);
 
        if (!attributes)
                return NULL;
@@ -273,51 +279,65 @@ static char *_get_attributes(AtspiAccessible *node)
        g_hash_table_iter_init (&attributes_iter, attributes);
        char *result = NULL;
        while (g_hash_table_iter_next (&attributes_iter, &attr_key, &attr_value)) {
-               char attributes_string[ATTR_WIDTH];
-               int ret = snprintf(attributes_string, ATTR_WIDTH, "(%s=%s)", (char*)attr_key, (char*)attr_value);
-               if (ret >= ATTR_WIDTH) {
-                       fprintf(stderr, "_get_attributes: generated string is too long. Buffer overflow");
-                       abort();
-               }
+               char attributes_string[SAFE_BUFFER_SIZE];
+               int ret = snprintf(attributes_string, SAFE_BUFFER_SIZE, "(%s=%s)", (char *)attr_key, (char *)attr_value);
+               if (ret >= SAFE_BUFFER_SIZE)
+                       fprintf(stderr, "\n%s, %s %d: generated string is too long. Buffer overflow\n", __FILE__, __FUNCTION__, __LINE__);
+
                _combine_strings(&result, attributes_string);
        }
        g_hash_table_unref(attributes);
 
+       int real_truncate_size = (length_limit < ATTR_WIDTH && length_limit > MINIMAL_MODULE_WIDTH) ? length_limit : ATTR_WIDTH;
+       if (result && attributes_are_too_long && strlen(result) > real_truncate_size)
+               *attributes_are_too_long = true;
+
+       _truncate_string(result, real_truncate_size);
        return result;
 }
 
-static char *_get_info(AtspiAccessible *node, int length_limit)
+static char *_get_info(AtspiAccessible *node, int length_limit, bool *attributes_are_too_long, bool *app_has_relations)
 {
        if (!node)
                return NULL;
 
        char *node_name = atspi_accessible_get_name(node, NULL);
        char *node_role_name = atspi_accessible_get_role_name(node, NULL);
+       char *unique_id = atspi_accessible_get_unique_id(node, NULL);
+       char *path = atspi_accessible_get_path(node, NULL);
+       unsigned long long eo_ptr = 0;
+       sscanf(path, "%llu", &eo_ptr);
 
-       char *attributes = _get_attributes(node);
-       _truncate_string(attributes, length_limit);
+       char *attributes = _get_attributes(node, length_limit, attributes_are_too_long);
        Box_Size *box_size = _get_box_size(node);
-       char *states = _get_states(node);
-       _truncate_string(states, length_limit);
+       char *states = _get_states(node, length_limit);
+
+       GArray *relations = atspi_accessible_get_relation_set(node, NULL);
+       bool current_node_has_relations = (relations && relations->len);
 
        char result[SAFE_BUFFER_SIZE];
-       int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s],[%s],[%s,%s,%s,%s],[%s],[%s]]",
-                                                                               node_role_name,
-                                                                               attributes,
-                                                                               box_size->x,
-                                                                               box_size->y,
-                                                                               box_size->width,
-                                                                               box_size->height,
-                                                                               node_name,
-                                                                               states);
-
-       if (ret >= SAFE_BUFFER_SIZE) {
-               fprintf(stderr, "_get_info: generated string is too long. Buffer overflow");
-               abort();
-       }
+       int ret = snprintf(result, SAFE_BUFFER_SIZE, "[[%s(%p)],[%s],[%s],[%s,%s,%s,%s],[%s],[%s],[%s]]",
+                                               unique_id, (uintptr_t)eo_ptr,
+                                               node_role_name,
+                                               attributes,
+                                               box_size->x,
+                                               box_size->y,
+                                               box_size->width,
+                                               box_size->height,
+                                               node_name,
+                                               states,
+                                               current_node_has_relations ? "*" : "");
+
+       if (ret >= SAFE_BUFFER_SIZE)
+               fprintf(stderr, "\n%s, %s %d: generated string is too long. Buffer overflow\n", __FILE__, __FUNCTION__, __LINE__);
+
+       if (current_node_has_relations)
+               *app_has_relations = true;
 
        free(node_name);
        free(node_role_name);
+       free(unique_id);
+       free(path);
        free(attributes);
        if (box_size) {
                free(box_size->width);
@@ -325,8 +345,9 @@ static char *_get_info(AtspiAccessible *node, int length_limit)
                free(box_size);
        }
        free(states);
+       g_array_free(relations, TRUE);
 
-       return _strdup(result);
+       return g_strdup(result);
 }
 
 static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessible *parent_candidate, int parent_candidate_index)
@@ -339,11 +360,16 @@ static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessi
                char parent_status[NUMBER_WIDTH];
 
                if (parent == NULL)
-                       strcpy(parent_status, "_");
+                       strncpy(parent_status, "_", NUMBER_WIDTH);
                else
                        snprintf(parent_status, NUMBER_WIDTH, "%d", parent_index);
 
-               snprintf(output, CHECK_OUTPUT_WIDTH, "[FAIL<%d,%s><%p,%p>]", parent_candidate_index, parent_status, parent_candidate, parent);
+               char *parent_unique_id = atspi_accessible_get_unique_id(parent, NULL);
+               char *parent_candidate_unique_id = atspi_accessible_get_unique_id(parent_candidate, NULL);
+               snprintf(output, CHECK_OUTPUT_WIDTH, "[FAIL<%d,%s><%s,%s>]", parent_candidate_index, parent_status,
+                               parent_candidate_unique_id, parent_unique_id);
+               free(parent_unique_id);
+               free(parent_candidate_unique_id);
 
        } else {
                snprintf(output, CHECK_OUTPUT_WIDTH, "[OK]");
@@ -352,7 +378,8 @@ static void _test_atspi_parent_child_relation(AtspiAccessible *obj, AtspiAccessi
        printf("%-*s\t", CHECK_OUTPUT_WIDTH, output);
 }
 
-static int _print_atspi_tree_verify_maybe_r(int indent_number, AtspiAccessible *object, bool check_integrity, int length_limit)
+static int _print_atspi_tree_verify_maybe_r(int indent_number, AtspiAccessible *object, bool check_integrity, int length_limit,
+                                                                                       bool *attributes_are_too_long, bool *app_has_relations)
 {
        char *indent = _multiply_string(' ', indent_number*indent_width);
        if (indent != NULL) {
@@ -360,7 +387,7 @@ static int _print_atspi_tree_verify_maybe_r(int indent_number, AtspiAccessible *
                free(indent);
        }
 
-       char *node_info = _get_info(object, length_limit);
+       char *node_info = _get_info(object, length_limit, attributes_are_too_long, app_has_relations);
        if (node_info != NULL) {
                printf("%s\n", node_info);
                free(node_info);
@@ -373,7 +400,7 @@ static int _print_atspi_tree_verify_maybe_r(int indent_number, AtspiAccessible *
                        if (check_integrity)
                                _test_atspi_parent_child_relation(child, object, i);
 
-                       _print_atspi_tree_verify_maybe_r(indent_number + 1, child, check_integrity, length_limit);
+                       _print_atspi_tree_verify_maybe_r(indent_number + 1, child, check_integrity, length_limit, attributes_are_too_long, app_has_relations);
                }
        }
        return 0;
@@ -388,6 +415,8 @@ void _print_help()
        printf("-v, --version\t\tshow actual version of tool\n");
        printf("-g, --show-legend\tprint AT-SPI state legend\n");
        printf("-l, --list-apps\t\tlist all applications of desktop\n");
+       printf("-a, --at-spi-client <true|false>\tenable/disable org.a11y.Status.IsEnabled property\n");
+       printf("-s, --sleep <N>\tsleep N seconds\n");
        printf("-d, --tree-dump\t\tdump tree for selected application\n");
        printf("-c, --tree-check\tcheck tree for selected application\n");
        printf("-f, --first-match\tperform dump or check only for first matching application\n");
@@ -399,55 +428,288 @@ void _print_help()
        printf("\tat_spi2_tool -i1 -c starter\n");
        printf("\t  show AT-SPI tree with integrity test for node \"starter\" using one-space indentation\n");
 }
+
 void _print_version()
 {
        printf("AT-SPI2-CORE-UTIL v%s\n", VERSION);
 }
 
-static void _atspi_tree_traverse(AtspiAccessible *desktop, const char *app_name, bool dump, bool check, bool first_match, int length_limit)
+static void _print_horizontal_line_in_relations_table() {
+       for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) {
+               for (int j = 0; j < RELATION_TABLE_COLUMN_WIDTH; j++)
+                       printf("-");
+               printf("+");
+       }
+       printf("\n");
+}
+
+static char *_get_unique_id_of_object_in_relation(AtspiRelation *relation) {
+       if (!relation)
+               return NULL;
+
+       gint last_index = atspi_relation_get_n_targets(relation) - 1;
+       AtspiAccessible *target = atspi_relation_get_target(relation, last_index);
+       return atspi_accessible_get_unique_id(target, NULL);
+}
+
+static void _print_relations_for_object(AtspiAccessible *node) {
+       GArray *relations = atspi_accessible_get_relation_set(node, NULL);
+       if (!relations)
+               return;
+
+       if (!relations->len) {
+               g_array_free(relations, FALSE);
+               return;
+       }
+
+       char **table = calloc(RELATION_TABLE_COLUMN_COUNT, sizeof(char *));
+       if (!table) {
+               fprintf(stderr, "Calloc failed. Can't alloc memory for object relations string\n");
+               return;
+       }
+
+       table[0] = atspi_accessible_get_unique_id(node, NULL);
+       for (int i = 0; i < relations->len; i++) {
+               AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i);
+               AtspiRelationType type = atspi_relation_get_relation_type(relation);
+               int idx;
+               switch (type) {
+                       case ATSPI_RELATION_CONTROLLER_FOR:     idx = 1; break;
+                       case ATSPI_RELATION_CONTROLLED_BY:      idx = 2; break;
+                       case ATSPI_RELATION_FLOWS_TO:           idx = 3; break;
+                       case ATSPI_RELATION_FLOWS_FROM:         idx = 4; break;
+                       case ATSPI_RELATION_DESCRIBED_BY:       idx = 5; break;
+                       default: idx = 0;
+               }
+
+               if (idx > 0)
+                       table[idx] = _get_unique_id_of_object_in_relation(relation);
+               else {
+                       char buf[16];
+                       snprintf(buf, sizeof(buf), " [%d]", type);
+                       _combine_strings(&table[RELATION_TABLE_COLUMN_COUNT - 1], buf);
+               }
+       }
+
+       for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++) {
+               printf("%*s|", RELATION_TABLE_COLUMN_WIDTH, table[i] ? table[i] : "");
+               free(table[i]);
+       }
+       free(table);
+
+       printf("\n");
+       _print_horizontal_line_in_relations_table();
+       g_array_free(relations, TRUE);
+}
+
+typedef void (*print_information_about_object_function)(AtspiAccessible *);
+
+static void _iterate_over_tree(print_information_about_object_function func, AtspiAccessible *node) {
+       func(node);
+
+       int count = atspi_accessible_get_child_count(node, NULL);
+       for (int i = 0; i < count; i++) {
+               AtspiAccessible *child = atspi_accessible_get_child_at_index(node, i, NULL);
+               if (child)
+                       _iterate_over_tree(func, child);
+       }
+}
+
+static void _print_relations_for_objects_in_tree(AtspiAccessible *node) {
+       _iterate_over_tree(_print_relations_for_object, node);
+}
+
+static void _print_header_for_relation_table() {
+       char *table[] = {"OBJECT", "CONTROLLER_FOR", "CONTROLLED_BY", "FLOWS_TO", "FLOWS_FROM", "DESCRIBED_BY", "OTHER RELATION [ID]"};
+       assert(ARRAY_SIZE(table) == RELATION_TABLE_COLUMN_COUNT);
+
+       _print_horizontal_line_in_relations_table();
+
+       for (int i = 0; i < RELATION_TABLE_COLUMN_COUNT; i++)
+               printf("%*s|", RELATION_TABLE_COLUMN_WIDTH , table[i]);
+
+       printf("\n");
+       _print_horizontal_line_in_relations_table();
+}
+
+static void _print_relations_table(AtspiAccessible *node) {
+       printf("\nRELATIONS TABLE\n");
+       _print_header_for_relation_table();
+       _print_relations_for_objects_in_tree(node);
+}
+
+static void _print_horizontal_line_in_attributes_table() {
+       int size_factor = 1;
+       for (int i = 0; i < ATTRIBUTE_TABLE_COLUMN_COUNT; i++) {
+               if (i == ATTRIBUTE_TABLE_COLUMN_COUNT - 1)
+                       size_factor = 4;
+               for (int j = 0; j < ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH * size_factor; j++)
+                       printf("-");
+               printf("+");
+       }
+       printf("\n");
+}
+
+static void _print_attributes_for_object(AtspiAccessible *node) {
+       GHashTable *attributes = atspi_accessible_get_attributes(node, NULL);
+
+       if (!attributes)
+               return;
+
+       char *unique_id = atspi_accessible_get_unique_id(node, NULL);
+       GHashTableIter attributes_iter;
+       gpointer attr_key;
+       gpointer attr_value;
+
+       g_hash_table_iter_init (&attributes_iter, attributes);
+       while (g_hash_table_iter_next (&attributes_iter, &attr_key, &attr_value)) {
+               printf("%*s|", ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH, unique_id ? unique_id : "");
+               printf("%*s|", ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH, attr_key ? (char *) attr_key : "");
+               printf("%*s|\n", ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH * 4, attr_value ? (char *) attr_value : "");
+       }
+
+       if (g_hash_table_size (attributes))
+               _print_horizontal_line_in_attributes_table();
+
+       g_hash_table_unref(attributes);
+       free(unique_id);
+}
+
+static void _print_attributes_for_objects_in_tree(AtspiAccessible *node) {
+       _iterate_over_tree(_print_attributes_for_object, node);
+}
+
+static void _print_header_for_attributes_table() {
+       char *table[] = {"OBJECT", "ATTRIBUTE KEY", "ATTRIBUTE VALUE"};
+       assert(ARRAY_SIZE(table) == ATTRIBUTE_TABLE_COLUMN_COUNT);
+
+       _print_horizontal_line_in_attributes_table();
+
+       int size_factor = 1;
+       for (int i = 0; i < ATTRIBUTE_TABLE_COLUMN_COUNT; i++) {
+               if (i == ATTRIBUTE_TABLE_COLUMN_COUNT - 1)
+                       size_factor = 4;
+               printf("%*s|", ATTRIBUTE_TABLE_BASE_COLUMN_WIDTH * size_factor , table[i]);
+       }
+
+       printf("\n");
+       _print_horizontal_line_in_attributes_table();
+}
+
+static void _print_attributes_table(AtspiAccessible *node) {
+       printf("\nATTRIBUTES TABLE\n");
+       _print_header_for_attributes_table();
+       _print_attributes_for_objects_in_tree(node);
+}
+
+static void _atspi_tree_traverse(const char *app_name, bool dump, bool check, bool first_match, int length_limit)
 {
+
+       AtspiAccessible *desktop = atspi_get_desktop(0);
+       if (!desktop) {
+               fprintf(stderr, "atspi_get_desktop failed\n");
+               return;
+       }
+
        int count = atspi_accessible_get_child_count(desktop, NULL);
        bool app_name_matched = false;
+
        for (int i = 0; i < count; i++) {
                AtspiAccessible *child = atspi_accessible_get_child_at_index(desktop, i, NULL);
-               if (child) {
-                       char *name = atspi_accessible_get_name(child, NULL);
+               if (child == NULL) {
+                       fprintf(stderr, "\n%s, %s %d: Null application occured. Results may be misleading.\n", __FILE__, __FUNCTION__, __LINE__);
+                       continue;
+               }
 
-                       if (!dump && !check) {
-                               printf("%s\n", name);
-                       }
+               char *name = atspi_accessible_get_name(child, NULL);
+               bool attributes_are_too_long = false;
+               bool app_has_relations = false;
+
+               if (!dump && !check)
+                       printf("%s\n", name);
+
+               if ((check || dump) && name && !strcmp(name, app_name)) {
+                       app_name_matched = true;
 
-                       if ((check || dump) && name && !strcmp(name, app_name)) {
-                               app_name_matched = true;
+                       _print_module_legend();
 
-                               _print_module_legend();
+                       if (check)
+                               _test_atspi_parent_child_relation(child, desktop, i);
 
-                               if (check)
-                                       _test_atspi_parent_child_relation(child, desktop, i);
+                       _print_atspi_tree_verify_maybe_r(0, child, check, length_limit, &attributes_are_too_long, &app_has_relations);
 
-                               _print_atspi_tree_verify_maybe_r(0, child, check, length_limit);
+                       if (app_has_relations)
+                               _print_relations_table(child);
 
-                               if (first_match) {
-                                       free(name);
-                                       break;
-                               } else
-                                       printf("\n");
+                       if (attributes_are_too_long)
+                               _print_attributes_table(child);
+
+                       if (first_match) {
+                               free(name);
+                               break;
+                       } else {
+                               printf("\n");
                        }
+
                        free(name);
                }
        }
 
        if (!app_name_matched && (dump || check))
                fprintf(stderr, "There is no application with name: %s. Try again.\n", app_name);
+
+       g_object_unref(desktop);
+}
+
+static void _at_spi_client_enable(gboolean enabled)
+{
+       static GDBusProxy *proxy = NULL; //we keep proxy (dbus connection) until program exits
+       GVariant *result;
+       GError *error = NULL;
+       GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_NONE;
+
+
+       if (!proxy) {
+               proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                       flags,
+                                       NULL, /* GDBusInterfaceInfo */
+                                       "org.a11y.Bus",
+                                       "/org/a11y/bus",
+                                       "org.freedesktop.DBus.Properties",
+                                       NULL, /* GCancellable */
+                                       &error);
+               if (error) {
+                       fprintf(stderr, "Failed to create proxy object for '/org/a11y/bus': %s\n", error->message);
+                       g_error_free(error);
+                       return;
+               }
+       }
+
+       result = g_dbus_proxy_call_sync(proxy,
+                                       "Set",
+                                       g_variant_new ("(ssv)",  "org.a11y.Status", "IsEnabled", g_variant_new_boolean(enabled)),
+                                       G_DBUS_CALL_FLAGS_NONE,
+                                       -1,
+                                       NULL,
+                                       &error);
+       if (result)
+               g_variant_unref(result);
+
+       if (error) {
+               fprintf(stderr, "Fail to call org.freedesktop.DBus.Properties.Set: %s\n", error->message);
+               g_error_free(error);
+       }
 }
 
-static void _run_command(int argc, char *argv[], AtspiAccessible *desktop)
+static void _run_command(int argc, char *argv[])
 {
        struct option long_options[] = {
                {"help", no_argument, 0, 'h'},
                {"version", no_argument, 0, 'v'},
                {"show-legend", no_argument, 0, 'g'},
                {"list-apps", no_argument, 0, 'l'},
+               {"at-spi-client", no_argument, 0, 'a'},
+               {"sleep", required_argument, 0, 's'},
                {"tree-dump", required_argument, 0, 'd'},
                {"tree-check", required_argument, 0, 'c'},
                {"first-match", no_argument, 0, 'f'},
@@ -459,9 +721,10 @@ static void _run_command(int argc, char *argv[], AtspiAccessible *desktop)
        int option_index = 0;
        bool traverse_flags[FLAG_NO] = {false};
        char *app_name = NULL;
+       gboolean enable_at_spi_client;
 
        while (TRUE) {
-               command = getopt_long(argc, argv, "hvgld:c:ft:i:", long_options, &option_index);
+               command = getopt_long(argc, argv, "hvgla:s:d:c:ft:i:", long_options, &option_index);
 
                if (command == ERROR_STATE)
                        break;
@@ -480,7 +743,19 @@ static void _run_command(int argc, char *argv[], AtspiAccessible *desktop)
                        break;
 
                case 'l':
-                       _atspi_tree_traverse(desktop, NULL, false, false, false, module_name_limit);
+                       _atspi_tree_traverse(NULL, false, false, false, module_name_limit);
+                       break;
+
+               case 'a':
+                       enable_at_spi_client = TRUE;
+                       if (optarg[0] == 'f' || optarg[0] == '0')
+                               enable_at_spi_client = FALSE;
+
+                       _at_spi_client_enable(enable_at_spi_client);
+                       break;
+
+               case 's':
+                       sleep(atoi(optarg));
                        break;
 
                case 'd':
@@ -515,7 +790,7 @@ static void _run_command(int argc, char *argv[], AtspiAccessible *desktop)
        }
 
        if (traverse_flags[DUMP] || traverse_flags[CHECK])
-               _atspi_tree_traverse(desktop, app_name, traverse_flags[DUMP], traverse_flags[CHECK], traverse_flags[FIRST_MATCH], module_name_limit);
+               _atspi_tree_traverse(app_name, traverse_flags[DUMP], traverse_flags[CHECK], traverse_flags[FIRST_MATCH], module_name_limit);
 }
 
 int main(int argc, char *argv[])
@@ -532,13 +807,7 @@ int main(int argc, char *argv[])
                return -1;
        }
 
-       AtspiAccessible *desktop = atspi_get_desktop(0);
-       if (!desktop) {
-               fprintf(stderr, "atspi_get_desktop failed\n");
-               return -1;
-       }
-
-       _run_command(argc, argv, desktop);
+       _run_command(argc, argv);
 
        return 0;
 }