]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-ui-utils.c
Merge branch 'sasl'
[empathy.git] / libempathy-gtk / empathy-ui-utils.c
index 93c08d1c59425e054851929a31d75c9abdf0f1fb..4c128742405b72274640e1b50b70b986c9594de2 100644 (file)
@@ -39,6 +39,7 @@
 #include <gtk/gtk.h>
 #include <gio/gio.h>
 
+#include <telepathy-glib/util.h>
 #include <folks/folks.h>
 
 #include "empathy-ui-utils.h"
@@ -128,9 +129,9 @@ empathy_builder_get_file (const gchar *filename,
 }
 
 void
-empathy_builder_connect (GtkBuilder *gui,
-                        gpointer    user_data,
-                        gchar      *first_object,
+empathy_builder_connect (GtkBuilder  *gui,
+                        gpointer     user_data,
+                        const gchar *first_object,
                         ...)
 {
        va_list      args;
@@ -205,6 +206,7 @@ empathy_icon_name_for_presence (TpConnectionPresenceType presence)
        case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN:
                return EMPATHY_IMAGE_PENDING;
        case TP_CONNECTION_PRESENCE_TYPE_UNSET:
+       default:
                return NULL;
        }
 
@@ -229,7 +231,8 @@ empathy_icon_name_for_individual (FolksIndividual *individual)
        FolksPresenceType folks_presence;
        TpConnectionPresenceType presence;
 
-       folks_presence = folks_individual_get_presence_type (individual);
+       folks_presence =
+           folks_presence_get_presence_type (FOLKS_PRESENCE (individual));
        presence = empathy_folks_presence_type_to_tp (folks_presence);
 
        return empathy_icon_name_for_presence (presence);
@@ -436,6 +439,35 @@ empathy_gdk_pixbuf_is_opaque (GdkPixbuf *pixbuf)
        return TRUE;
 }
 
+static GdkPixbuf *
+avatar_pixbuf_from_loader (GdkPixbufLoader *loader)
+{
+       GdkPixbuf *pixbuf;
+
+       pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+       if (!gdk_pixbuf_get_has_alpha (pixbuf)) {
+               GdkPixbuf *rounded_pixbuf;
+
+               rounded_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
+                                                gdk_pixbuf_get_width (pixbuf),
+                                                gdk_pixbuf_get_height (pixbuf));
+               gdk_pixbuf_copy_area (pixbuf, 0, 0,
+                                     gdk_pixbuf_get_width (pixbuf),
+                                     gdk_pixbuf_get_height (pixbuf),
+                                     rounded_pixbuf,
+                                     0, 0);
+               pixbuf = rounded_pixbuf;
+       } else {
+               g_object_ref (pixbuf);
+       }
+
+       if (empathy_gdk_pixbuf_is_opaque (pixbuf)) {
+               empathy_avatar_pixbuf_roundify (pixbuf);
+       }
+
+       return pixbuf;
+}
+
 GdkPixbuf *
 empathy_pixbuf_from_avatar_scaled (EmpathyAvatar *avatar,
                                  gint          width,
@@ -469,27 +501,7 @@ empathy_pixbuf_from_avatar_scaled (EmpathyAvatar *avatar,
        }
 
        gdk_pixbuf_loader_close (loader, NULL);
-
-       pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
-       if (!gdk_pixbuf_get_has_alpha (pixbuf)) {
-               GdkPixbuf *rounded_pixbuf;
-
-               rounded_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
-                                                gdk_pixbuf_get_width (pixbuf),
-                                                gdk_pixbuf_get_height (pixbuf));
-               gdk_pixbuf_copy_area (pixbuf, 0, 0,
-                                     gdk_pixbuf_get_width (pixbuf),
-                                     gdk_pixbuf_get_height (pixbuf),
-                                     rounded_pixbuf,
-                                     0, 0);
-               pixbuf = rounded_pixbuf;
-       } else {
-               g_object_ref (pixbuf);
-       }
-
-       if (empathy_gdk_pixbuf_is_opaque (pixbuf)) {
-               empathy_avatar_pixbuf_roundify (pixbuf);
-       }
+       pixbuf = avatar_pixbuf_from_loader (loader);
 
        g_object_unref (loader);
 
