diff options
author | Alexander Larsson <alexl@redhat.com> | 2008-02-20 12:38:37 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2008-02-20 12:38:37 +0000 |
commit | c99b0c2ac706eb44a9b29d1b10ced47bd540adb6 (patch) | |
tree | b38c9f28e8803074c5586b8e36fdfa847c22760b /common | |
parent | ccde4823cbe6c5aa5bb530fed0aaf3ac37cd19a0 (diff) | |
download | gvfs-c99b0c2ac706eb44a9b29d1b10ced47bd540adb6.tar.gz |
Add ask_question support
2008-02-20 Alexander Larsson <alexl@redhat.com>
* common/gmountsource.[ch]:
Add ask_question support
* daemon/gvfsbackendsftp.c:
Handle host identity changed messages (#517460)
Patch from Carlos Garcia Campos
svn path=/trunk/; revision=1308
Diffstat (limited to 'common')
-rw-r--r-- | common/gmountsource.c | 237 | ||||
-rw-r--r-- | common/gmountsource.h | 19 |
2 files changed, 247 insertions, 9 deletions
diff --git a/common/gmountsource.c b/common/gmountsource.c index 864c85f7..01bc8c4a 100644 --- a/common/gmountsource.c +++ b/common/gmountsource.c @@ -131,9 +131,9 @@ struct AskPasswordData { GPasswordSave password_save; }; -typedef struct AskPasswordSyncData AskPasswordSyncData; +typedef struct AskSyncData AskSyncData; -struct AskPasswordSyncData { +struct AskSyncData { /* For sync calls */ GMutex *mutex; @@ -312,13 +312,13 @@ g_mount_source_ask_password_finish (GMountSource *source, static void -ask_password_reply_sync (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +ask_reply_sync (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { - AskPasswordSyncData *data; + AskSyncData *data; - data = (AskPasswordSyncData *) user_data; + data = (AskSyncData *) user_data; data->result = g_object_ref (res); @@ -343,7 +343,7 @@ g_mount_source_ask_password (GMountSource *source, char *password, *username, *domain; GPasswordSave password_save; gboolean handled, aborted; - AskPasswordSyncData data = {NULL}; + AskSyncData data = {NULL}; if (password_out) *password_out = NULL; @@ -363,7 +363,7 @@ g_mount_source_ask_password (GMountSource *source, default_user, default_domain, flags, - ask_password_reply_sync, + ask_reply_sync, &data); g_cond_wait(data.cond, data.mutex); @@ -473,6 +473,224 @@ op_ask_password (GMountOperation *op, return TRUE; } +typedef struct AskQuestionData AskQuestionData; + +struct AskQuestionData { + + /* results: */ + gboolean aborted; + guint32 choice; +}; + +/* the callback from dbus -> main thread */ +static void +ask_question_reply (DBusMessage *reply, + GError *error, + gpointer _data) +{ + GSimpleAsyncResult *result; + AskQuestionData *data; + dbus_bool_t handled, aborted; + guint32 choice; + DBusMessageIter iter; + + result = G_SIMPLE_ASYNC_RESULT (_data); + handled = TRUE; + + data = g_new0 (AskQuestionData, 1); + g_simple_async_result_set_op_res_gpointer (result, data, g_free); + + if (reply == NULL) + { + data->aborted = TRUE; + } + else + { + dbus_message_iter_init (reply, &iter); + if (!_g_dbus_message_iter_get_args (&iter, NULL, + DBUS_TYPE_BOOLEAN, &handled, + DBUS_TYPE_BOOLEAN, &aborted, + DBUS_TYPE_UINT32, &choice, + 0)) + data->aborted = TRUE; + else + { + data->aborted = aborted; + data->choice = choice; + } + } + + if (handled == FALSE) + { + g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED, NULL); + } + + g_simple_async_result_complete (result); +} + +gboolean +g_mount_source_ask_question (GMountSource *source, + const char *message, + const char **choices, + gint n_choices, + gboolean *aborted_out, + gint *choice_out) +{ + gint choice; + gboolean handled, aborted; + AskSyncData data = {NULL}; + + data.mutex = g_mutex_new (); + data.cond = g_cond_new (); + + g_mutex_lock (data.mutex); + + g_mount_source_ask_question_async (source, + message, + choices, + n_choices, + ask_reply_sync, + &data); + + g_cond_wait(data.cond, data.mutex); + g_mutex_unlock (data.mutex); + + g_cond_free (data.cond); + g_mutex_free (data.mutex); + + handled = g_mount_source_ask_question_finish (source, + data.result, + &aborted, + &choice); + + g_object_unref (data.result); + + if (aborted_out) + *aborted_out = aborted; + + if (choice_out) + *choice_out = choice; + + return handled; +} + +void +g_mount_source_ask_question_async (GMountSource *source, + const char *message_string, + const char **choices, + gint n_choices, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + DBusMessage *message; + + /* If no dbus id specified, reply that we weren't handled */ + if (source->dbus_id[0] == 0) + { + g_simple_async_report_error_in_idle (G_OBJECT (source), + callback, + user_data, + G_IO_ERROR, G_IO_ERROR_FAILED, NULL); + return; + } + + if (message_string == NULL) + message_string = ""; + + message = dbus_message_new_method_call (source->dbus_id, + source->obj_path, + G_VFS_DBUS_MOUNT_OPERATION_INTERFACE, + G_VFS_DBUS_MOUNT_OPERATION_OP_ASK_QUESTION); + + _g_dbus_message_append_args (message, + DBUS_TYPE_STRING, &message_string, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, + choices, n_choices, + 0); + + result = g_simple_async_result_new (G_OBJECT (source), callback, user_data, + g_mount_source_ask_question_async); + /* 30 minute timeout */ + _g_dbus_connection_call_async (NULL, message, 1000 * 60 * 30, + ask_question_reply, result); + dbus_message_unref (message); + +} + +gboolean +g_mount_source_ask_question_finish (GMountSource *source, + GAsyncResult *result, + gboolean *aborted, + gint *choice_out) +{ + AskQuestionData *data; + GSimpleAsyncResult *simple; + + simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, NULL)) + return FALSE; + + data = (AskQuestionData *) g_simple_async_result_get_op_res_gpointer (simple); + + if (aborted) + *aborted = data->aborted; + + if (choice_out) + *choice_out = data->choice; + + return TRUE; +} + +static void +op_ask_question_reply (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GMountOperationResult result; + GMountOperation *op; + GMountSource *source; + gboolean handled, aborted; + gint choice; + + source = G_MOUNT_SOURCE (source_object); + op = G_MOUNT_OPERATION (user_data); + + handled = g_mount_source_ask_question_finish (source, + res, + &aborted, + &choice); + + if (!handled) + result = G_MOUNT_OPERATION_UNHANDLED; + else if (aborted) + result = G_MOUNT_OPERATION_ABORTED; + else + { + result = G_MOUNT_OPERATION_HANDLED; + g_mount_operation_set_choice (op, choice); + } + + g_mount_operation_reply (op, result); + g_object_unref (op); +} + +static gboolean +op_ask_question (GMountOperation *op, + const char *message, + const char **choices, + gint n_choices, + GMountSource *mount_source) +{ + g_mount_source_ask_question_async (mount_source, + message, + choices, + n_choices, + op_ask_question_reply, + g_object_ref (op)); + return TRUE; +} GMountOperation * g_mount_source_get_operation (GMountSource *mount_source) @@ -486,6 +704,7 @@ g_mount_source_get_operation (GMountSource *mount_source) g_signal_connect (op, "ask_password", (GCallback)op_ask_password, mount_source); + g_signal_connect (op, "ask_question", (GCallback)op_ask_question, mount_source); return op; } diff --git a/common/gmountsource.h b/common/gmountsource.h index 540af899..676595ff 100644 --- a/common/gmountsource.h +++ b/common/gmountsource.h @@ -83,6 +83,25 @@ gboolean g_mount_source_ask_password_finish (GMountSource char **domain_out, GPasswordSave *password_save_out); +gboolean g_mount_source_ask_question (GMountSource *mount_source, + const char *message, + const char **choices, + gint n_choices, + gboolean *aborted, + gint *choice_out); + +void g_mount_source_ask_question_async (GMountSource *mount_source, + const char *message, + const char **choices, + gint n_choices, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean g_mount_source_ask_question_finish (GMountSource *source, + GAsyncResult *result, + gboolean *aborted, + gint *choice_out); + const char * g_mount_source_get_dbus_id (GMountSource *mount_source); const char * g_mount_source_get_obj_path (GMountSource *mount_source); |