/* * Copyright (C) 2010 - 2011, Robert Ancell * Copyright (C) 2011, Gunnar Hjalmarsson * Copyright (C) 2012 - 2013, Lionel Le Folgoc * Copyright (C) 2012, Julien Lavergne * Copyright (C) 2013 - 2015, Simon Steinbeiß * Copyright (C) 2013 - 2020, Sean Davis * Copyright (C) 2014, Andrew P. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. See http://www.gnu.org/copyleft/gpl.html the full text of the * license. */ #include #include "greeterconfiguration.h" #include "greeteruserimage.h" #define USER_IMAGE_SIZE 80 #define LOGGED_IN_EMBLEM_SIZE 20 #define LOGGED_IN_EMBLEM_ICON "emblem-default" #define VALUE_IS_ICON_PATH(v) (v[0] == '/') #define VALUE_ICON_PATH(v) (v) #define VALUE_IS_ICON_NAME(v) (v[0] == '#') #define VALUE_ICON_NAME(v) (v + 1) static GdkPixbuf * round_image (GdkPixbuf *pixbuf) { GdkPixbuf *dest = NULL; cairo_surface_t *surface; cairo_t *cr; gint size; size = gdk_pixbuf_get_width (pixbuf); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, size, size); cr = cairo_create (surface); /* Clip a circle */ cairo_arc (cr, size/2, size/2, size/2, 0, 2 * G_PI); cairo_clip (cr); cairo_new_path (cr); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); cairo_paint (cr); dest = gdk_pixbuf_get_from_surface (surface, 0, 0, size, size); cairo_surface_destroy (surface); cairo_destroy (cr); return dest; } static GdkPixbuf * logged_in_pixbuf (GdkPixbuf *pixbuf) { GdkPixbuf *composite = NULL, *emblem = NULL; gint width, height; GError *error = NULL; emblem = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), LOGGED_IN_EMBLEM_ICON, LOGGED_IN_EMBLEM_SIZE, GTK_ICON_LOOKUP_FORCE_SIZE, &error); if (!emblem) { g_warning ("Failed to load the logged icon: %s", error->message); g_clear_error (&error); return NULL; } composite = gdk_pixbuf_copy (pixbuf); width = gdk_pixbuf_get_width (composite); height = gdk_pixbuf_get_height (composite); gdk_pixbuf_composite (emblem, composite, width - LOGGED_IN_EMBLEM_SIZE, height - LOGGED_IN_EMBLEM_SIZE, LOGGED_IN_EMBLEM_SIZE, LOGGED_IN_EMBLEM_SIZE, width - LOGGED_IN_EMBLEM_SIZE, height - LOGGED_IN_EMBLEM_SIZE, 1.0, 1.0, GDK_INTERP_BILINEAR, 255); g_object_unref (emblem); return composite; } static GdkPixbuf * get_default_user_image_from_settings (void) { GdkPixbuf *image = NULL; gchar *value = NULL; GError *error = NULL; value = config_get_string (NULL, CONFIG_KEY_DEFAULT_USER_IMAGE, NULL); if (!value) return NULL; if (VALUE_IS_ICON_PATH(value)) { image = gdk_pixbuf_new_from_file_at_scale (VALUE_ICON_PATH(value), USER_IMAGE_SIZE, USER_IMAGE_SIZE, FALSE, &error); if (!image) { g_warning ("Failed to load default user image from path: %s", error->message); g_clear_error (&error); } } else if (VALUE_IS_ICON_NAME(value)) { image = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), VALUE_ICON_NAME(value), USER_IMAGE_SIZE, GTK_ICON_LOOKUP_FORCE_SIZE, &error); if (!image) { g_warning ("Failed to load default user image from icon theme: %s", error->message); g_clear_error (&error); } } g_free (value); return image; } static GdkPixbuf * get_default_user_image (void) { GdkPixbuf *temp_image = NULL, *image = NULL; GError *error = NULL; /* If a file is set by preferences, it must be prioritized. */ image = get_default_user_image_from_settings (); /* Fallback to avatar-default icon from theme */ if (!image) { image = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "avatar-default", USER_IMAGE_SIZE, GTK_ICON_LOOKUP_FORCE_SIZE, &error); if (error != NULL) { g_warning ("Failed to load fallback user image: %s", error->message); g_clear_error (&error); } } /* Fallback again to old stock_person icon from theme */ if (!image) { image = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "stock_person", USER_IMAGE_SIZE, GTK_ICON_LOOKUP_FORCE_SIZE, &error); if (error != NULL) { g_warning ("Failed to load old fallback user image: %s", error->message); g_clear_error (&error); } } return image; } GdkPixbuf * greeter_get_user_image (const gchar *username) { LightDMUser *user = NULL; GdkPixbuf *temp_image = NULL, *image = NULL; GError *error = NULL; gboolean logged_in = FALSE; const gchar *path; if (username) { user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username); } if (user) { path = lightdm_user_get_image (user); if (path) { image = gdk_pixbuf_new_from_file_at_scale (path, USER_IMAGE_SIZE, USER_IMAGE_SIZE, FALSE, &error); if (!image) { g_debug ("Failed to load user image: %s", error->message); g_clear_error (&error); } } logged_in = lightdm_user_get_logged_in (user); } /* Fallback to default icon */ if (!image) { image = get_default_user_image (); } if (image && config_get_bool (NULL, CONFIG_KEY_ROUND_USER_IMAGE, TRUE)) { temp_image = round_image (image); if (temp_image != NULL) { g_object_unref (image); image = temp_image; } } if (image && logged_in && config_get_bool (NULL, CONFIG_KEY_HIGHLIGHT_LOGGED_USER, TRUE)) { temp_image = logged_in_pixbuf (image); if (temp_image != NULL) { g_object_unref (image); image = temp_image; } } return image; }