@@ -510,6 +522,164 @@ empathy_pixbuf_avatar_from_contact_scaled (EmpathyContact *contact,
        return empathy_pixbuf_from_avatar_scaled (avatar, width, height);
 }
 
+typedef struct {
+       FolksIndividual *individual;
+       GSimpleAsyncResult *result;
+       guint width;
+       guint height;
+} PixbufAvatarFromIndividualClosure;
+
+static PixbufAvatarFromIndividualClosure *
+pixbuf_avatar_from_individual_closure_new (FolksIndividual    *individual,
+                                          GSimpleAsyncResult *result,
+                                          gint                width,
+                                          gint                height)
+{
+       PixbufAvatarFromIndividualClosure *closure;
+
+       g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL);
+       g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+       closure = g_new0 (PixbufAvatarFromIndividualClosure, 1);
+       closure->individual = g_object_ref (individual);
+       closure->result = g_object_ref (result);
+       closure->width = width;
+       closure->height = height;
+
+       return closure;
+}
+
+static void
+pixbuf_avatar_from_individual_closure_free (
+               PixbufAvatarFromIndividualClosure *closure)
+{
+       g_object_unref (closure->individual);
+       g_object_unref (closure->result);
+       g_free (closure);
+}
+
+static void
+avatar_file_load_contents_cb (GObject      *object,
+                             GAsyncResult *result,
+                             gpointer      user_data)
+{
+       GFile *file = G_FILE (object);
+       PixbufAvatarFromIndividualClosure *closure = user_data;
+       char *data = NULL;
+       gsize data_size;
+       struct SizeData size_data;
+       GError *error = NULL;
+       GdkPixbufLoader *loader = NULL;
+
+       if (!g_file_load_contents_finish (file, result, &data, &data_size,
+                               NULL, &error)) {
+               DEBUG ("failed to load avatar from file: %s",
+                               error->message);
+               g_simple_async_result_set_from_error (closure->result, error);
+               goto out;
+       }
+
+       size_data.width = closure->width;
+       size_data.height = closure->height;
+       size_data.preserve_aspect_ratio = TRUE;
+
+       loader = gdk_pixbuf_loader_new ();
+
+       g_signal_connect (loader, "size-prepared",
+                         G_CALLBACK (pixbuf_from_avatar_size_prepared_cb),
+                         &size_data);
+
+       if (!gdk_pixbuf_loader_write (loader, (guchar *) data, data_size,
+                               &error)) {
+               DEBUG ("Failed to write to pixbuf loader: %s",
+                       error ? error->message : "No error given");
+               g_simple_async_result_set_from_error (closure->result, error);
+               goto out;
+       }
+       if (!gdk_pixbuf_loader_close (loader, &error)) {
+               DEBUG ("Failed to close pixbuf loader: %s",
+                       error ? error->message : "No error given");
+               g_simple_async_result_set_from_error (closure->result, error);
+               goto out;
+       }
+
+       g_simple_async_result_set_op_res_gpointer (closure->result,
+                       avatar_pixbuf_from_loader (loader), g_object_unref);
+
+out:
+       g_simple_async_result_complete (closure->result);
+
+       g_clear_error (&error);
+       g_free (data);
+       tp_clear_object (&loader);
+       pixbuf_avatar_from_individual_closure_free (closure);
+}
+
+void
+empathy_pixbuf_avatar_from_individual_scaled_async (
+               FolksIndividual     *individual,
+               gint                 width,
+               gint                 height,
+               GCancellable        *cancellable,
+               GAsyncReadyCallback  callback,
+               gpointer             user_data)
+{
+       GFile *avatar_file;
+       GSimpleAsyncResult *result;
+       PixbufAvatarFromIndividualClosure *closure;
+
+       result = g_simple_async_result_new (G_OBJECT (individual),
+                       callback, user_data,
+                       empathy_pixbuf_avatar_from_individual_scaled_async);
+
+       avatar_file = folks_avatar_get_avatar (FOLKS_AVATAR (individual));
+       if (avatar_file == NULL)
+               goto out;
+
+       closure = pixbuf_avatar_from_individual_closure_new (individual, result,
+                                                            width, height);
+       if (closure == NULL)
+               goto out;
+
+       g_file_load_contents_async (avatar_file, cancellable,
+                       avatar_file_load_contents_cb, closure);
+
+       g_object_unref (result);
+
+       return;
+
+out:
+       g_simple_async_result_set_op_res_gpointer (result, NULL, NULL);
+       g_simple_async_result_complete (result);
+       g_object_unref (result);
+}
+
+/* Return a ref on the GdkPixbuf */
+GdkPixbuf *
+empathy_pixbuf_avatar_from_individual_scaled_finish (
+               FolksIndividual *individual,
+               GAsyncResult *result,
+               GError **error)
+{
+       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+       gboolean result_valid;
+       GdkPixbuf *pixbuf;
+
+       g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL);
+       g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (simple), NULL);
+
+       if (g_simple_async_result_propagate_error (simple, error))
+               return NULL;
+
+       result_valid = g_simple_async_result_is_valid (result,
+                       G_OBJECT (individual),
+                       empathy_pixbuf_avatar_from_individual_scaled_async);
+       g_return_val_if_fail (result_valid, NULL);
+
+       pixbuf = g_simple_async_result_get_op_res_gpointer (simple);
+       return pixbuf != NULL ? g_object_ref (pixbuf) : NULL;
+}
+
 GdkPixbuf *
 empathy_pixbuf_contact_status_icon (EmpathyContact *contact,
                                   gboolean       show_protocol)
