Removed, all functionality moved to mail-session.
2001-10-23 <NotZed@Ximian.com> * mail-mt.c (mail_user_message): (mail_get_password): Removed, all functionality moved to mail-session. * mail-config.c (mail_config_write_on_exit): Check threaded/preview hash is null before using it, its setup on demand so itmight nto be initialised here. * mail-session.c (request_password): Remove password_current stuff. (alert_user): Redont, similar to get_pass. Do things as async as possible, and dont even wait for a response if we're not asking for the cancel button (this may or may not be right behaviour - need to check). mail_user_message() code replaced from the stuff in mail-mt.c (MailSession): Added a lock field. (init): Setup lock. (finalise): fRee lock. (register_timeout): Redone. We now allocate our own 'timeoutid's, and <> to the real things asynchronously. Use async_event's so we can make sure we have no outstanding ones after shutdown. (mail_session_enable_interaction): If interaction has been disabled, and we have either a message-box open, or a password request open and/or any pending message boxes/passwords, blow 'em away. (main_register_timeout): If we have pending remove of this same timeout, dont do anything. (timeout_timeout): Properly honour the result, remove the timout if it returns false. svn path=/trunk/; revision=13952
This commit is contained in:
@ -1,3 +1,35 @@
|
||||
2001-10-23 <NotZed@Ximian.com>
|
||||
|
||||
* mail-mt.c (mail_user_message):
|
||||
(mail_get_password): Removed, all functionality moved to
|
||||
mail-session.
|
||||
|
||||
* mail-config.c (mail_config_write_on_exit): Check
|
||||
threaded/preview hash is null before using it, its setup on demand
|
||||
so itmight nto be initialised here.
|
||||
|
||||
* mail-session.c (request_password): Remove password_current
|
||||
stuff.
|
||||
(alert_user): Redont, similar to get_pass. Do things as async as
|
||||
possible, and dont even wait for a response if we're not asking
|
||||
for the cancel button (this may or may not be right behaviour -
|
||||
need to check). mail_user_message() code replaced from the stuff
|
||||
in mail-mt.c
|
||||
(MailSession): Added a lock field.
|
||||
(init): Setup lock.
|
||||
(finalise): fRee lock.
|
||||
(register_timeout): Redone. We now allocate our own 'timeoutid's,
|
||||
and <> to the real things asynchronously. Use async_event's so we
|
||||
can make sure we have no outstanding ones after shutdown.
|
||||
(mail_session_enable_interaction): If interaction has been
|
||||
disabled, and we have either a message-box open, or a password
|
||||
request open and/or any pending message boxes/passwords, blow 'em
|
||||
away.
|
||||
(main_register_timeout): If we have pending remove of this same
|
||||
timeout, dont do anything.
|
||||
(timeout_timeout): Properly honour the result, remove the timout
|
||||
if it returns false.
|
||||
|
||||
2001-10-23 Jeffrey Stedfast <fejj@ximian.com>
|
||||
|
||||
* mail-callbacks.c (reply_to_sender): Make sure the fb and it's
|
||||
@ -34,6 +66,9 @@
|
||||
* mail-mt.c: Added missing errno.h
|
||||
(mail_msg_new): Fix the logic a bit, dont try to open the log file
|
||||
unless logging is actually requested.
|
||||
(mail_enable_stop, mail_disable_stop, do_set_busy,
|
||||
mail_operation_statys): Dont bother propagating events if
|
||||
global_shell_client isn't up yet.
|
||||
|
||||
2001-10-23 Dan Winship <danw@ximian.com>
|
||||
|
||||
|
@ -875,12 +875,12 @@ mail_config_write_on_exit (void)
|
||||
|
||||
bonobo_config_set_string_wrapper (config->db, "/Mail/Filters/log_path",
|
||||
config->filter_log_path, NULL);
|
||||
|
||||
if (config->threaded_hash)
|
||||
g_hash_table_foreach_remove (config->threaded_hash, hash_save_state, "Threads");
|
||||
|
||||
g_hash_table_foreach_remove (config->threaded_hash,
|
||||
hash_save_state, "Threads");
|
||||
|
||||
g_hash_table_foreach_remove (config->preview_hash,
|
||||
hash_save_state, "Preview");
|
||||
if (config->preview_hash)
|
||||
g_hash_table_foreach_remove (config->preview_hash, hash_save_state, "Preview");
|
||||
|
||||
CORBA_exception_init (&ev);
|
||||
Bonobo_ConfigDatabase_sync (config->db, &ev);
|
||||
|
320
mail/mail-mt.c
320
mail/mail-mt.c
@ -351,6 +351,7 @@ EMsgPort *mail_gui_port;
|
||||
static GIOChannel *mail_gui_channel;
|
||||
static guint mail_gui_watch;
|
||||
|
||||
/* TODO: Merge these, gui_port2 doesn't do any mail_msg processing on the request (replies, forwards, frees) */
|
||||
EMsgPort *mail_gui_port2;
|
||||
static GIOChannel *mail_gui_channel2;
|
||||
static guint mail_gui_watch2;
|
||||
@ -562,315 +563,6 @@ static pthread_mutex_t status_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* ********************************************************************** */
|
||||
|
||||
#if 0
|
||||
static GnomeDialog *password_dialogue = NULL;
|
||||
static EDList password_list = E_DLIST_INITIALISER(password_list);
|
||||
static struct _pass_msg *password_current = NULL;
|
||||
|
||||
static void do_get_pass (struct _mail_msg *mm);
|
||||
|
||||
struct _pass_msg {
|
||||
struct _mail_msg msg;
|
||||
const char *prompt;
|
||||
gboolean secret;
|
||||
gboolean *cache;
|
||||
char *result;
|
||||
char *service_url;
|
||||
GtkWidget *check;
|
||||
int inmain;
|
||||
};
|
||||
|
||||
static void
|
||||
pass_got (char *string, void *data)
|
||||
{
|
||||
struct _pass_msg *m = data;
|
||||
|
||||
printf("password got! string = '%s'\n", string?string:"<nil>");
|
||||
|
||||
if (string) {
|
||||
MailConfigService *service = NULL;
|
||||
const MailConfigAccount *mca;
|
||||
gboolean remember;
|
||||
|
||||
m->result = g_strdup (string);
|
||||
|
||||
remember = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (m->check));
|
||||
if (m->service_url) {
|
||||
mca = mail_config_get_account_by_source_url (m->service_url);
|
||||
if (mca) {
|
||||
service = mca->source;
|
||||
} else {
|
||||
mca = mail_config_get_account_by_transport_url (m->service_url);
|
||||
if (mca)
|
||||
service = mca->transport;
|
||||
}
|
||||
|
||||
if (service) {
|
||||
mail_config_service_set_save_passwd (service, remember);
|
||||
|
||||
/* set `remember' to TRUE because people don't want to have to
|
||||
re-enter their passwords for this session even if they told
|
||||
us not to cache their passwords in the dialog...*sigh* */
|
||||
remember = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (m->cache)
|
||||
*(m->cache) = remember;
|
||||
|
||||
}
|
||||
|
||||
if (!m->inmain)
|
||||
e_msgport_reply((EMsg *)m);
|
||||
|
||||
password_dialogue = NULL;
|
||||
|
||||
m = e_dlist_remhead(&password_list);
|
||||
if (m) {
|
||||
printf("Have queued password request, showing now the other is finished\n");
|
||||
do_get_pass(m);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_get_pass (struct _mail_msg *mm)
|
||||
{
|
||||
struct _pass_msg *m = (struct _pass_msg *)mm;
|
||||
const MailConfigAccount *mca = NULL;
|
||||
GtkWidget *dialogue;
|
||||
GtkWidget *check, *entry;
|
||||
GList *children, *iter;
|
||||
gboolean show;
|
||||
char *title;
|
||||
|
||||
/* If we already have a password_dialogue up, save this request till later */
|
||||
if (!m->inmain && password_dialogue) {
|
||||
e_dlist_addtail(&password_list, (EDListNode *)mm);
|
||||
return;
|
||||
}
|
||||
|
||||
password_current = m;
|
||||
|
||||
/* this api is just awful ... hence the hacks */
|
||||
dialogue = gnome_request_dialog (m->secret, m->prompt, NULL, 0, pass_got, m, NULL);
|
||||
|
||||
/* Remember the password? */
|
||||
check = gtk_check_button_new_with_label (m->service_url ? _("Remember this password") :
|
||||
_("Remember this password for the remainder of this session"));
|
||||
show = TRUE;
|
||||
|
||||
if (m->service_url) {
|
||||
mca = mail_config_get_account_by_source_url (m->service_url);
|
||||
if (mca)
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), mca->source->save_passwd);
|
||||
else {
|
||||
mca = mail_config_get_account_by_transport_url (m->service_url);
|
||||
if (mca)
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), mca->transport->save_passwd);
|
||||
else {
|
||||
d(printf ("Cannot figure out which account owns URL \"%s\"\n", m->service_url));
|
||||
show = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (show)
|
||||
gtk_widget_show (check);
|
||||
|
||||
/* do some dirty stuff to put the checkbutton after the entry */
|
||||
entry = NULL;
|
||||
children = gtk_container_children (GTK_CONTAINER (GNOME_DIALOG (dialogue)->vbox));
|
||||
for (iter = children; iter; iter = iter->next) {
|
||||
if (GTK_IS_ENTRY (iter->data)) {
|
||||
entry = GTK_WIDGET (iter->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_list_free (children);
|
||||
|
||||
if (entry) {
|
||||
gtk_object_ref (GTK_OBJECT (entry));
|
||||
gtk_container_remove (GTK_CONTAINER (GNOME_DIALOG (dialogue)->vbox), entry);
|
||||
}
|
||||
|
||||
gtk_box_pack_end (GTK_BOX (GNOME_DIALOG (dialogue)->vbox), check, TRUE, FALSE, 0);
|
||||
|
||||
if (entry) {
|
||||
gtk_box_pack_end (GTK_BOX (GNOME_DIALOG (dialogue)->vbox), entry, TRUE, FALSE, 0);
|
||||
gtk_widget_grab_focus (entry);
|
||||
gtk_object_unref (GTK_OBJECT (entry));
|
||||
}
|
||||
|
||||
m->check = check;
|
||||
|
||||
/* hrm, we can't run this async since the gui_port from which we're called
|
||||
will reply to our message for us */
|
||||
|
||||
if (mca) {
|
||||
char *name;
|
||||
|
||||
name = e_utf8_to_gtk_string (GTK_WIDGET (dialogue), mca->name);
|
||||
title = g_strdup_printf (_("Enter Password for %s"), name);
|
||||
g_free (name);
|
||||
} else
|
||||
title = g_strdup (_("Enter Password"));
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (dialogue), title);
|
||||
g_free (title);
|
||||
|
||||
if (m->inmain) {
|
||||
printf("showing dialogue in main\n");
|
||||
password_current = NULL;
|
||||
gnome_dialog_run_and_close ((GnomeDialog *)dialogue);
|
||||
e_msgport_reply((EMsg *)m);
|
||||
} else {
|
||||
printf("showing dialogue async\n");
|
||||
gtk_widget_show(dialogue);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_free_pass(struct _mail_msg *mm)
|
||||
{
|
||||
/*struct _pass_msg *m = (struct _pass_msg *)mm;*/
|
||||
|
||||
/* the string is passed out so we dont need to free it */
|
||||
}
|
||||
|
||||
struct _mail_msg_op get_pass_op = {
|
||||
NULL,
|
||||
do_get_pass,
|
||||
NULL,
|
||||
do_free_pass,
|
||||
};
|
||||
|
||||
/* returns the password, or NULL if cancelled */
|
||||
char *
|
||||
mail_get_password (CamelService *service, const char *prompt, gboolean secret, gboolean *cache)
|
||||
{
|
||||
char *ret;
|
||||
struct _pass_msg *m, *r;
|
||||
EMsgPort *pass_reply;
|
||||
|
||||
pass_reply = e_msgport_new ();
|
||||
|
||||
m = mail_msg_new (&get_pass_op, pass_reply, sizeof (struct _pass_msg));
|
||||
|
||||
m->prompt = prompt;
|
||||
m->secret = secret;
|
||||
m->cache = cache;
|
||||
m->inmain = pthread_self() == mail_gui_thread;
|
||||
if (service) {
|
||||
m->service_url = camel_url_to_string (service->url, CAMEL_URL_HIDE_ALL);
|
||||
} else
|
||||
m->service_url = NULL;
|
||||
|
||||
if (m->inmain) {
|
||||
do_get_pass ((struct _mail_msg *)m);
|
||||
r = m;
|
||||
} else {
|
||||
e_msgport_put (mail_gui_port2, (EMsg *)m);
|
||||
e_msgport_wait (pass_reply);
|
||||
r = (struct _pass_msg *)e_msgport_get (pass_reply);
|
||||
}
|
||||
|
||||
g_assert (r == m);
|
||||
|
||||
ret = m->result;
|
||||
|
||||
g_free (m->service_url);
|
||||
mail_msg_free (m);
|
||||
e_msgport_destroy (pass_reply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ******************** */
|
||||
|
||||
/* ********************************************************************** */
|
||||
|
||||
struct _user_message_msg {
|
||||
struct _mail_msg msg;
|
||||
const char *type;
|
||||
const char *prompt;
|
||||
gboolean allow_cancel;
|
||||
gboolean result;
|
||||
};
|
||||
|
||||
static void
|
||||
do_user_message (struct _mail_msg *mm)
|
||||
{
|
||||
struct _user_message_msg *m = (struct _user_message_msg *)mm;
|
||||
int dialog_result;
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gnome_message_box_new (m->prompt, m->type,
|
||||
GNOME_STOCK_BUTTON_OK,
|
||||
m->allow_cancel ? GNOME_STOCK_BUTTON_CANCEL : NULL,
|
||||
NULL);
|
||||
gnome_dialog_set_default (GNOME_DIALOG (dialog), 1);
|
||||
gtk_window_set_policy (GTK_WINDOW (dialog), TRUE, TRUE, TRUE);
|
||||
|
||||
/* hrm, we can't run this async since the gui_port from which we're called
|
||||
will reply to our message for us */
|
||||
dialog_result = gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
|
||||
|
||||
if (dialog_result == -1 || dialog_result == 1)
|
||||
m->result = FALSE;
|
||||
else
|
||||
m->result = TRUE;
|
||||
}
|
||||
|
||||
struct _mail_msg_op user_message_op = {
|
||||
NULL,
|
||||
do_user_message,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* prompt the user with a yes/no question and return the response */
|
||||
gboolean
|
||||
mail_user_message (const char *type, const char *prompt, gboolean allow_cancel)
|
||||
{
|
||||
struct _user_message_msg *m, *r;
|
||||
EMsgPort *user_message_reply;
|
||||
gboolean accept;
|
||||
|
||||
user_message_reply = e_msgport_new ();
|
||||
|
||||
m = mail_msg_new (&user_message_op, user_message_reply, sizeof (*m));
|
||||
|
||||
m->type = type;
|
||||
m->prompt = prompt;
|
||||
m->allow_cancel = allow_cancel;
|
||||
|
||||
if (pthread_self () == mail_gui_thread) {
|
||||
do_user_message ((struct _mail_msg *)m);
|
||||
r = m;
|
||||
} else {
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* we want this single-threaded, this is the easiest way to do it without blocking ? */
|
||||
pthread_mutex_lock (&lock);
|
||||
e_msgport_put (mail_gui_port, (EMsg *)m);
|
||||
e_msgport_wait (user_message_reply);
|
||||
r = (struct _user_message_msg *)e_msgport_get (user_message_reply);
|
||||
pthread_mutex_unlock (&lock);
|
||||
}
|
||||
|
||||
g_assert (r == m);
|
||||
|
||||
accept = m->result;
|
||||
|
||||
mail_msg_free (m);
|
||||
e_msgport_destroy (user_message_reply);
|
||||
|
||||
return accept;
|
||||
}
|
||||
|
||||
/* ******************** */
|
||||
|
||||
struct _proxy_msg {
|
||||
struct _mail_msg msg;
|
||||
MailAsyncEvent *ea;
|
||||
@ -1057,7 +749,8 @@ static int busy_state;
|
||||
|
||||
static void do_set_busy(struct _mail_msg *mm)
|
||||
{
|
||||
set_stop(busy_state > 0);
|
||||
if (global_shell_client)
|
||||
set_stop(busy_state > 0);
|
||||
}
|
||||
|
||||
struct _mail_msg_op set_busy_op = {
|
||||
@ -1073,7 +766,7 @@ static void mail_enable_stop(void)
|
||||
|
||||
MAIL_MT_LOCK(status_lock);
|
||||
busy_state++;
|
||||
if (busy_state == 1) {
|
||||
if (busy_state == 1 && global_shell_client) {
|
||||
m = mail_msg_new(&set_busy_op, NULL, sizeof(*m));
|
||||
e_msgport_put(mail_gui_port, (EMsg *)m);
|
||||
}
|
||||
@ -1086,7 +779,7 @@ static void mail_disable_stop(void)
|
||||
|
||||
MAIL_MT_LOCK(status_lock);
|
||||
busy_state--;
|
||||
if (busy_state == 0) {
|
||||
if (busy_state == 0 && global_shell_client) {
|
||||
m = mail_msg_new(&set_busy_op, NULL, sizeof(*m));
|
||||
e_msgport_put(mail_gui_port, (EMsg *)m);
|
||||
}
|
||||
@ -1229,6 +922,9 @@ mail_operation_status (struct _CamelOperation *op, const char *what, int pc, voi
|
||||
struct _op_status_msg *m;
|
||||
|
||||
d(printf("got operation statys: %s %d%%\n", what, pc));
|
||||
|
||||
if (global_shell_client == NULL)
|
||||
return;
|
||||
|
||||
m = mail_msg_new(&op_status_op, NULL, sizeof(*m));
|
||||
m->op = op;
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include <libgnomeui/gnome-dialog-util.h>
|
||||
#include <libgnomeui/gnome-messagebox.h>
|
||||
#include <libgnomeui/gnome-stock.h>
|
||||
|
||||
#include <gal/widgets/e-unicode.h>
|
||||
|
||||
#include "camel/camel-filter-driver.h"
|
||||
#include "filter/filter-context.h"
|
||||
#include "filter/filter-filter.h"
|
||||
@ -38,6 +41,7 @@
|
||||
#include "mail-tools.h"
|
||||
#include "mail-mt.h"
|
||||
#include "e-util/e-passwords.h"
|
||||
#include "e-util/e-msgport.h"
|
||||
|
||||
#define d(x)
|
||||
|
||||
@ -49,12 +53,22 @@ CamelSession *session;
|
||||
#define MAIL_SESSION_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), MAIL_SESSION_TYPE, MailSessionClass))
|
||||
#define MAIL_IS_SESSION(o) (CAMEL_CHECK_TYPE((o), MAIL_SESSION_TYPE))
|
||||
|
||||
#define MAIL_SESSION_LOCK(s, l) (e_mutex_lock(((MailSession *)s)->l))
|
||||
#define MAIL_SESSION_UNLOCK(s, l) (e_mutex_unlock(((MailSession *)s)->l))
|
||||
|
||||
typedef struct _MailSession {
|
||||
CamelSession parent_object;
|
||||
|
||||
gboolean interaction_enabled;
|
||||
FILE *filter_logfile;
|
||||
|
||||
EMutex *lock;
|
||||
|
||||
MailAsyncEvent *async;
|
||||
|
||||
/* must all be accessed with lock held ! */
|
||||
unsigned int timeout_id;/* next camel timneout id */
|
||||
EDList timeouts; /* list of struct _timeout_data's of current or pending removed timeouts */
|
||||
} MailSession;
|
||||
|
||||
typedef struct _MailSessionClass {
|
||||
@ -62,32 +76,33 @@ typedef struct _MailSessionClass {
|
||||
|
||||
} MailSessionClass;
|
||||
|
||||
|
||||
static char *get_password (CamelSession *session, const char *prompt,
|
||||
gboolean secret, CamelService *service,
|
||||
const char *item, CamelException *ex);
|
||||
static void forget_password (CamelSession *session, CamelService *service,
|
||||
const char *item, CamelException *ex);
|
||||
static gboolean alert_user (CamelSession *session, CamelSessionAlertType type,
|
||||
const char *prompt, gboolean cancel);
|
||||
static guint register_timeout (CamelSession *session, guint32 interval,
|
||||
CamelTimeoutCallback cb, gpointer camel_data);
|
||||
static gboolean remove_timeout (CamelSession *session, guint handle);
|
||||
static CamelFilterDriver *get_filter_driver (CamelSession *session,
|
||||
const char *type,
|
||||
CamelException *ex);
|
||||
|
||||
static char *get_password(CamelSession *session, const char *prompt, gboolean secret, CamelService *service, const char *item, CamelException *ex);
|
||||
static void forget_password(CamelSession *session, CamelService *service, const char *item, CamelException *ex);
|
||||
static gboolean alert_user(CamelSession *session, CamelSessionAlertType type, const char *prompt, gboolean cancel);
|
||||
static guint register_timeout(CamelSession *session, guint32 interval, CamelTimeoutCallback cb, gpointer camel_data);
|
||||
static gboolean remove_timeout(CamelSession *session, guint handle);
|
||||
static CamelFilterDriver *get_filter_driver(CamelSession *session, const char *type, CamelException *ex);
|
||||
|
||||
static void
|
||||
init (MailSession *session)
|
||||
{
|
||||
session->lock = e_mutex_new(E_MUTEX_REC);
|
||||
session->timeout_id = 1; /* first timeout id */
|
||||
session->async = mail_async_event_new();
|
||||
e_dlist_init(&session->timeouts);
|
||||
}
|
||||
|
||||
static void
|
||||
finalise (MailSession *session)
|
||||
{
|
||||
mail_async_event_destroy(session->async);
|
||||
e_mutex_destroy(session->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
class_init (MailSessionClass *mail_session_class)
|
||||
{
|
||||
CamelSessionClass *camel_session_class =
|
||||
CAMEL_SESSION_CLASS (mail_session_class);
|
||||
CamelSessionClass *camel_session_class = CAMEL_SESSION_CLASS (mail_session_class);
|
||||
|
||||
/* virtual method override */
|
||||
camel_session_class->get_password = get_password;
|
||||
@ -112,7 +127,7 @@ mail_session_get_type (void)
|
||||
(CamelObjectClassInitFunc) class_init,
|
||||
NULL,
|
||||
(CamelObjectInitFunc) init,
|
||||
NULL);
|
||||
(CamelObjectFinalizeFunc) finalise);
|
||||
}
|
||||
|
||||
return mail_session_type;
|
||||
@ -136,7 +151,6 @@ make_key (CamelService *service, const char *item)
|
||||
|
||||
static GnomeDialog *password_dialogue = NULL;
|
||||
static EDList password_list = E_DLIST_INITIALISER(password_list);
|
||||
static struct _pass_msg *password_current = NULL;
|
||||
static int password_destroy_id;
|
||||
|
||||
struct _pass_msg {
|
||||
@ -232,12 +246,10 @@ request_password(struct _pass_msg *m)
|
||||
return;
|
||||
}
|
||||
|
||||
password_current = m;
|
||||
|
||||
/* FIXME: Remove this total snot */
|
||||
|
||||
/* this api is just awful ... hence the major hacks */
|
||||
password_dialogue = dialogue = gnome_request_dialog (m->secret, m->prompt, NULL, 0, pass_got, m, NULL);
|
||||
password_dialogue = (GnomeDialog *)dialogue = gnome_request_dialog (m->secret, m->prompt, NULL, 0, pass_got, m, NULL);
|
||||
|
||||
/* cant bleieve how @!@#!@# 5this api is, it doesn't handle this for you, BLAH! */
|
||||
password_destroy_id = gtk_signal_connect((GtkObject *)dialogue, "destroy", request_password_deleted, m);
|
||||
@ -303,12 +315,10 @@ request_password(struct _pass_msg *m)
|
||||
gtk_window_set_title (GTK_WINDOW (dialogue), title);
|
||||
g_free (title);
|
||||
|
||||
if (m->ismain) {
|
||||
password_current = NULL;
|
||||
if (m->ismain)
|
||||
gnome_dialog_run_and_close ((GnomeDialog *)dialogue);
|
||||
} else {
|
||||
else
|
||||
gtk_widget_show(dialogue);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -377,7 +387,7 @@ get_password (CamelSession *session, const char *prompt, gboolean secret, CamelS
|
||||
m->key = make_key(service, item);
|
||||
|
||||
if (m->ismain)
|
||||
do_get_pass(m);
|
||||
do_get_pass((struct _mail_msg *)m);
|
||||
else {
|
||||
extern EMsgPort *mail_gui_port2;
|
||||
|
||||
@ -412,60 +422,249 @@ forget_password (CamelSession *session, CamelService *service, const char *item,
|
||||
session, service, item, ex);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
alert_user (CamelSession *session, CamelSessionAlertType type,
|
||||
const char *prompt, gboolean cancel)
|
||||
/* ********************************************************************** */
|
||||
|
||||
static GnomeDialog *message_dialogue;
|
||||
static EDList message_list = E_DLIST_INITIALISER(password_list);
|
||||
static guint message_destroy_id;
|
||||
|
||||
struct _user_message_msg {
|
||||
struct _mail_msg msg;
|
||||
|
||||
CamelSessionAlertType type;
|
||||
const char *prompt;
|
||||
|
||||
unsigned int allow_cancel:1;
|
||||
unsigned int result:1;
|
||||
unsigned int ismain:1;
|
||||
};
|
||||
|
||||
static void do_user_message (struct _mail_msg *mm);
|
||||
|
||||
/* if we dont have to wait for reply, we just check to see if any newly waiting prompts are there */
|
||||
static void
|
||||
user_message_destroy_noreply(GnomeDialog *gd, void *data)
|
||||
{
|
||||
MailSession *mail_session = MAIL_SESSION (session);
|
||||
const char *message_type = NULL;
|
||||
|
||||
if (!mail_session->interaction_enabled)
|
||||
return FALSE;
|
||||
|
||||
switch (type) {
|
||||
struct _user_message_msg *m;
|
||||
|
||||
message_dialogue = NULL;
|
||||
if ((m = (struct _user_message_msg *)e_dlist_remhead(&message_list)))
|
||||
do_user_message((struct _mail_msg *)m);
|
||||
}
|
||||
|
||||
/* clicked, send back the reply */
|
||||
static void
|
||||
user_message_clicked(GnomeDialog *gd, int button, struct _user_message_msg *m)
|
||||
{
|
||||
message_dialogue = NULL;
|
||||
|
||||
if (message_destroy_id) {
|
||||
gtk_signal_disconnect((GtkObject *)gd, message_destroy_id);
|
||||
message_destroy_id = 0;
|
||||
}
|
||||
|
||||
m->result = button == 0;
|
||||
e_msgport_reply((EMsg *)m);
|
||||
|
||||
/* check for pendings */
|
||||
if ((m = (struct _user_message_msg *)e_dlist_remhead(&message_list)))
|
||||
do_user_message((struct _mail_msg *)m);
|
||||
}
|
||||
|
||||
static void
|
||||
user_message_destroy(GnomeDialog *gd, struct _user_message_msg *m)
|
||||
{
|
||||
message_destroy_id = 0;
|
||||
user_message_clicked(gd, -1, m);
|
||||
}
|
||||
|
||||
static void
|
||||
do_user_message (struct _mail_msg *mm)
|
||||
{
|
||||
struct _user_message_msg *m = (struct _user_message_msg *)mm;
|
||||
const char *msg_type;
|
||||
|
||||
if (!m->ismain && message_dialogue != NULL) {
|
||||
e_dlist_addtail(&message_list, (EDListNode *)m);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m->type) {
|
||||
case CAMEL_SESSION_ALERT_INFO:
|
||||
message_type = GNOME_MESSAGE_BOX_INFO;
|
||||
msg_type = GNOME_MESSAGE_BOX_INFO;
|
||||
break;
|
||||
case CAMEL_SESSION_ALERT_WARNING:
|
||||
message_type = GNOME_MESSAGE_BOX_WARNING;
|
||||
msg_type = GNOME_MESSAGE_BOX_WARNING;
|
||||
break;
|
||||
case CAMEL_SESSION_ALERT_ERROR:
|
||||
message_type = GNOME_MESSAGE_BOX_ERROR;
|
||||
msg_type = GNOME_MESSAGE_BOX_ERROR;
|
||||
break;
|
||||
default:
|
||||
msg_type = NULL;
|
||||
}
|
||||
return mail_user_message (message_type, prompt, cancel);
|
||||
|
||||
message_dialogue = (GnomeDialog *)gnome_message_box_new(m->prompt, msg_type, GNOME_STOCK_BUTTON_OK,
|
||||
m->allow_cancel ? GNOME_STOCK_BUTTON_CANCEL : NULL,
|
||||
NULL);
|
||||
gnome_dialog_set_default(message_dialogue, 1);
|
||||
gnome_dialog_set_close(message_dialogue, TRUE);
|
||||
gtk_window_set_policy (GTK_WINDOW (message_dialogue), TRUE, TRUE, TRUE);
|
||||
|
||||
/* We only need to wait for the result if we allow cancel otherwise show but send result back instantly */
|
||||
if (m->allow_cancel) {
|
||||
gtk_signal_connect((GtkObject*)message_dialogue, "clicked", user_message_clicked, m);
|
||||
gtk_signal_connect((GtkObject*)message_dialogue, "destroy", user_message_destroy, m);
|
||||
if (m->ismain)
|
||||
gnome_dialog_run_and_close ((GnomeDialog *)message_dialogue);
|
||||
else
|
||||
gtk_widget_show((GtkWidget *)message_dialogue);
|
||||
} else {
|
||||
gtk_signal_connect((GtkObject *)message_dialogue, "destroy", user_message_destroy_noreply, NULL);
|
||||
gtk_widget_show((GtkWidget *)message_dialogue);
|
||||
m->result = TRUE;
|
||||
e_msgport_reply((EMsg *)m);
|
||||
}
|
||||
}
|
||||
|
||||
static struct _mail_msg_op user_message_op = { NULL, do_user_message, NULL, NULL };
|
||||
|
||||
static gboolean
|
||||
alert_user(CamelSession *session, CamelSessionAlertType type, const char *prompt, gboolean cancel)
|
||||
{
|
||||
MailSession *mail_session = MAIL_SESSION (session);
|
||||
struct _user_message_msg *m, *r;
|
||||
EMsgPort *user_message_reply;
|
||||
gboolean ret;
|
||||
|
||||
if (!mail_session->interaction_enabled)
|
||||
return FALSE;
|
||||
|
||||
user_message_reply = e_msgport_new ();
|
||||
m = mail_msg_new (&user_message_op, user_message_reply, sizeof (*m));
|
||||
m->ismain = pthread_self() == mail_gui_thread;
|
||||
m->type = type;
|
||||
m->prompt = prompt;
|
||||
m->allow_cancel = cancel;
|
||||
|
||||
if (m->ismain)
|
||||
do_user_message((struct _mail_msg *)m);
|
||||
else {
|
||||
extern EMsgPort *mail_gui_port2;
|
||||
|
||||
e_msgport_put(mail_gui_port2, (EMsg *)m);
|
||||
}
|
||||
|
||||
e_msgport_wait(user_message_reply);
|
||||
r = (struct _user_message_msg *)e_msgport_get(user_message_reply);
|
||||
g_assert(m == r);
|
||||
|
||||
ret = m->result;
|
||||
mail_msg_free(m);
|
||||
e_msgport_destroy(user_message_reply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ******************** */
|
||||
|
||||
struct _timeout_data {
|
||||
CamelTimeoutCallback cb;
|
||||
struct _timeout_data *next;
|
||||
struct _timeout_data *prev;
|
||||
|
||||
CamelSession *session;
|
||||
|
||||
guint32 interval;
|
||||
|
||||
CamelTimeoutCallback cb;
|
||||
void *camel_data;
|
||||
int result;
|
||||
|
||||
guint id; /* the camel 'id' */
|
||||
guint timeout_id; /* the gtk 'id' */
|
||||
|
||||
unsigned int busy:1; /* on if its currently running */
|
||||
unsigned int removed:1; /* if its been removed since */
|
||||
};
|
||||
|
||||
struct _timeout_msg {
|
||||
struct _mail_msg msg;
|
||||
|
||||
CamelTimeoutCallback cb;
|
||||
gpointer camel_data;
|
||||
|
||||
CamelSession *session;
|
||||
unsigned int id;
|
||||
int result;
|
||||
};
|
||||
|
||||
static struct _timeout_data *
|
||||
find_timeout(EDList *list, unsigned int id)
|
||||
{
|
||||
struct _timeout_data *td, *tn;
|
||||
|
||||
td = (struct _timeout_data *)list->head;
|
||||
tn = td->next;
|
||||
while (tn) {
|
||||
if (td->id == id)
|
||||
return td;
|
||||
td = tn;
|
||||
tn = tn->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
timeout_timeout (struct _mail_msg *mm)
|
||||
{
|
||||
struct _timeout_msg *m = (struct _timeout_msg *)mm;
|
||||
|
||||
/* we ignore the callback result, do we care?? no. */
|
||||
m->cb (m->camel_data);
|
||||
MailSession *ms = (MailSession *)m->session;
|
||||
struct _timeout_data *td;
|
||||
|
||||
MAIL_SESSION_LOCK(ms, lock);
|
||||
td = find_timeout(&ms->timeouts, m->id);
|
||||
if (td && !td->removed) {
|
||||
if (td->busy) {
|
||||
g_warning("Timeout event dropped, still busy with last one");
|
||||
} else {
|
||||
td->busy = TRUE;
|
||||
m->result = td->cb(td->camel_data);
|
||||
td->busy = FALSE;
|
||||
td->removed = !m->result;
|
||||
}
|
||||
}
|
||||
MAIL_SESSION_UNLOCK(ms, lock);
|
||||
}
|
||||
|
||||
static void
|
||||
timeout_done(struct _mail_msg *mm)
|
||||
{
|
||||
struct _timeout_msg *m = (struct _timeout_msg *)mm;
|
||||
MailSession *ms = (MailSession *)m->session;
|
||||
struct _timeout_data *td;
|
||||
|
||||
if (!m->result) {
|
||||
MAIL_SESSION_LOCK(ms, lock);
|
||||
td = find_timeout(&ms->timeouts, m->id);
|
||||
if (td) {
|
||||
e_dlist_remove((EDListNode *)td);
|
||||
if (td->timeout_id)
|
||||
gtk_timeout_remove(td->timeout_id);
|
||||
g_free(td);
|
||||
}
|
||||
MAIL_SESSION_UNLOCK(ms, lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
timeout_free(struct _mail_msg *mm)
|
||||
{
|
||||
struct _timeout_msg *m = (struct _timeout_msg *)mm;
|
||||
|
||||
camel_object_unref((CamelObject *)m->session);
|
||||
}
|
||||
|
||||
static struct _mail_msg_op timeout_op = {
|
||||
NULL,
|
||||
timeout_timeout,
|
||||
NULL,
|
||||
NULL,
|
||||
timeout_done,
|
||||
timeout_free,
|
||||
};
|
||||
|
||||
static gboolean
|
||||
@ -473,65 +672,120 @@ camel_timeout (gpointer data)
|
||||
{
|
||||
struct _timeout_data *td = data;
|
||||
struct _timeout_msg *m;
|
||||
|
||||
/* stop if we are removed pending */
|
||||
if (td->removed)
|
||||
return FALSE;
|
||||
|
||||
m = mail_msg_new (&timeout_op, NULL, sizeof (*m));
|
||||
m = mail_msg_new(&timeout_op, NULL, sizeof (*m));
|
||||
|
||||
m->session = td->session;
|
||||
camel_object_ref((CamelObject *)td->session);
|
||||
m->id = td->id;
|
||||
|
||||
m->cb = td->cb;
|
||||
m->camel_data = td->camel_data;
|
||||
|
||||
e_thread_put (mail_thread_queued, (EMsg *)m);
|
||||
e_thread_put(mail_thread_queued, (EMsg *)m);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
main_register_timeout(struct _timeout_data *td)
|
||||
main_register_timeout(CamelSession *session, void *event_data, void *data)
|
||||
{
|
||||
td->result = gtk_timeout_add_full(td->interval, camel_timeout, NULL, td, g_free);
|
||||
MailSession *ms = (MailSession *)session;
|
||||
unsigned int handle = (unsigned int)event_data;
|
||||
struct _timeout_data *td;
|
||||
|
||||
MAIL_SESSION_LOCK(session, lock);
|
||||
td = find_timeout(&ms->timeouts, handle);
|
||||
if (td) {
|
||||
if (td->removed) {
|
||||
e_dlist_remove((EDListNode *)td);
|
||||
if (td->timeout_id)
|
||||
gtk_timeout_remove(td->timeout_id);
|
||||
g_free(td);
|
||||
} else {
|
||||
td->timeout_id = gtk_timeout_add(td->interval, camel_timeout, td);
|
||||
}
|
||||
}
|
||||
MAIL_SESSION_UNLOCK(session, lock);
|
||||
|
||||
camel_object_unref((CamelObject *)ms);
|
||||
}
|
||||
|
||||
static guint
|
||||
register_timeout (CamelSession *session, guint32 interval, CamelTimeoutCallback cb, gpointer camel_data)
|
||||
{
|
||||
struct _timeout_data *td;
|
||||
|
||||
/* We do this because otherwise the timeout can get called
|
||||
* more often than the dispatch thread can get rid of it,
|
||||
* leading to timeout calls piling up, and we don't have a
|
||||
* good way to watch the return values. It's not cool.
|
||||
*/
|
||||
if (interval < 1000) {
|
||||
g_warning("Timeout %u too small, increased to 1000", interval);
|
||||
interval = 1000;
|
||||
}
|
||||
MailSession *ms = (MailSession *)session;
|
||||
guint ret;
|
||||
|
||||
/* This is extremely messy, we need to proxy to gtk thread for this */
|
||||
td = g_malloc (sizeof (*td));
|
||||
td->interval = interval;
|
||||
td->result = 0;
|
||||
MAIL_SESSION_LOCK(session, lock);
|
||||
|
||||
ret = ms->timeout_id;
|
||||
ms->timeout_id ++;
|
||||
|
||||
/* just debugging, the timeout code now ignores excessive events anyway */
|
||||
if (interval < 100)
|
||||
g_warning("Timeout requested %d is small, may cause performance problems", interval);
|
||||
|
||||
td = g_malloc(sizeof(*td));
|
||||
td->cb = cb;
|
||||
td->camel_data = camel_data;
|
||||
td->interval = interval;
|
||||
td->id = ret;
|
||||
td->session = session;
|
||||
td->removed = FALSE;
|
||||
td->busy = FALSE;
|
||||
e_dlist_addhead(&ms->timeouts, (EDListNode *)td);
|
||||
|
||||
mail_call_main(MAIL_CALL_p_p, (MailMainFunc)main_register_timeout, td);
|
||||
MAIL_SESSION_UNLOCK(session, lock);
|
||||
|
||||
if (td->result == 0) {
|
||||
g_free(td);
|
||||
return 0;
|
||||
}
|
||||
camel_object_ref((CamelObject *)ms);
|
||||
mail_async_event_emit(ms->async, (CamelObjectEventHookFunc)main_register_timeout, (CamelObject *)session, (void *)ret, NULL);
|
||||
|
||||
return td->result;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
main_remove_timeout(guint *edata)
|
||||
main_remove_timeout(CamelSession *session, void *event_data, void *data)
|
||||
{
|
||||
gtk_timeout_remove(*edata);
|
||||
MailSession *ms = (MailSession *)session;
|
||||
unsigned int handle = (unsigned int)event_data;
|
||||
struct _timeout_data *td;
|
||||
|
||||
MAIL_SESSION_LOCK(session, lock);
|
||||
td = find_timeout(&ms->timeouts, handle);
|
||||
if (td) {
|
||||
e_dlist_remove((EDListNode *)td);
|
||||
if (td->timeout_id)
|
||||
gtk_timeout_remove(td->timeout_id);
|
||||
g_free(td);
|
||||
}
|
||||
MAIL_SESSION_UNLOCK(session, lock);
|
||||
|
||||
camel_object_unref((CamelObject *)ms);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
remove_timeout (CamelSession *session, guint handle)
|
||||
{
|
||||
mail_call_main(MAIL_CALL_p_p, (MailMainFunc)main_remove_timeout, &handle);
|
||||
MailSession *ms = (MailSession *)session;
|
||||
struct _timeout_data *td;
|
||||
int remove = FALSE;
|
||||
|
||||
MAIL_SESSION_LOCK(session, lock);
|
||||
td = find_timeout(&ms->timeouts, handle);
|
||||
if (td && !td->removed) {
|
||||
td->removed = TRUE;
|
||||
remove = TRUE;
|
||||
}
|
||||
MAIL_SESSION_UNLOCK(session, lock);
|
||||
|
||||
if (remove) {
|
||||
camel_object_ref((CamelObject *)ms);
|
||||
mail_async_event_emit(ms->async, (CamelObjectEventHookFunc)main_remove_timeout, (CamelObject *)session, (void *)handle, NULL);
|
||||
} else
|
||||
g_warning("Removing a timeout i dont know about (or twice): %d", handle);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -676,6 +930,37 @@ void
|
||||
mail_session_enable_interaction (gboolean enable)
|
||||
{
|
||||
MAIL_SESSION (session)->interaction_enabled = enable;
|
||||
|
||||
if (!enable) {
|
||||
struct _pass_msg *pm;
|
||||
struct _user_message_msg *um;
|
||||
|
||||
printf("Gone non-interactive, checking for outstanding interactive tasks\n");
|
||||
|
||||
/* clear out pending password requests */
|
||||
while ((pm = (struct _pass_msg *)e_dlist_remhead(&password_list))) {
|
||||
printf("Flushing password request : %s\n", pm->prompt);
|
||||
e_msgport_reply((EMsg *)pm);
|
||||
}
|
||||
|
||||
/* destroy the current */
|
||||
if (password_dialogue) {
|
||||
printf("Destroying password dialogue\n");
|
||||
gtk_object_destroy((GtkObject *)password_dialogue);
|
||||
}
|
||||
|
||||
/* same for pending user messages */
|
||||
while ((um = (struct _user_message_msg *)e_dlist_remhead(&message_list))) {
|
||||
printf("Flusing message request: %s\n", um->prompt);
|
||||
e_msgport_reply((EMsg *)um);
|
||||
}
|
||||
|
||||
/* and the current */
|
||||
if (message_dialogue) {
|
||||
printf("Destroying message dialogue\n");
|
||||
gtk_object_destroy((GtkObject *)message_dialogue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
Reference in New Issue
Block a user