diff --git a/client/dbus-proxy.c b/client/dbus-proxy.c index 260a8210..41adadc1 100644 --- a/client/dbus-proxy.c +++ b/client/dbus-proxy.c @@ -44,6 +44,27 @@ static struct l_dbus *dbus; static struct l_queue *proxy_interfaces; static struct l_queue *proxy_interface_types; +static const void *proxy_interface_property_tostr( + const struct proxy_interface *proxy, + const char *name) +{ + size_t i; + const struct proxy_interface_property *property_table = + proxy->type->properties; + + for (i = 0; property_table[i].name; i++) { + if (strcmp(property_table[i].name, name)) + continue; + + if (!property_table[i].tostr) + break; + + return property_table[i].tostr(proxy->data); + } + + return NULL; +} + static void proxy_interface_property_set(struct proxy_interface *proxy, const char *name, struct l_dbus_message_iter *variant) @@ -85,6 +106,43 @@ static void interface_update_properties(struct proxy_interface *proxy, proxy_interface_property_set(proxy, name, NULL); } +char *proxy_property_str_completion(const struct proxy_interface_type *type, + proxy_property_match_func_t function, + const char *property_name, + const char *value, int state) +{ + static struct l_queue *match; + static const struct l_queue_entry *entry; + + if (!state) { + match = proxy_interface_find_all(type->interface, function, + value); + if (!match) + return NULL; + + entry = l_queue_get_entries(match); + } + + while (entry) { + const struct proxy_interface *proxy = entry->data; + const char *str; + + entry = entry->next; + + str = proxy_interface_property_tostr(proxy, property_name); + if (!str) + return NULL; + + return l_strdup(str); + } + + l_queue_destroy(match, NULL); + match = NULL; + entry = NULL; + + return NULL; +} + bool dbus_message_has_error(struct l_dbus_message *message) { const char *name; diff --git a/client/dbus-proxy.h b/client/dbus-proxy.h index a2cebd62..17aa0887 100644 --- a/client/dbus-proxy.h +++ b/client/dbus-proxy.h @@ -70,6 +70,11 @@ bool proxy_interface_method_call(const struct proxy_interface *proxy, const char *name, const char *signature, l_dbus_message_func_t callback, ...); +char *proxy_property_str_completion(const struct proxy_interface_type *type, + proxy_property_match_func_t function, + const char *property_name, + const char *value, int state); + void *proxy_interface_get_data(const struct proxy_interface *proxy); const char *proxy_interface_get_interface(const struct proxy_interface *proxy); const char *proxy_interface_get_identity_str( diff --git a/client/device.c b/client/device.c index e49e2fd6..9b89fab5 100644 --- a/client/device.c +++ b/client/device.c @@ -341,6 +341,14 @@ static bool match_by_name(const void *a, const void *b) return !strcmp(device->name, name); } +static bool match_by_partial_name(const void *a, const void *b) +{ + const struct device *device = a; + const char *text = b; + + return !strncmp(device->name, text, strlen(text)); +} + static const struct proxy_interface *get_device_proxy_by_name( const char *device_name) { @@ -471,7 +479,33 @@ static const struct command device_commands[] = { static char *family_arg_completion(const char *text, int state) { - return NULL; + static bool first_pass; + static size_t index; + static size_t len; + const char *cmd; + + if (!state) { + index = 0; + len = strlen(text); + first_pass = true; + } + + while ((cmd = device_commands[index].cmd)) { + if (device_commands[index++].entity) + continue; + + if (!strncmp(cmd, text, len)) + return l_strdup(cmd); + } + + if (first_pass) { + state = 0; + first_pass = false; + } + + return proxy_property_str_completion(&device_interface_type, + match_by_partial_name, "Name", + text, state); } static char *entity_arg_completion(const char *text, int state)