@@ -1394,7 +1564,7 @@ empathy_window_iconify (GtkWindow *window, GtkStatusIcon *status_icon)
 
        gtk_status_icon_get_geometry (status_icon, NULL, &icon_location, NULL);
        gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
-       dpy = gdk_x11_drawable_get_xdisplay (gdk_window);
+       dpy = GDK_WINDOW_XDISPLAY (gdk_window);
 
        data[0] = icon_location.x;
        data[1] = icon_location.y;
@@ -1404,7 +1574,7 @@ empathy_window_iconify (GtkWindow *window, GtkStatusIcon *status_icon)
        XChangeProperty (dpy,
                         GDK_WINDOW_XID (gdk_window),
                         gdk_x11_get_xatom_by_name_for_display (
-                               gdk_drawable_get_display (gdk_window),
+                               gdk_window_get_display (gdk_window),
                         "_NET_WM_ICON_GEOMETRY"),
                         XA_CARDINAL, 32, PropModeReplace,
                         (guchar *)&data, 4);
@@ -1440,7 +1610,11 @@ empathy_window_present_with_time (GtkWindow *window,
                        gtk_widget_hide (GTK_WIDGET (window));
        }
 
-       gtk_window_present_with_time (window, timestamp);
+       if (timestamp == GDK_CURRENT_TIME)
+               gtk_window_present (window);
+       else
+               gtk_window_present_with_time (window, timestamp);
+
        gtk_window_set_skip_taskbar_hint (window, FALSE);
        gtk_window_deiconify (window);
 }
@@ -1448,7 +1622,7 @@ empathy_window_present_with_time (GtkWindow *window,
 void
 empathy_window_present (GtkWindow *window)
 {
-  empathy_window_present_with_time (window, GDK_CURRENT_TIME);
+  empathy_window_present_with_time (window, gtk_get_current_event_time ());
 }
 
 GtkWindow *
@@ -1694,7 +1868,7 @@ empathy_receive_file_with_file_chooser (EmpathyFTHandler *handler)
        g_assert (contact != NULL);
 
        title = g_strdup_printf (_("Incoming file from %s"),
-               empathy_contact_get_name (contact));
+               empathy_contact_get_alias (contact));
 
        widget = gtk_file_chooser_dialog_new (title,
                                              NULL,