--- a/pidgin/gtkmedia.c Sat Apr 13 23:08:29 2024 -0500
+++ b/pidgin/gtkmedia.c Sat Apr 13 23:52:51 2024 -0500
@@ -470,18 +470,12 @@
pidgin_request_timeout_cb(PidginMedia *gtkmedia)
PurpleMediaSessionType type;
account = purple_media_get_account(gtkmedia->priv->media);
- buddy = purple_blist_find_buddy(account, gtkmedia->priv->screenname);
- alias = purple_buddy_get_contact_alias(buddy);
- alias = gtkmedia->priv->screenname;
+ alias = gtkmedia->priv->screenname; type = gtkmedia->priv->request_type;
gtkmedia->priv->timeout_id = 0;
@@ -887,20 +881,15 @@
pidgin_media_new_cb(G_GNUC_UNUSED PurpleMediaManager *manager,
- PurpleMedia *media, PurpleAccount *account,
+ G_GNUC_UNUSED PurpleAccount *account, char *screenname, G_GNUC_UNUSED gpointer data)
PidginMedia *gtkmedia = NULL;
- PurpleBuddy *buddy = NULL;
const gchar *alias = NULL;
gtkmedia = PIDGIN_MEDIA(pidgin_media_new(media, screenname));
- buddy = purple_blist_find_buddy(account, screenname);
- alias = purple_buddy_get_contact_alias(buddy);
gtk_window_set_title(GTK_WINDOW(gtkmedia), alias);
gtk_widget_set_visible(GTK_WIDGET(gtkmedia),
--- a/pidgin/gtkwhiteboard.c Sat Apr 13 23:08:29 2024 -0500
+++ b/pidgin/gtkwhiteboard.c Sat Apr 13 23:52:51 2024 -0500
@@ -473,7 +473,6 @@
pidgin_whiteboard_create(PurpleWhiteboard *wb)
gtkwb = g_object_new(PIDGIN_TYPE_WHITEBOARD, NULL);
@@ -495,16 +494,10 @@
gtkwb->brush_color = 0xff0000;
- /* Try and set window title as the name of the buddy, else just use
+ /* Set the window title to the id of the whiteboard as we can't test - buddy = purple_blist_find_buddy(purple_whiteboard_get_account(wb),
- purple_whiteboard_get_id(wb));
- gtk_window_set_title(GTK_WINDOW(gtkwb),
- ? purple_buddy_get_contact_alias(buddy)
- : purple_whiteboard_get_id(wb));
+ gtk_window_set_title(GTK_WINDOW(gtkwb), purple_whiteboard_get_id(wb)); gtk_widget_set_name(GTK_WIDGET(gtkwb), purple_whiteboard_get_id(wb));
gtk_widget_set_size_request(GTK_WIDGET(gtkwb->drawing_area),
--- a/pidgin/pidginaccounteditor.c Sat Apr 13 23:08:29 2024 -0500
+++ b/pidgin/pidginaccounteditor.c Sat Apr 13 23:52:51 2024 -0500
@@ -243,18 +243,15 @@
pidgin_account_editor_update_user_options(PidginAccountEditor *editor,
- PurpleProtocol *protocol)
+ G_GNUC_UNUSED PurpleProtocol *protocol) - PurpleBuddyIconSpec *icon_spec = NULL;
PurpleImage *image = NULL;
gboolean show_avatar_opts = TRUE;
const gchar *svalue = "";
gboolean use_global = TRUE;
/* Check if the protocol supports avatars. */
- icon_spec = purple_protocol_get_icon_spec(protocol);
- show_avatar_opts = (icon_spec != NULL && icon_spec->format != NULL);
- purple_buddy_icon_spec_free(icon_spec);
+ show_avatar_opts = FALSE; gtk_widget_set_visible(editor->avatar_row, show_avatar_opts);
--- a/pidgin/pidginavatar.c Sat Apr 13 23:08:29 2024 -0500
+++ b/pidgin/pidginavatar.c Sat Apr 13 23:52:51 2024 -0500
@@ -33,14 +33,14 @@
GdkPixbufAnimation *animation;
+ PurpleContactInfo *info; PurpleConversation *conversation;
@@ -51,72 +51,20 @@
/******************************************************************************
*****************************************************************************/
-pidgin_avatar_get_effective_buddy(PidginAvatar *avatar) {
- PurpleBuddy *buddy = NULL;
- if(PURPLE_IS_BUDDY(avatar->buddy)) {
- buddy = PURPLE_BUDDY(avatar->buddy);
-static GdkPixbufAnimation *
-pidgin_avatar_find_buddy_icon(PurpleBuddy *buddy,
- G_GNUC_UNUSED PurpleConversation *conversation)
- GdkPixbufAnimation *ret = NULL;
- GInputStream *stream = NULL;
- PurpleMetaContact *contact = NULL;
- g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
- /* First check if our user has set a custom icon for this buddy. */
- contact = purple_buddy_get_contact(buddy);
- if(PURPLE_IS_META_CONTACT(contact)) {
- PurpleBlistNode *node = PURPLE_BLIST_NODE(contact);
- PurpleImage *custom_image = NULL;
- custom_image = purple_buddy_icons_node_find_custom_icon(node);
- if(PURPLE_IS_IMAGE(custom_image)) {
- gconstpointer data = purple_image_get_data(custom_image);
- gsize length = purple_image_get_data_size(custom_image);
- stream = g_memory_input_stream_new_from_data(data, (gssize)length,
- /* If there is no custom icon, fall back to checking if the buddy has an
- if(!G_IS_INPUT_STREAM(stream)) {
- PurpleBuddyIcon *icon = purple_buddy_get_icon(buddy);
- stream = purple_buddy_icon_get_stream(icon);
- if(G_IS_INPUT_STREAM(stream)) {
- ret = gdk_pixbuf_animation_new_from_stream(stream, NULL, NULL);
- g_clear_object(&stream);
pidgin_avatar_update(PidginAvatar *avatar) {
- PurpleBuddy *buddy = NULL;
+ PurpleAvatar *purple_avatar = NULL; GdkPixbufAnimation *animation = NULL;
GdkPixbuf *pixbuf = NULL;
- buddy = pidgin_avatar_get_effective_buddy(avatar);
- if(PURPLE_IS_BUDDY(buddy)) {
- animation = pidgin_avatar_find_buddy_icon(buddy,
+ if(PURPLE_IS_CONTACT_INFO(avatar->info)) { + purple_avatar = purple_contact_info_get_avatar(avatar->info); + } else if(PURPLE_IS_CONVERSATION(avatar->conversation)) { + purple_avatar = purple_conversation_get_avatar(avatar->conversation); + if(PURPLE_IS_AVATAR(purple_avatar)) { + animation = purple_avatar_get_animation(purple_avatar); g_set_object(&avatar->animation, animation);
@@ -138,187 +86,7 @@
/******************************************************************************
*****************************************************************************/
-pidgin_avatar_save_dialog_cb(GObject *source, GAsyncResult *result,
- PidginAvatar *avatar = data;
- PurpleBuddy *buddy = NULL;
- PurpleBuddyIcon *icon = NULL;
- GtkFileDialog *dialog = GTK_FILE_DIALOG(source);
- file = gtk_file_dialog_save_finish(dialog, result, &error);
- g_warning("failed to select custom avatar destination: %s",
- buddy = pidgin_avatar_get_effective_buddy(avatar);
- if(!PURPLE_IS_BUDDY(buddy)) {
- icon = purple_buddy_get_icon(buddy);
- filename = g_file_get_path(file);
- purple_buddy_icon_save_to_filename(icon, filename, NULL);
-pidgin_avatar_save_cb(G_GNUC_UNUSED GSimpleAction *action,
- G_GNUC_UNUSED GVariant *parameter, gpointer data)
- PidginAvatar *avatar = PIDGIN_AVATAR(data);
- PurpleBuddy *buddy = NULL;
- PurpleBuddyIcon *icon = NULL;
- PurpleAccount *account = NULL;
- GtkFileDialog *dialog = NULL;
- GtkWindow *window = NULL;
- const gchar *ext = NULL, *name = NULL;
- gchar *filename = NULL;
- buddy = pidgin_avatar_get_effective_buddy(avatar);
- icon = purple_buddy_get_icon(buddy);
- ext = purple_buddy_icon_get_extension(icon);
- account = purple_buddy_get_account(buddy);
- name = purple_buddy_get_name(buddy);
- filename = g_strdup_printf("%s.%s", purple_normalize(account, name),
- filename = g_strdup(purple_normalize(account, name));
- window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(avatar)));
- dialog = gtk_file_dialog_new();
- gtk_file_dialog_set_title(dialog, _("Save Avatar"));
- gtk_file_dialog_set_modal(dialog, TRUE);
- gtk_file_dialog_set_initial_name(dialog, filename);
- gtk_file_dialog_save(dialog, window, NULL, pidgin_avatar_save_dialog_cb,
- g_clear_object(&dialog);
-pidgin_avatar_set_custom_dialog_cb(GObject *source, GAsyncResult *result,
- PidginAvatar *avatar = data;
- PurpleBuddy *buddy = NULL;
- GtkFileDialog *dialog = GTK_FILE_DIALOG(source);
- gchar *filename = NULL;
- file = gtk_file_dialog_open_finish(dialog, result, &error);
- g_message("failed to select custom avatar: %s", error->message);
- buddy = pidgin_avatar_get_effective_buddy(avatar);
- if(!PURPLE_IS_BUDDY(buddy)) {
- filename = g_file_get_path(file);
- PurpleMetaContact *contact = purple_buddy_get_contact(buddy);
- PurpleBlistNode *node = PURPLE_BLIST_NODE(contact);
- purple_buddy_icons_node_set_custom_icon_from_file(node, filename);
- pidgin_avatar_update(avatar);
- g_clear_pointer(&filename, g_free);
-pidgin_avatar_set_custom_cb(G_GNUC_UNUSED GSimpleAction *action,
- G_GNUC_UNUSED GVariant *parameter, gpointer data)
- PidginAvatar *avatar = PIDGIN_AVATAR(data);
- GtkFileDialog *dialog = NULL;
- GtkWindow *window = NULL;
- window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(avatar)));
- dialog = gtk_file_dialog_new();
- gtk_file_dialog_set_title(dialog, _("Set Custom Avatar"));
- gtk_file_dialog_set_accept_label(dialog, _("Set Custom"));
- gtk_file_dialog_set_modal(dialog, TRUE);
- gtk_file_dialog_open(dialog, window, NULL,
- pidgin_avatar_set_custom_dialog_cb, avatar);
- g_clear_object(&dialog);
-pidgin_avatar_clear_custom_cb(G_GNUC_UNUSED GSimpleAction *action,
- G_GNUC_UNUSED GVariant *parameter, gpointer data)
- PidginAvatar *avatar = PIDGIN_AVATAR(data);
- PurpleBuddy *buddy = NULL;
- buddy = pidgin_avatar_get_effective_buddy(avatar);
- if(PURPLE_IS_BUDDY(buddy)) {
- PurpleMetaContact *contact = purple_buddy_get_contact(buddy);
- PurpleBlistNode *node = PURPLE_BLIST_NODE(contact);
- purple_buddy_icons_node_set_custom_icon_from_file(node, NULL);
- pidgin_avatar_update(avatar);
-static GActionEntry actions[] = {
- .activate = pidgin_avatar_save_cb,
- .name = "set-custom-avatar",
- .activate = pidgin_avatar_set_custom_cb,
- .name = "clear-custom-avatar",
- .activate = pidgin_avatar_clear_custom_cb,
+static GActionEntry actions[] = {}; /******************************************************************************
@@ -344,14 +112,16 @@
- * This function is a callback for when properties change on the buddy we're
- * tracking. It should not be reused for the conversation we're tracking
+ * This function is a callback for when properties change on the contact info + * we're tracking. It should not be reused for the conversation we're tracking * because we have to disconnect old handlers and reuse of this function will
- * cause issues if a buddy is changed but a conversation is not and vice versa.
+ * cause issues if a contact info is changed but a conversation is not and vice -pidgin_avatar_buddy_icon_updated(G_GNUC_UNUSED GObject *obj,
- G_GNUC_UNUSED GParamSpec *pspec, gpointer d)
+pidgin_avatar_contact_info_updated(G_GNUC_UNUSED GObject *obj, + G_GNUC_UNUSED GParamSpec *pspec, PidginAvatar *avatar = PIDGIN_AVATAR(d);
@@ -410,8 +180,8 @@
g_value_set_boolean(value, pidgin_avatar_get_animate(avatar));
- g_value_set_object(value, pidgin_avatar_get_buddy(avatar));
+ case PROP_CONTACT_INFO: + g_value_set_object(value, pidgin_avatar_get_contact_info(avatar)); g_value_set_object(value, pidgin_avatar_get_conversation(avatar));
@@ -432,8 +202,8 @@
pidgin_avatar_set_animate(avatar, g_value_get_boolean(value));
- pidgin_avatar_set_buddy(avatar, g_value_get_object(value));
+ case PROP_CONTACT_INFO: + pidgin_avatar_set_contact_info(avatar, g_value_get_object(value)); pidgin_avatar_set_conversation(avatar, g_value_get_object(value));
@@ -448,8 +218,8 @@
pidgin_avatar_dispose(GObject *obj) {
PidginAvatar *avatar = PIDGIN_AVATAR(obj);
- pidgin_avatar_set_buddy(avatar, NULL);
- pidgin_avatar_set_conversation(avatar, NULL);
+ g_clear_object(&avatar->info); + g_clear_object(&avatar->conversation); g_clear_object(&avatar->animation);
@@ -495,26 +265,26 @@
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ * PidginAvatar:contact-info: - * The buddy whose avatar will be displayed.
+ * The contact info whose avatar will be displayed. - properties[PROP_BUDDY] = g_param_spec_object(
- "The buddy whose avatar to display",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ properties[PROP_CONTACT_INFO] = g_param_spec_object( + "contact-info", "contact-info", + "The contact info whose avatar to display", + PURPLE_TYPE_CONTACT_INFO, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); * PidginAvatar:conversation:
- * The conversation which will be used to find the correct buddy.
+ * The conversation which will be used to find the correct avatar. properties[PROP_CONVERSATION] = g_param_spec_object(
"conversation", "conversation",
- "The conversation used to find the correct buddy.",
+ "The conversation used to find the correct avatar.", PURPLE_TYPE_CONVERSATION,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -571,34 +341,36 @@
-pidgin_avatar_set_buddy(PidginAvatar *avatar, PurpleBuddy *buddy) {
+pidgin_avatar_set_contact_info(PidginAvatar *avatar, PurpleContactInfo *info) { g_return_if_fail(PIDGIN_IS_AVATAR(avatar));
/* Remove our old signal handler. */
- if(PURPLE_IS_BUDDY(avatar->buddy)) {
- g_signal_handlers_disconnect_by_func(avatar->buddy,
- pidgin_avatar_buddy_icon_updated,
+ if(PURPLE_IS_CONTACT_INFO(avatar->info)) { + g_signal_handlers_disconnect_by_func(avatar->info, + pidgin_avatar_contact_info_updated, - if(g_set_object(&avatar->buddy, buddy)) {
+ if(g_set_object(&avatar->info, info)) { pidgin_avatar_update(avatar);
- g_object_notify_by_pspec(G_OBJECT(avatar), properties[PROP_BUDDY]);
+ g_object_notify_by_pspec(G_OBJECT(avatar), + properties[PROP_CONTACT_INFO]); /* Add the notify signal so we can update when the icon changes. */
- if(PURPLE_IS_BUDDY(avatar->buddy)) {
- g_signal_connect(G_OBJECT(avatar->buddy), "notify::icon",
- G_CALLBACK(pidgin_avatar_buddy_icon_updated), avatar);
+ if(PURPLE_IS_CONTACT_INFO(avatar->info)) { + g_signal_connect_object(G_OBJECT(avatar->info), "notify::avatar", + G_CALLBACK(pidgin_avatar_contact_info_updated),
-pidgin_avatar_get_buddy(PidginAvatar *avatar) {
+pidgin_avatar_get_contact_info(PidginAvatar *avatar) { g_return_val_if_fail(PIDGIN_IS_AVATAR(avatar), NULL);
@@ -621,8 +393,9 @@
/* Add the notify signal so we can update when the icon changes. */
if(PURPLE_IS_CONVERSATION(avatar->conversation)) {
- g_signal_connect(G_OBJECT(avatar->conversation), "notify",
- G_CALLBACK(pidgin_avatar_conversation_updated), avatar);
+ g_signal_connect_object(G_OBJECT(avatar->conversation), "notify", + G_CALLBACK(pidgin_avatar_conversation_updated), --- a/pidgin/pidginavatar.h Sat Apr 13 23:08:29 2024 -0500
+++ b/pidgin/pidginavatar.h Sat Apr 13 23:52:51 2024 -0500
@@ -91,37 +91,38 @@
gboolean pidgin_avatar_get_animate(PidginAvatar *avatar);
- * pidgin_avatar_set_buddy:
+ * pidgin_avatar_set_contact_info: * @avatar: The #PidginAvatar instance.
- * @buddy: (nullable): The #PurpleBuddy to set or %NULL to unset.
+ * @info: (nullable): A contact info or %NULL to unset. - * Sets or unsets the #PurpleBuddy that @avatar should use for display.
+ * Sets or unsets the [class@Purple.ContactInfo] that @avatar should use for -void pidgin_avatar_set_buddy(PidginAvatar *avatar, PurpleBuddy *buddy);
+void pidgin_avatar_set_contact_info(PidginAvatar *avatar, PurpleContactInfo *info); - * pidgin_avatar_get_buddy:
+ * pidgin_avatar_get_contact_info: * @avatar: The #PidginAvatar instance.
- * Gets the #PurpleBuddy that @avatar is using for display.
+ * Gets the [class@Purple.ContactInfo] that @avatar is using for display. - * Returns: (transfer none): The #PurpleBuddy that @avatar is using for display.
+ * Returns: (transfer none): The contact info if set, otherwise %NULL. -PurpleBuddy *pidgin_avatar_get_buddy(PidginAvatar *avatar);
+PurpleContactInfo *pidgin_avatar_get_contact_info(PidginAvatar *avatar); * pidgin_avatar_set_conversation:
* @avatar: The #PidginAvatar instance.
- * @conversation: (nullable): The #PurpleConversation to set or %NULL to unset.
+ * @conversation: (nullable): The conversation to set or %NULL to unset. - * Sets or unsets the #PurpleConversation that @avatar uses to find the
- * #PurpleBuddy whose icon to display.
+ * Sets or unsets the conversation that @avatar uses to find the + * [class@Purple.Avatar] to display. @@ -134,8 +135,8 @@
* Gets the #PurpleConversation that @avatar is using for display.
- * Returns: (transfer none): The #PurpleConversation that @avatar is using to
- * find the #PurpleBuddy whose icon to display.
+ * Returns: (transfer none): The conversation that @avatar is using to + * find the [class@Purple.Avatar] to display. --- a/pidgin/pidgincontactlist.c Sat Apr 13 23:08:29 2024 -0500
+++ b/pidgin/pidgincontactlist.c Sat Apr 13 23:52:51 2024 -0500
@@ -179,9 +179,6 @@
PurpleAvatar *avatar = NULL;
PurpleContactInfo *info = NULL;
- PurpleContact *contact = NULL;
- PurpleBuddyIcon *icon = NULL;
- GdkTexture *texture = NULL;
/* When filtering we get called for rows that have been filtered out. We
* also get called during finalization. I'm not sure why either of these
@@ -205,34 +202,7 @@
- /* All of the contact info in the manager are PurpleContact's so this cast
- contact = PURPLE_CONTACT(info);
- icon = purple_buddy_icons_find(purple_contact_get_account(contact),
- purple_contact_info_get_username(info));
- gconstpointer data = NULL;
- data = purple_buddy_icon_get_data(icon, &size);
- bytes = g_bytes_new(data, size);
- texture = gdk_texture_new_from_bytes(bytes, &error);
- g_warning("Failed to create texture: %s", error->message);