diff --git a/client/agent.c b/client/agent.c
index b0ac2f8..0c533ef 100644
--- a/client/agent.c
+++ b/client/agent.c
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <readline/readline.h>
#include <gdbus.h>
#define AGENT_PATH "/org/bluez/agent"
#define AGENT_INTERFACE "org.bluez.Agent1"
+#define AGENT_PROMPT COLOR_RED "[agent]" COLOR_OFF " "
+
static gboolean agent_registered = FALSE;
static const char *agent_capability = NULL;
static DBusMessage *pending_message = NULL;
+static char *agent_saved_prompt = NULL;
+static int agent_saved_point = 0;
+
+static void agent_prompt(const char *msg)
+{
+ char *prompt;
+
+ /* Normal use should not prompt for user input to the agent a second
+ * time before it releases the prompt, but we take a safe action. */
+ if (agent_saved_prompt)
+ return;
+
+ agent_saved_point = rl_point;
+ agent_saved_prompt = g_strdup(rl_prompt);
+
+ rl_set_prompt("");
+ rl_redisplay();
+
+ prompt = g_strdup_printf(AGENT_PROMPT "%s", msg);
+ rl_set_prompt(prompt);
+ g_free(prompt);
+
+ rl_replace_line("", 0);
+ rl_redisplay();
+}
+
+static void agent_release_prompt(void)
+{
+ if (!agent_saved_prompt)
+ return;
+
+ /* This will cause rl_expand_prompt to re-run over the last prompt, but
+ * our prompt doesn't expand anyway. */
+ rl_set_prompt(agent_saved_prompt);
+ rl_replace_line("", 0);
+ rl_point = agent_saved_point;
+ rl_redisplay();
+
+ g_free(agent_saved_prompt);
+ agent_saved_prompt = NULL;
+}
dbus_bool_t agent_completion(void)
{
{
const char *member;
- rl_clear_message();
-
if (!pending_message)
return FALSE;
+ agent_release_prompt();
+
member = dbus_message_get_member(pending_message);
if (!strcmp(member, "RequestPinCode"))
static DBusMessage *release_agent(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
- if (pending_message)
- rl_clear_message();
-
agent_registered = FALSE;
agent_capability = NULL;
pending_message = NULL;
}
+ agent_release_prompt();
+
g_dbus_unregister_interface(conn, AGENT_PATH, AGENT_INTERFACE);
return dbus_message_new_method_return(msg);
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
DBUS_TYPE_INVALID);
- rl_message("Enter PIN code: ");
+ agent_prompt("Enter PIN code: ");
pending_message = dbus_message_ref(msg);
DBUS_TYPE_UINT32, &passkey, DBUS_TYPE_INVALID);
str = g_strdup_printf("Confirm passkey %06u (yes/no): ", passkey);
- rl_message(str);
+ agent_prompt(str);
g_free(str);
pending_message = dbus_message_ref(msg);
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
DBUS_TYPE_INVALID);
- rl_message("Accept pairing (yes/no): ");
+ agent_prompt("Accept pairing (yes/no): ");
pending_message = dbus_message_ref(msg);
DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID);
str = g_strdup_printf("Authorize service %s (yes/no): ", uuid);
- rl_message(str);
+ agent_prompt(str);
g_free(str);
pending_message = dbus_message_ref(msg);
static DBusMessage *cancel_request(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
- rl_clear_message();
-
rl_printf("Request canceled\n");
+ agent_release_prompt();
dbus_message_unref(pending_message);
pending_message = NULL;
diff --git a/client/display.h b/client/display.h
index 9cb891a..957bdc6 100644
--- a/client/display.h
+++ b/client/display.h
#define COLOR_RED "\x1B[0;91m"
#define COLOR_GREEN "\x1B[0;92m"
#define COLOR_YELLOW "\x1B[0;93m"
-#define COLOR_BLUE "\x1B[0;34m"
+#define COLOR_BLUE "\x1B[0;94m"
void rl_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
diff --git a/client/main.c b/client/main.c
index d8547c0..704cf46 100644
--- a/client/main.c
+++ b/client/main.c
#define COLORED_CHG COLOR_YELLOW "CHG" COLOR_OFF
#define COLORED_DEL COLOR_RED "DEL" COLOR_OFF
+#define PROMPT_ON COLOR_BLUE "[bluetooth]" COLOR_OFF "# "
+#define PROMPT_OFF "[bluetooth]# "
+
static GMainLoop *main_loop;
static DBusConnection *dbus_conn;
static void connect_handler(DBusConnection *connection, void *user_data)
{
- rl_set_prompt(COLOR_BLUE "[bluetooth]" COLOR_OFF "# ");
+ rl_set_prompt(PROMPT_ON);
printf("\r");
rl_on_new_line();
rl_redisplay();
static void disconnect_handler(DBusConnection *connection, void *user_data)
{
- rl_set_prompt("[bluetooth]# ");
+ rl_set_prompt(PROMPT_OFF);
printf("\r");
rl_on_new_line();
rl_redisplay();
rl_erase_empty_line = 1;
rl_callback_handler_install(NULL, rl_handler);
- rl_set_prompt("[bluetooth]# ");
+ rl_set_prompt(PROMPT_OFF);
rl_redisplay();
- input = setup_standard_input();
- signal = setup_signalfd();
+ input = setup_standard_input();
+ signal = setup_signalfd();
client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
g_dbus_client_set_connect_watch(client, connect_handler, NULL);