+ msg_done ();
+ g_queue_free (message_queue);
+}
+
+static gboolean
+dequeue_message (gpointer data)
+{
+ struct msg * m ;
+
+ /* If a pointer grab is in effect, then the combination of that, and
+ a modal dialog box, will cause an impossible situation.
+ So don't pop it up just yet.
+ */
+ if ( gdk_pointer_is_grabbed ())
+ return TRUE;
+
+ m = g_queue_pop_tail (message_queue);
+
+ if ( m )
+ {
+ popup_message (m);
+ msg_destroy (m);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+enqueue_msg (const struct msg *msg)
+{
+ struct msg *m = msg_dup (msg);
+
+ g_queue_push_head (message_queue, m);
+
+ g_idle_add (dequeue_message, 0);
+}
+
+
+void
+popup_message (const struct msg *m)
+{
+ GtkWidget *dialog;
+ gchar *location = NULL;