user-accounts: port to libaccountsservice

This removes a bunch of duplicated code, and also drops
a direct dependency on libsystemd-login.

https://bugzilla.gnome.org/show_bug.cgi?id=671858
This commit is contained in:
Ryan Lortie 2012-12-04 12:48:57 -05:00 committed by Ray Strode
parent db97299e74
commit d46a23a5a2
18 changed files with 468 additions and 2199 deletions

View file

@ -107,6 +107,7 @@ SCHEMAS_REQUIRED_VERSION=3.7.2.2
LIBWACOM_REQUIRED_VERSION=0.7
CLUTTER_REQUIRED_VERSION=1.11.3
GOA_REQUIRED_VERSION=3.5.90
ACCOUNTSSERVICE_REQUIRED_VERSION=0.6.30
COMMON_MODULES="gtk+-3.0 >= $GTK_REQUIRED_VERSION
glib-2.0 >= $GLIB_REQUIRED_VERSION
@ -161,7 +162,7 @@ PKG_CHECK_MODULES(USER_ACCOUNTS_PANEL, $COMMON_MODULES
gnome-desktop-3.0
gdk-pixbuf-2.0 >= $GDKPIXBUF_REQUIRED_VERSION
pwquality
libsystemd-login)
accountsservice >= $ACCOUNTSSERVICE_REQUIRED_VERSION)
PKG_CHECK_MODULES(GVC, gobject-2.0 libpulse libpulse-mainloop-glib)
AM_CONDITIONAL(HAVE_INTROSPECTION, false)

View file

@ -29,10 +29,6 @@ BUILT_SOURCES = \
libuser_accounts_la_SOURCES = \
um-account-type.h \
um-account-type.c \
um-user.h \
um-user.c \
um-user-manager.h \
um-user-manager.c \
um-account-dialog.h \
um-account-dialog.c \
um-password-dialog.h \
@ -87,10 +83,6 @@ frob_account_dialog_SOURCES = \
um-account-dialog.c \
um-realm-manager.c \
um-realm-manager.h \
um-user.h \
um-user.c \
um-user-manager.c \
um-user-manager.h \
um-utils.h \
um-utils.c \
$(BUILT_SOURCES)

View file

@ -27,13 +27,13 @@ on_dialog_complete (GObject *object,
gpointer user_data)
{
GMainLoop *loop = user_data;
UmUser *user;
ActUser *user;
user = um_account_dialog_finish (UM_ACCOUNT_DIALOG (object), result);
if (user == NULL) {
g_printerr ("No user created\n");
} else {
g_printerr ("User created: %s\n", um_user_get_user_name (user));
g_printerr ("User created: %s\n", act_user_get_user_name (user));
g_object_unref (user);
}

View file

@ -24,10 +24,10 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <act/act.h>
#include "um-account-dialog.h"
#include "um-realm-manager.h"
#include "um-user-manager.h"
#include "um-utils.h"
typedef enum {
@ -149,7 +149,7 @@ finish_action (UmAccountDialog *self)
static void
complete_dialog (UmAccountDialog *self,
UmUser *user)
ActUser *user)
{
if (user != NULL) {
g_simple_async_result_set_op_res_gpointer (self->async,
@ -162,11 +162,11 @@ complete_dialog (UmAccountDialog *self,
}
static void
create_user_done (UmUserManager *manager,
create_user_done (ActUserManager *manager,
GAsyncResult *res,
UmAccountDialog *self)
{
UmUser *user;
ActUser *user;
GError *error;
finish_action (self);
@ -174,14 +174,16 @@ create_user_done (UmUserManager *manager,
/* Note that user is returned without an extra reference */
error = NULL;
if (!um_user_manager_create_user_finish (manager, res, &user, &error)) {
user = act_user_manager_create_user_finish (manager, res, &error);
if (user == NULL) {
g_debug ("Failed to create user: %s", error->message);
if (!g_error_matches (error, UM_USER_MANAGER_ERROR, UM_USER_MANAGER_ERROR_PERMISSION_DENIED))
if (!g_error_matches (error, ACT_USER_MANAGER_ERROR, ACT_USER_MANAGER_ERROR_PERMISSION_DENIED))
show_error_dialog (self, _("Failed to add account"), error);
g_error_free (error);
gtk_widget_grab_focus (self->local_name);
} else {
g_debug ("Created user: %s", um_user_get_user_name (user));
g_debug ("Created user: %s", act_user_get_user_name (user));
complete_dialog (self, user);
}
}
@ -189,7 +191,7 @@ create_user_done (UmUserManager *manager,
static void
local_create_user (UmAccountDialog *self)
{
UmUserManager *manager;
ActUserManager *manager;
const gchar *username;
const gchar *name;
gint account_type;
@ -206,16 +208,14 @@ local_create_user (UmAccountDialog *self)
g_debug ("Creating local user: %s", username);
manager = um_user_manager_ref_default ();
um_user_manager_create_user (manager,
username,
name,
account_type,
self->cancellable,
(GAsyncReadyCallback)create_user_done,
self,
NULL);
g_object_unref (manager);
manager = act_user_manager_get_default ();
act_user_manager_create_user_async (manager,
username,
name,
account_type,
self->cancellable,
(GAsyncReadyCallback)create_user_done,
self);
}
static gboolean
@ -389,14 +389,13 @@ on_register_user (GObject *source,
{
UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
GError *error = NULL;
UmUser *user = NULL;
ActUser *user;
um_user_manager_cache_user_finish (UM_USER_MANAGER (source),
result, &user, &error);
user = act_user_manager_cache_user_finish (ACT_USER_MANAGER (source), result, &error);
/* This is where we're finally done */
if (error == NULL) {
g_debug ("Successfully cached remote user: %s", um_user_get_user_name (user));
if (user != NULL) {
g_debug ("Successfully cached remote user: %s", act_user_get_user_name (user));
finish_action (self);
complete_dialog (self, user);
@ -406,6 +405,8 @@ on_register_user (GObject *source,
finish_action (self);
g_error_free (error);
}
g_object_unref (self);
}
static void
@ -415,7 +416,7 @@ on_permit_user_login (GObject *source,
{
UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
UmRealmCommon *common;
UmUserManager *manager;
ActUserManager *manager;
GError *error = NULL;
gchar *login;
@ -428,18 +429,16 @@ on_permit_user_login (GObject *source,
* should also lookup information about this via the realm and make
* sure all that is functional.
*/
manager = um_user_manager_ref_default ();
manager = act_user_manager_get_default ();
login = um_realm_calculate_login (common, gtk_entry_get_text (self->enterprise_login));
g_return_if_fail (login != NULL);
g_debug ("Caching remote user: %s", login);
um_user_manager_cache_user (manager, login, self->cancellable,
on_register_user, g_object_ref (self),
g_object_unref);
act_user_manager_cache_user_async (manager, login, self->cancellable,
on_register_user, g_object_ref (self));
g_free (login);
g_object_unref (manager);
} else {
show_error_dialog (self, _("Failed to register account"), error);
@ -1192,11 +1191,11 @@ um_account_dialog_show (UmAccountDialog *self,
gtk_widget_grab_focus (self->local_name);
}
UmUser *
ActUser *
um_account_dialog_finish (UmAccountDialog *self,
GAsyncResult *result)
{
UmUser *user;
ActUser *user;
g_return_val_if_fail (UM_IS_ACCOUNT_DIALOG (self), NULL);
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),

View file

@ -22,8 +22,8 @@
#ifndef __UM_ACCOUNT_DIALOG_H__
#define __UM_ACCOUNT_DIALOG_H__
#include <act/act.h>
#include <gtk/gtk.h>
#include "um-user.h"
G_BEGIN_DECLS
@ -40,7 +40,7 @@ void um_account_dialog_show (UmAccountDialog *self,
GtkWindow *parent,
GAsyncReadyCallback callback,
gpointer user_data);
UmUser * um_account_dialog_finish (UmAccountDialog *self,
ActUser * um_account_dialog_finish (UmAccountDialog *self,
GAsyncResult *result);
G_END_DECLS

View file

@ -256,7 +256,7 @@ static void
delete_fingerprints_question (GtkWindow *parent,
GtkWidget *label1,
GtkWidget *label2,
UmUser *user)
ActUser *user)
{
GtkWidget *question;
GtkWidget *button;
@ -628,7 +628,7 @@ static void
enroll_fingerprints (GtkWindow *parent,
GtkWidget *label1,
GtkWidget *label2,
UmUser *user)
ActUser *user)
{
GDBusProxy *device;
GtkBuilder *dialog;
@ -766,7 +766,7 @@ void
fingerprint_button_clicked (GtkWindow *parent,
GtkWidget *label1,
GtkWidget *label2,
UmUser *user)
ActUser *user)
{
bindtextdomain ("fprintd", GNOMELOCALEDIR);
bind_textdomain_codeset ("fprintd", "UTF-8");

View file

@ -18,11 +18,11 @@
*/
#include <gtk/gtk.h>
#include "um-user.h"
#include <act/act.h>
gboolean set_fingerprint_label (GtkWidget *label1,
GtkWidget *label2);
void fingerprint_button_clicked (GtkWindow *parent,
GtkWidget *label1,
GtkWidget *label2,
UmUser *user);
ActUser *user);

View file

@ -29,9 +29,9 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <act/act.h>
#include "um-password-dialog.h"
#include "um-user-manager.h"
#include "um-utils.h"
#include "run-passwd.h"
#include "pw-utils.h"
@ -51,7 +51,7 @@ struct _UmPasswordDialog {
GtkWidget *show_password_button;
GtkWidget *ok_button;
UmUser *user;
ActUser *user;
GtkWidget *old_password_label;
GtkWidget *old_password_entry;
@ -205,26 +205,51 @@ accept_password_dialog (GtkButton *button,
password = gtk_entry_get_text (GTK_ENTRY (um->password_entry));
hint = gtk_entry_get_text (GTK_ENTRY (um->normal_hint_entry));
if (mode == UM_PASSWORD_DIALOG_MODE_NORMAL && um_user_get_uid (um->user) == getuid ()) {
GdkDisplay *display;
GdkCursor *cursor;
switch (mode) {
case UM_PASSWORD_DIALOG_MODE_NORMAL:
if (act_user_get_uid (um->user) == getuid ()) {
GdkDisplay *display;
GdkCursor *cursor;
/* When setting a password for the current user,
* use passwd directly, to preserve the audit trail
* and to e.g. update the keyring password.
*/
passwd_change_password (um->passwd_handler, password, (PasswdCallback) password_changed_cb, um);
gtk_widget_set_sensitive (um->dialog, FALSE);
display = gtk_widget_get_display (um->dialog);
cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
gdk_window_set_cursor (gtk_widget_get_window (um->dialog), cursor);
gdk_display_flush (display);
g_object_unref (cursor);
}
else {
um_user_set_password (um->user, mode, password, hint);
finish_password_change (um);
/* When setting a password for the current user,
* use passwd directly, to preserve the audit trail
* and to e.g. update the keyring password.
*/
passwd_change_password (um->passwd_handler, password,
(PasswdCallback) password_changed_cb, um);
gtk_widget_set_sensitive (um->dialog, FALSE);
display = gtk_widget_get_display (um->dialog);
cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
gdk_window_set_cursor (gtk_widget_get_window (um->dialog), cursor);
gdk_display_flush (display);
g_object_unref (cursor);
return;
}
act_user_set_password (um->user, password, hint);
break;
case UM_PASSWORD_DIALOG_MODE_SET_AT_LOGIN:
act_user_set_password_mode (um->user, ACT_USER_PASSWORD_MODE_SET_AT_LOGIN);
break;
case UM_PASSWORD_DIALOG_MODE_NO_PASSWORD:
act_user_set_password_mode (um->user, ACT_USER_PASSWORD_MODE_NONE);
break;
case UM_PASSWORD_DIALOG_MODE_LOCK_ACCOUNT:
act_user_set_locked (um->user, TRUE);
break;
case UM_PASSWORD_DIALOG_MODE_UNLOCK_ACCOUNT:
act_user_set_locked (um->user, FALSE);
break;
default:
g_assert_not_reached ();
}
finish_password_change (um);
}
static void
@ -330,7 +355,7 @@ update_password_strength (UmPasswordDialog *um)
password = gtk_entry_get_text (GTK_ENTRY (um->password_entry));
old_password = gtk_entry_get_text (GTK_ENTRY (um->old_password_entry));
username = um_user_get_user_name (um->user);
username = act_user_get_user_name (um->user);
pw_strength (password, old_password, username,
&hint, &long_hint, &strength_level);
@ -625,7 +650,7 @@ visible_func (GtkTreeModel *model,
{
if (um->user) {
gint mode;
gboolean locked = um_user_get_locked (um->user);
gboolean locked = act_user_get_locked (um->user);
gtk_tree_model_get (model, iter, 1, &mode, -1);
@ -643,7 +668,7 @@ visible_func (GtkTreeModel *model,
void
um_password_dialog_set_user (UmPasswordDialog *um,
UmUser *user)
ActUser *user)
{
GdkPixbuf *pixbuf;
GtkTreeModel *model;
@ -655,20 +680,20 @@ um_password_dialog_set_user (UmPasswordDialog *um,
if (user) {
um->user = g_object_ref (user);
pixbuf = um_user_render_icon (user, UM_ICON_STYLE_NONE, 48);
pixbuf = render_user_icon (user, UM_ICON_STYLE_NONE, 48);
gtk_image_set_from_pixbuf (GTK_IMAGE (um->user_icon), pixbuf);
g_object_unref (pixbuf);
gtk_label_set_label (GTK_LABEL (um->user_name),
um_user_get_real_name (user));
act_user_get_real_name (user));
gtk_entry_set_text (GTK_ENTRY (um->password_entry), "");
gtk_entry_set_text (GTK_ENTRY (um->verify_entry), "");
gtk_entry_set_text (GTK_ENTRY (um->normal_hint_entry), "");
gtk_entry_set_text (GTK_ENTRY (um->old_password_entry), "");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->show_password_button), FALSE);
if (um_user_get_uid (um->user) == getuid () &&
um_user_get_password_mode (um->user) == UM_PASSWORD_MODE_REGULAR) {
if (act_user_get_uid (um->user) == getuid () &&
act_user_get_password_mode (um->user) == ACT_USER_PASSWORD_MODE_REGULAR) {
gtk_widget_show (um->old_password_label);
gtk_widget_show (um->old_password_entry);
um->old_password_ok = FALSE;
@ -678,7 +703,7 @@ um_password_dialog_set_user (UmPasswordDialog *um,
gtk_widget_hide (um->old_password_entry);
um->old_password_ok = TRUE;
}
if (um_user_get_uid (um->user) == getuid()) {
if (act_user_get_uid (um->user) == getuid()) {
if (um->passwd_handler != NULL)
passwd_destroy (um->passwd_handler);
um->passwd_handler = passwd_init ();

View file

@ -23,7 +23,7 @@
#define __UM_PASSWORD_DIALOG_H__
#include <gtk/gtk.h>
#include "um-user.h"
#include <act/act.h>
G_BEGIN_DECLS
@ -32,7 +32,7 @@ typedef struct _UmPasswordDialog UmPasswordDialog;
UmPasswordDialog *um_password_dialog_new (void);
void um_password_dialog_free (UmPasswordDialog *dialog);
void um_password_dialog_set_user (UmPasswordDialog *dialog,
UmUser *user);
ActUser *user);
void um_password_dialog_set_privileged (UmPasswordDialog *dialog,
gboolean privileged);
void um_password_dialog_show (UmPasswordDialog *dialog,

View file

@ -26,6 +26,7 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <act/act.h>
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
@ -36,7 +37,6 @@
#endif /* HAVE_CHEESE */
#include "um-photo-dialog.h"
#include "um-user-manager.h"
#include "um-crop-area.h"
#include "um-utils.h"
@ -55,7 +55,7 @@ struct _UmPhotoDialog {
GnomeDesktopThumbnailFactory *thumb_factory;
UmUser *user;
ActUser *user;
};
static void
@ -74,7 +74,7 @@ crop_dialog_response (GtkWidget *dialog,
pb = um_crop_area_get_picture (UM_CROP_AREA (um->crop_area));
pb2 = gdk_pixbuf_scale_simple (pb, 96, 96, GDK_INTERP_BILINEAR);
um_user_set_icon_data (um->user, pb2);
set_user_icon_data (um->user, pb2);
g_object_unref (pb2);
g_object_unref (pb);
@ -247,7 +247,7 @@ static void
none_icon_selected (GtkMenuItem *menuitem,
UmPhotoDialog *um)
{
um_user_set_icon_file (um->user, "");
act_user_set_icon_file (um->user, "");
}
static void
@ -276,7 +276,7 @@ webcam_response_cb (GtkDialog *dialog,
g_object_get (G_OBJECT (dialog), "pixbuf", &pb, NULL);
pb2 = gdk_pixbuf_scale_simple (pb, 96, 96, GDK_INTERP_BILINEAR);
um_user_set_icon_data (um->user, pb2);
set_user_icon_data (um->user, pb2);
g_object_unref (pb2);
g_object_unref (pb);
@ -337,7 +337,7 @@ stock_icon_selected (GtkMenuItem *menuitem,
const char *filename;
filename = g_object_get_data (G_OBJECT (menuitem), "filename");
um_user_set_icon_file (um->user, filename);
act_user_set_icon_file (um->user, filename);
}
static GtkWidget *
@ -652,11 +652,11 @@ set_tip (GtkWidget *item,
void
um_photo_dialog_set_user (UmPhotoDialog *um,
UmUser *user)
ActUser *user)
{
UmUserManager *manager;
ActUserManager *manager;
GSList *list, *l;
UmUser *u;
ActUser *u;
GIcon *icon;
GEmblem *emblem;
GList *children, *c;
@ -675,9 +675,8 @@ um_photo_dialog_set_user (UmPhotoDialog *um,
children = gtk_container_get_children (GTK_CONTAINER (um->photo_popup));
g_list_foreach (children, (GFunc) clear_tip, NULL);
manager = um_user_manager_ref_default ();
list = um_user_manager_list_users (manager);
g_object_unref (manager);
manager = act_user_manager_get_default ();
list = act_user_manager_list_users (manager);
icon = g_themed_icon_new ("avatar-default");
emblem = g_emblem_new (icon);
@ -689,7 +688,7 @@ um_photo_dialog_set_user (UmPhotoDialog *um,
u = l->data;
if (u == user)
continue;
filename = um_user_get_icon_file (u);
filename = act_user_get_icon_file (u);
if (filename == NULL)
continue;
for (c = children; c; c = c->next) {
@ -702,7 +701,7 @@ um_photo_dialog_set_user (UmPhotoDialog *um,
char *tip;
tip = g_strdup_printf (_("Used by %s"),
um_user_get_real_name (u));
act_user_get_real_name (u));
set_tip (GTK_WIDGET (c->data), tip, emblem);
g_free (tip);
break;

View file

@ -23,7 +23,7 @@
#define __UM_PHOTO_DIALOG_H__
#include <gtk/gtk.h>
#include "um-user.h"
#include <act/act.h>
G_BEGIN_DECLS
@ -32,7 +32,7 @@ typedef struct _UmPhotoDialog UmPhotoDialog;
UmPhotoDialog *um_photo_dialog_new (GtkWidget *button);
void um_photo_dialog_free (UmPhotoDialog *dialog);
void um_photo_dialog_set_user (UmPhotoDialog *dialog,
UmUser *user);
ActUser *user);
G_END_DECLS

View file

@ -1,734 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2009-2010 Red Hat, Inc.
*
* 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 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Written by: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif /* HAVE_PATHS_H */
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <glib-object.h>
#include <gio/gio.h>
#include "um-user-manager.h"
enum {
USERS_LOADED,
USER_ADDED,
USER_REMOVED,
USER_CHANGED,
LAST_SIGNAL
};
static guint signals [LAST_SIGNAL] = { 0, };
static void um_user_manager_class_init (UmUserManagerClass *klass);
static void um_user_manager_init (UmUserManager *user_manager);
static void um_user_manager_finalize (GObject *object);
static gpointer user_manager_object = NULL;
G_DEFINE_TYPE (UmUserManager, um_user_manager, G_TYPE_OBJECT)
static void
um_user_manager_class_init (UmUserManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = um_user_manager_finalize;
signals [USERS_LOADED] =
g_signal_new ("users-loaded",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (UmUserManagerClass, users_loaded),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals [USER_ADDED] =
g_signal_new ("user-added",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (UmUserManagerClass, user_added),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, UM_TYPE_USER);
signals [USER_REMOVED] =
g_signal_new ("user-removed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (UmUserManagerClass, user_removed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, UM_TYPE_USER);
signals [USER_CHANGED] =
g_signal_new ("user-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (UmUserManagerClass, user_changed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, UM_TYPE_USER);
}
/* We maintain a ring for each group of users with the same real name.
* We need this to pick the right display names.
*/
static void
remove_user_from_dupe_ring (UmUserManager *manager,
UmUser *user)
{
GList *dupes;
UmUser *dup;
dup = NULL;
dupes = g_object_get_data (G_OBJECT (user), "dupes");
if (!dupes) {
goto out;
}
if (dupes->next == dupes->prev) {
dup = dupes->next->data;
g_list_free_1 (dupes->next);
g_object_set_data (G_OBJECT (dup), "dupes", NULL);
}
else {
dupes->next->prev = dupes->prev;
dupes->prev->next = dupes->next;
}
g_list_free_1 (dupes);
g_object_set_data (G_OBJECT (user), "dupes", NULL);
out:
if (dup) {
um_user_show_short_display_name (dup);
g_signal_emit (manager, signals[USER_CHANGED], 0, dup);
}
um_user_show_short_display_name (user);
g_signal_emit (manager, signals[USER_CHANGED], 0, user);
}
static gboolean
match_real_name_hrfunc (gpointer key,
gpointer value,
gpointer user)
{
return (value != user && g_strcmp0 (um_user_get_real_name (user), um_user_get_real_name (value)) == 0);
}
static void
add_user_to_dupe_ring (UmUserManager *manager,
UmUser *user)
{
UmUser *dup;
GList *dupes;
GList *l;
dup = g_hash_table_find (manager->user_by_object_path,
match_real_name_hrfunc, user);
if (!dup) {
return;
}
dupes = g_object_get_data (G_OBJECT (dup), "dupes");
if (!dupes) {
dupes = g_list_append (NULL, dup);
g_object_set_data (G_OBJECT (dup), "dupes", dupes);
dupes->next = dupes->prev = dupes;
}
else {
dup = NULL;
}
l = g_list_append (NULL, user);
g_object_set_data (G_OBJECT (user), "dupes", l);
l->prev = dupes->prev;
dupes->prev->next = l;
l->next = dupes;
dupes->prev = l;
if (dup) {
um_user_show_full_display_name (dup);
g_signal_emit (manager, signals[USER_CHANGED], 0, dup);
}
um_user_show_full_display_name (user);
g_signal_emit (manager, signals[USER_CHANGED], 0, user);
}
static void
user_changed_handler (UmUser *user,
UmUserManager *manager)
{
remove_user_from_dupe_ring (manager, user);
add_user_to_dupe_ring (manager, user);
g_signal_emit (manager, signals[USER_CHANGED], 0, user);
}
static void
user_added_handler (UmUserManager *manager,
const char *object_path)
{
UmUser *user;
if (g_hash_table_lookup (manager->user_by_object_path, object_path))
return;
user = um_user_new_from_object_path (object_path);
if (!user)
return;
if (um_user_is_system_account (user)) {
g_object_unref (user);
return;
}
add_user_to_dupe_ring (manager, user);
g_signal_connect (user, "changed",
G_CALLBACK (user_changed_handler), manager);
g_hash_table_insert (manager->user_by_object_path, g_strdup (um_user_get_object_path (user)), g_object_ref (user));
g_hash_table_insert (manager->user_by_name, g_strdup (um_user_get_user_name (user)), g_object_ref (user));
g_signal_emit (manager, signals[USER_ADDED], 0, user);
g_object_unref (user);
}
static void
user_deleted_handler (UmUserManager *manager,
const char *object_path)
{
UmUser *user;
user = g_hash_table_lookup (manager->user_by_object_path, object_path);
if (!user)
return;
g_object_ref (user);
g_signal_handlers_disconnect_by_func (user, user_changed_handler, manager);
remove_user_from_dupe_ring (manager, user);
g_hash_table_remove (manager->user_by_object_path, um_user_get_object_path (user));
g_hash_table_remove (manager->user_by_name, um_user_get_user_name (user));
g_signal_emit (manager, signals[USER_REMOVED], 0, user);
g_object_unref (user);
}
static void
manager_signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, UmUserManager *manager)
{
if (strcmp (signal_name, "UserAdded") == 0) {
if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(o)"))) {
gchar *object_path;
g_variant_get (parameters, "(&o)", &object_path);
user_added_handler (manager, object_path);
}
}
else if (strcmp (signal_name, "UserDeleted") == 0) {
if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(o)"))) {
gchar *object_path;
g_variant_get (parameters, "(&o)", &object_path);
user_deleted_handler (manager, object_path);
}
}
}
static void
got_users (GObject *object,
GAsyncResult *res,
gpointer data)
{
UmUserManager *manager = data;
GVariant *result;
GError *error = NULL;
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
if (!result) {
manager->no_service = TRUE;
g_error_free (error);
goto done;
}
if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(ao)"))) {
GVariantIter *iter;
gchar *object_path;
g_variant_get (result, "(ao)", &iter);
while (g_variant_iter_loop (iter, "&o", &object_path))
user_added_handler (manager, object_path);
g_variant_iter_free (iter);
}
g_variant_unref (result);
done:
g_signal_emit (G_OBJECT (manager), signals[USERS_LOADED], 0);
}
static void
get_users (UmUserManager *manager)
{
g_debug ("calling 'ListCachedUsers'");
g_dbus_proxy_call (manager->proxy,
"ListCachedUsers",
g_variant_new ("()"),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
got_users,
manager);
}
static void
um_user_manager_init (UmUserManager *manager)
{
GError *error = NULL;
GDBusConnection *bus;
manager->user_by_object_path = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_object_unref);
manager->user_by_name = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_object_unref);
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (bus == NULL) {
g_warning ("Couldn't connect to system bus: %s", error->message);
g_error_free (error);
return;
}
manager->proxy = g_dbus_proxy_new_sync (bus,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
"org.freedesktop.Accounts",
"/org/freedesktop/Accounts",
"org.freedesktop.Accounts",
NULL,
&error);
if (manager->proxy == NULL) {
g_warning ("Couldn't get accounts proxy: %s", error->message);
g_error_free (error);
return;
}
g_signal_connect (manager->proxy, "g-signal", G_CALLBACK (manager_signal_cb), manager);
get_users (manager);
}
static void
clear_dup (gpointer key,
gpointer value,
gpointer data)
{
GList *dupes;
/* don't bother maintaining the ring, we're destroying the
* entire hash table anyway
*/
dupes = g_object_get_data (G_OBJECT (value), "dupes");
if (dupes) {
g_list_free_1 (dupes);
g_object_set_data (G_OBJECT (value), "dupes", NULL);
}
}
static void
um_user_manager_finalize (GObject *object)
{
UmUserManager *manager;
manager = UM_USER_MANAGER (object);
g_hash_table_foreach (manager->user_by_object_path, clear_dup, NULL);
g_hash_table_destroy (manager->user_by_object_path);
g_hash_table_destroy (manager->user_by_name);
g_object_unref (manager->proxy);
G_OBJECT_CLASS (um_user_manager_parent_class)->finalize (object);
}
UmUserManager *
um_user_manager_ref_default (void)
{
if (user_manager_object != NULL) {
g_object_ref (user_manager_object);
} else {
user_manager_object = g_object_new (UM_TYPE_USER_MANAGER, NULL);
g_object_add_weak_pointer (user_manager_object,
(gpointer *) &user_manager_object);
}
return UM_USER_MANAGER (user_manager_object);
}
typedef struct {
UmUserManager *manager;
gchar *user_name;
GAsyncReadyCallback callback;
gpointer data;
GDestroyNotify destroy;
} AsyncUserOpData;
static void
async_user_op_data_free (gpointer d)
{
AsyncUserOpData *data = d;
g_object_unref (data->manager);
g_free (data->user_name);
if (data->destroy)
data->destroy (data->data);
g_free (data);
}
/* Used for both create_user and cache_user */
static void
user_call_done (GObject *proxy,
GAsyncResult *r,
gpointer user_data)
{
AsyncUserOpData *data = user_data;
GSimpleAsyncResult *res;
GVariant *result;
GError *error = NULL;
gchar *remote;
res = g_simple_async_result_new (G_OBJECT (data->manager),
data->callback,
data->data,
um_user_manager_create_user);
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), r, &error);
if (!result) {
/* dbus-glib fail:
* We have to translate the errors manually here, since
* calling dbus_g_error_has_name on the error returned in
* um_user_manager_create_user_finish doesn't work.
*/
remote = g_dbus_error_get_remote_error (error);
if (g_dbus_error_is_remote_error (error) &&
strcmp (remote, "org.freedesktop.Accounts.Error.PermissionDenied") == 0) {
g_simple_async_result_set_error (res,
UM_USER_MANAGER_ERROR,
UM_USER_MANAGER_ERROR_PERMISSION_DENIED,
"Not authorized");
}
if (g_dbus_error_is_remote_error (error) &&
strcmp (remote, "org.freedesktop.Accounts.Error.UserExists") == 0) {
g_simple_async_result_set_error (res,
UM_USER_MANAGER_ERROR,
UM_USER_MANAGER_ERROR_USER_EXISTS,
_("A user with name '%s' already exists."),
data->user_name);
} else if (g_dbus_error_is_remote_error (error) &&
strcmp (remote, "org.freedesktop.Accounts.Error.UserDoesNotExist") == 0) {
g_simple_async_result_set_error (res,
UM_USER_MANAGER_ERROR,
UM_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST,
_("No user with the name '%s' exists."),
data->user_name);
}
else {
g_simple_async_result_set_from_error (res, error);
}
g_error_free (error);
g_free (remote);
}
else {
if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)"))) {
gchar *path;
g_variant_get (result, "(o)", &path);
g_simple_async_result_set_op_res_gpointer (res, path, g_free);
}
else
g_simple_async_result_set_error (res,
UM_USER_MANAGER_ERROR,
UM_USER_MANAGER_ERROR_FAILED,
"Got invalid response from AccountsService");
g_variant_unref (result);
}
data->callback (G_OBJECT (data->manager), G_ASYNC_RESULT (res), data->data);
async_user_op_data_free (data);
g_object_unref (res);
}
gboolean
um_user_manager_create_user_finish (UmUserManager *manager,
GAsyncResult *result,
UmUser **user,
GError **error)
{
gchar *path;
GSimpleAsyncResult *res;
res = G_SIMPLE_ASYNC_RESULT (result);
*user = NULL;
if (g_simple_async_result_propagate_error (res, error)) {
return FALSE;
}
path = g_simple_async_result_get_op_res_gpointer (res);
*user = g_hash_table_lookup (manager->user_by_object_path, path);
return TRUE;
}
void
um_user_manager_create_user (UmUserManager *manager,
const char *user_name,
const char *real_name,
gint account_type,
GCancellable *cancellable,
GAsyncReadyCallback done,
gpointer done_data,
GDestroyNotify destroy)
{
AsyncUserOpData *data;
data = g_new0 (AsyncUserOpData, 1);
data->manager = g_object_ref (manager);
data->user_name = g_strdup (user_name);
data->callback = done;
data->data = done_data;
data->destroy = destroy;
g_dbus_proxy_call (manager->proxy,
"CreateUser",
g_variant_new ("(ssi)", user_name, real_name, account_type),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
user_call_done,
data);
}
gboolean
um_user_manager_cache_user_finish (UmUserManager *manager,
GAsyncResult *result,
UmUser **user,
GError **error)
{
gchar *path;
GSimpleAsyncResult *res;
res = G_SIMPLE_ASYNC_RESULT (result);
*user = NULL;
if (g_simple_async_result_propagate_error (res, error)) {
return FALSE;
}
path = g_simple_async_result_get_op_res_gpointer (res);
*user = g_hash_table_lookup (manager->user_by_object_path, path);
return TRUE;
}
void
um_user_manager_cache_user (UmUserManager *manager,
const char *user_name,
GCancellable *cancellable,
GAsyncReadyCallback done,
gpointer done_data,
GDestroyNotify destroy)
{
AsyncUserOpData *data;
data = g_new0 (AsyncUserOpData, 1);
data->manager = g_object_ref (manager);
data->user_name = g_strdup (user_name);
data->callback = done;
data->data = done_data;
data->destroy = destroy;
g_dbus_proxy_call (manager->proxy,
"CacheUser",
g_variant_new ("(s)", user_name),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
user_call_done,
data);
}
static void
delete_user_done (GObject *proxy,
GAsyncResult *r,
gpointer user_data)
{
AsyncUserOpData *data = user_data;
GSimpleAsyncResult *res;
GVariant *result;
GError *error = NULL;
res = g_simple_async_result_new (G_OBJECT (data->manager),
data->callback,
data->data,
um_user_manager_delete_user);
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), r, &error);
if (!result) {
if (g_dbus_error_is_remote_error (error) &&
strcmp (g_dbus_error_get_remote_error(error), "org.freedesktop.Accounts.Error.PermissionDenied") == 0) {
g_simple_async_result_set_error (res,
UM_USER_MANAGER_ERROR,
UM_USER_MANAGER_ERROR_PERMISSION_DENIED,
"Not authorized");
}
else if (g_dbus_error_is_remote_error (error) &&
strcmp (g_dbus_error_get_remote_error(error), "org.freedesktop.Accounts.Error.UserExists") == 0) {
g_simple_async_result_set_error (res,
UM_USER_MANAGER_ERROR,
UM_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST,
_("This user does not exist."));
}
else {
g_simple_async_result_set_from_error (res, error);
g_error_free (error);
}
}
else
g_variant_unref (result);
data->callback (G_OBJECT (data->manager), G_ASYNC_RESULT (res), data->data);
async_user_op_data_free (data);
g_object_unref (res);
}
gboolean
um_user_manager_delete_user_finish (UmUserManager *manager,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *res;
res = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (res, error)) {
return FALSE;
}
return TRUE;
}
void
um_user_manager_delete_user (UmUserManager *manager,
UmUser *user,
gboolean remove_files,
GAsyncReadyCallback done,
gpointer done_data,
GDestroyNotify destroy)
{
AsyncUserOpData *data;
data = g_new0 (AsyncUserOpData, 1);
data->manager = g_object_ref (manager);
data->callback = done;
data->data = done_data;
data->destroy = destroy;
g_dbus_proxy_call (manager->proxy,
"DeleteUser",
g_variant_new ("(xb)", (gint64) um_user_get_uid (user), remove_files),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
delete_user_done,
data);
}
GSList *
um_user_manager_list_users (UmUserManager *manager)
{
GSList *list = NULL;
GHashTableIter iter;
gpointer value;
g_hash_table_iter_init (&iter, manager->user_by_name);
while (g_hash_table_iter_next (&iter, NULL, &value)) {
list = g_slist_prepend (list, value);
}
return g_slist_sort (list, (GCompareFunc) um_user_collate);
}
UmUser *
um_user_manager_get_user (UmUserManager *manager,
const gchar *name)
{
return g_hash_table_lookup (manager->user_by_name, name);
}
UmUser *
um_user_manager_get_user_by_id (UmUserManager *manager,
uid_t uid)
{
struct passwd *pwent;
pwent = getpwuid (uid);
if (!pwent) {
return NULL;
}
return um_user_manager_get_user (manager, pwent->pw_name);
}
gboolean
um_user_manager_no_service (UmUserManager *manager)
{
return manager->no_service;
}
GQuark
um_user_manager_error_quark (void)
{
return g_quark_from_static_string ("um-user-manager-error-quark");
}

View file

@ -1,121 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2009-2010 Red Hat, Inc.
*
* 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 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __UM_USER_MANAGER__
#define __UM_USER_MANAGER__
#include <glib-object.h>
#include <gio/gio.h>
#include "um-user.h"
G_BEGIN_DECLS
#define UM_TYPE_USER_MANAGER (um_user_manager_get_type ())
#define UM_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), UM_TYPE_USER_MANAGER, UmUserManager))
#define UM_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), UM_TYPE_USER_MANAGER, UmUserManagerClass))
#define UM_IS_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), UM_TYPE_USER_MANAGER))
#define UM_IS_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), UM_TYPE_USER_MANAGER))
#define UM_USER_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), UM_TYPE_USER_MANAGER, UmUserManagerClass))
typedef struct
{
GObject parent;
GDBusProxy *proxy;
GHashTable *user_by_object_path;
GHashTable *user_by_name;
gboolean no_service;
} UmUserManager;
typedef struct
{
GObjectClass parent_class;
void (* users_loaded) (UmUserManager *user_managaer);
void (* user_added) (UmUserManager *user_manager,
UmUser *user);
void (* user_removed) (UmUserManager *user_manager,
UmUser *user);
void (* user_changed) (UmUserManager *user_manager,
UmUser *user);
} UmUserManagerClass;
typedef enum {
UM_USER_MANAGER_ERROR_FAILED,
UM_USER_MANAGER_ERROR_USER_EXISTS,
UM_USER_MANAGER_ERROR_USER_DOES_NOT_EXIST,
UM_USER_MANAGER_ERROR_PERMISSION_DENIED
} UmUserManagerError;
#define UM_USER_MANAGER_ERROR um_user_manager_error_quark ()
GQuark um_user_manager_error_quark (void);
GType um_user_manager_get_type (void);
UmUserManager * um_user_manager_ref_default (void);
gboolean um_user_manager_no_service (UmUserManager *manager);
GSList * um_user_manager_list_users (UmUserManager *manager);
UmUser * um_user_manager_get_user (UmUserManager *manager,
const char *user_name);
UmUser * um_user_manager_get_user_by_id (UmUserManager *manager,
uid_t uid);
void um_user_manager_create_user (UmUserManager *manager,
const char *user_name,
const char *real_name,
gint account_type,
GCancellable *cancellable,
GAsyncReadyCallback done,
gpointer user_data,
GDestroyNotify destroy);
gboolean um_user_manager_create_user_finish (UmUserManager *manager,
GAsyncResult *result,
UmUser **user,
GError **error);
void um_user_manager_cache_user (UmUserManager *manager,
const char *user_name,
GCancellable *cancellable,
GAsyncReadyCallback done,
gpointer user_data,
GDestroyNotify destroy);
gboolean um_user_manager_cache_user_finish (UmUserManager *manager,
GAsyncResult *result,
UmUser **user,
GError **error);
void um_user_manager_delete_user (UmUserManager *manager,
UmUser *user,
gboolean remove_files,
GAsyncReadyCallback done,
gpointer user_data,
GDestroyNotify destroy);
gboolean um_user_manager_delete_user_finish (UmUserManager *manager,
GAsyncResult *result,
GError **error);
G_END_DECLS
#endif /* __UM_USER_MANAGER__ */

View file

@ -32,6 +32,7 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <polkit/polkit.h>
#include <act/act.h>
#ifdef HAVE_CHEESE
#include <gst/gst.h>
@ -39,9 +40,6 @@
#include "shell/cc-editable-entry.h"
#include "um-user.h"
#include "um-user-manager.h"
#include "um-editable-button.h"
#include "um-editable-combo.h"
@ -62,7 +60,7 @@ CC_PANEL_REGISTER (CcUserPanel, cc_user_panel)
(G_TYPE_INSTANCE_GET_PRIVATE ((o), UM_TYPE_USER_PANEL, CcUserPanelPrivate))
struct _CcUserPanelPrivate {
UmUserManager *um;
ActUserManager *um;
GtkBuilder *builder;
GtkWidget *main_box;
@ -90,14 +88,14 @@ enum {
NUM_USER_LIST_COLS
};
static UmUser *
static ActUser *
get_selected_user (CcUserPanelPrivate *d)
{
GtkTreeView *tv;
GtkTreeIter iter;
GtkTreeSelection *selection;
GtkTreeModel *model;
UmUser *user;
ActUser *user;
tv = (GtkTreeView *)get_widget (d, "list-treeview");
selection = gtk_tree_view_get_selection (tv);
@ -111,15 +109,15 @@ get_selected_user (CcUserPanelPrivate *d)
}
static char *
get_name_col_str (UmUser *user)
get_name_col_str (ActUser *user)
{
return g_markup_printf_escaped ("<b>%s</b>\n<small>%s</small>",
um_user_get_display_name (user),
um_user_get_user_name (user));
act_user_get_real_name (user),
act_user_get_user_name (user));
}
static void
user_added (UmUserManager *um, UmUser *user, CcUserPanelPrivate *d)
user_added (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
{
GtkWidget *widget;
GtkTreeModel *model;
@ -131,16 +129,16 @@ user_added (UmUserManager *um, UmUser *user, CcUserPanelPrivate *d)
GtkTreeSelection *selection;
gint sort_key;
g_debug ("user added: %d %s\n", um_user_get_uid (user), um_user_get_real_name (user));
g_debug ("user added: %d %s\n", act_user_get_uid (user), act_user_get_real_name (user));
widget = get_widget (d, "list-treeview");
model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
store = GTK_LIST_STORE (model);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
pixbuf = um_user_render_icon (user, UM_ICON_STYLE_FRAME | UM_ICON_STYLE_STATUS, 48);
pixbuf = render_user_icon (user, UM_ICON_STYLE_FRAME | UM_ICON_STYLE_STATUS, 48);
text = get_name_col_str (user);
if (um_user_get_uid (user) == getuid ()) {
if (act_user_get_uid (user) == getuid ()) {
sort_key = 1;
}
else {
@ -172,7 +170,7 @@ get_previous_user_row (GtkTreeModel *model,
GtkTreeIter *prev)
{
GtkTreePath *path;
UmUser *user;
ActUser *user;
path = gtk_tree_model_get_path (model, iter);
while (gtk_tree_path_prev (path)) {
@ -191,7 +189,7 @@ get_next_user_row (GtkTreeModel *model,
GtkTreeIter *iter,
GtkTreeIter *next)
{
UmUser *user;
ActUser *user;
*next = *iter;
while (gtk_tree_model_iter_next (model, next)) {
@ -206,16 +204,16 @@ get_next_user_row (GtkTreeModel *model,
}
static void
user_removed (UmUserManager *um, UmUser *user, CcUserPanelPrivate *d)
user_removed (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
{
GtkTreeView *tv;
GtkTreeModel *model;
GtkTreeSelection *selection;
GtkListStore *store;
GtkTreeIter iter, next;
UmUser *u;
ActUser *u;
g_debug ("user removed: %s\n", um_user_get_user_name (user));
g_debug ("user removed: %s\n", act_user_get_user_name (user));
tv = (GtkTreeView *)get_widget (d, "list-treeview");
selection = gtk_tree_view_get_selection (tv);
model = gtk_tree_view_get_model (tv);
@ -225,7 +223,7 @@ user_removed (UmUserManager *um, UmUser *user, CcUserPanelPrivate *d)
gtk_tree_model_get (model, &iter, USER_COL, &u, -1);
if (u != NULL) {
if (um_user_get_uid (user) == um_user_get_uid (u)) {
if (act_user_get_uid (user) == act_user_get_uid (u)) {
if (!get_next_user_row (model, &iter, &next))
get_previous_user_row (model, &iter, &next);
gtk_list_store_remove (store, &iter);
@ -239,16 +237,16 @@ user_removed (UmUserManager *um, UmUser *user, CcUserPanelPrivate *d)
}
}
static void show_user (UmUser *user, CcUserPanelPrivate *d);
static void show_user (ActUser *user, CcUserPanelPrivate *d);
static void
user_changed (UmUserManager *um, UmUser *user, CcUserPanelPrivate *d)
user_changed (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
{
GtkTreeView *tv;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
UmUser *current;
ActUser *current;
GdkPixbuf *pixbuf;
char *text;
@ -260,7 +258,7 @@ user_changed (UmUserManager *um, UmUser *user, CcUserPanelPrivate *d)
do {
gtk_tree_model_get (model, &iter, USER_COL, &current, -1);
if (current == user) {
pixbuf = um_user_render_icon (user, UM_ICON_STYLE_FRAME | UM_ICON_STYLE_STATUS, 48);
pixbuf = render_user_icon (user, UM_ICON_STYLE_FRAME | UM_ICON_STYLE_STATUS, 48);
text = get_name_col_str (user);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
@ -301,9 +299,9 @@ select_created_user (GObject *object,
GtkTreeModel *model;
GtkTreeSelection *selection;
GtkTreeIter iter;
UmUser *current;
ActUser *current;
GtkTreePath *path;
UmUser *user;
ActUser *user;
dialog = UM_ACCOUNT_DIALOG (object);
user = um_account_dialog_finish (dialog, result);
@ -345,15 +343,15 @@ add_user (GtkButton *button, CcUserPanelPrivate *d)
}
static void
delete_user_done (UmUserManager *manager,
delete_user_done (ActUserManager *manager,
GAsyncResult *res,
CcUserPanelPrivate *d)
{
GError *error;
error = NULL;
if (!um_user_manager_delete_user_finish (manager, res, &error)) {
if (!g_error_matches (error, UM_USER_MANAGER_ERROR, UM_USER_MANAGER_ERROR_PERMISSION_DENIED)) {
if (!act_user_manager_delete_user_finish (manager, res, &error)) {
if (!g_error_matches (error, ACT_USER_MANAGER_ERROR, ACT_USER_MANAGER_ERROR_PERMISSION_DENIED)) {
GtkWidget *dialog;
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
@ -378,7 +376,7 @@ delete_user_response (GtkWidget *dialog,
gint response_id,
CcUserPanelPrivate *d)
{
UmUser *user;
ActUser *user;
gboolean remove_files;
gtk_widget_destroy (dialog);
@ -395,12 +393,12 @@ delete_user_response (GtkWidget *dialog,
user = get_selected_user (d);
um_user_manager_delete_user (d->um,
user,
remove_files,
(GAsyncReadyCallback)delete_user_done,
d,
NULL);
act_user_manager_delete_user_async (d->um,
user,
remove_files,
NULL,
(GAsyncReadyCallback)delete_user_done,
d);
g_object_unref (user);
}
@ -408,14 +406,14 @@ delete_user_response (GtkWidget *dialog,
static void
delete_user (GtkButton *button, CcUserPanelPrivate *d)
{
UmUser *user;
ActUser *user;
GtkWidget *dialog;
user = get_selected_user (d);
if (user == NULL) {
return;
}
else if (um_user_get_uid (user) == getuid ()) {
else if (act_user_get_uid (user) == getuid ()) {
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
0,
GTK_MESSAGE_INFO,
@ -424,13 +422,13 @@ delete_user (GtkButton *button, CcUserPanelPrivate *d)
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
}
else if (um_user_is_logged_in (user)) {
else if (act_user_is_logged_in (user)) {
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
0,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
_("%s is still logged in"),
um_user_get_real_name (user));
act_user_get_real_name (user));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
_("Deleting a user while they are logged in can leave the system in an inconsistent state."));
@ -443,7 +441,7 @@ delete_user (GtkButton *button, CcUserPanelPrivate *d)
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
_("Do you want to keep %s's files?"),
um_user_get_real_name (user));
act_user_get_real_name (user));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
_("It is possible to keep the home directory, mail spool and temporary files around when deleting a user account."));
@ -497,22 +495,22 @@ get_invisible_text (void)
}
static const gchar *
get_password_mode_text (UmUser *user)
get_password_mode_text (ActUser *user)
{
const gchar *text;
if (um_user_get_locked (user)) {
if (act_user_get_locked (user)) {
text = C_("Password mode", "Account disabled");
}
else {
switch (um_user_get_password_mode (user)) {
case UM_PASSWORD_MODE_REGULAR:
switch (act_user_get_password_mode (user)) {
case ACT_USER_PASSWORD_MODE_REGULAR:
text = get_invisible_text ();
break;
case UM_PASSWORD_MODE_SET_AT_LOGIN:
case ACT_USER_PASSWORD_MODE_SET_AT_LOGIN:
text = C_("Password mode", "To be set at next login");
break;
case UM_PASSWORD_MODE_NONE:
case ACT_USER_PASSWORD_MODE_NONE:
text = C_("Password mode", "None");
break;
default:
@ -529,21 +527,21 @@ autologin_changed (GObject *object,
CcUserPanelPrivate *d)
{
gboolean active;
UmUser *user;
ActUser *user;
active = gtk_switch_get_active (GTK_SWITCH (object));
user = get_selected_user (d);
if (active != um_user_get_automatic_login (user)) {
um_user_set_automatic_login (user, active);
if (um_user_get_automatic_login (user)) {
if (active != act_user_get_automatic_login (user)) {
act_user_set_automatic_login (user, active);
if (act_user_get_automatic_login (user)) {
GSList *list;
GSList *l;
list = um_user_manager_list_users (d->um);
list = act_user_manager_list_users (d->um);
for (l = list; l != NULL; l = l->next) {
UmUser *u = l->data;
if (um_user_get_uid (u) != um_user_get_uid (user)) {
um_user_set_automatic_login (user, FALSE);
ActUser *u = l->data;
if (act_user_get_uid (u) != act_user_get_uid (user)) {
act_user_set_automatic_login (user, FALSE);
}
}
g_slist_free (list);
@ -554,14 +552,14 @@ autologin_changed (GObject *object,
}
static gchar *
get_login_time_text (UmUser *user)
get_login_time_text (ActUser *user)
{
gchar *text, *date_str, *time_str;
GDateTime *date_time;
gint64 time;
time = um_user_get_login_time (user);
if (um_user_is_logged_in (user)) {
time = act_user_get_login_time (user);
if (act_user_is_logged_in (user)) {
text = g_strdup (_("Logged in"));
}
else if (time > 0) {
@ -583,7 +581,7 @@ get_login_time_text (UmUser *user)
}
static void
show_user (UmUser *user, CcUserPanelPrivate *d)
show_user (ActUser *user, CcUserPanelPrivate *d)
{
GtkWidget *image;
GtkWidget *label;
@ -595,9 +593,9 @@ show_user (UmUser *user, CcUserPanelPrivate *d)
GtkTreeModel *model;
GtkTreeIter iter;
gboolean show, enable;
UmUser *current;
ActUser *current;
pixbuf = um_user_render_icon (user, UM_ICON_STYLE_NONE, 48);
pixbuf = render_user_icon (user, UM_ICON_STYLE_NONE, 48);
image = get_widget (d, "user-icon-image");
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
image = get_widget (d, "user-icon-image2");
@ -607,34 +605,34 @@ show_user (UmUser *user, CcUserPanelPrivate *d)
um_photo_dialog_set_user (d->photo_dialog, user);
widget = get_widget (d, "full-name-entry");
cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), um_user_get_real_name (user));
gtk_widget_set_tooltip_text (widget, um_user_get_user_name (user));
cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), act_user_get_real_name (user));
gtk_widget_set_tooltip_text (widget, act_user_get_user_name (user));
widget = get_widget (d, "account-type-combo");
um_editable_combo_set_active (UM_EDITABLE_COMBO (widget), um_user_get_account_type (user));
um_editable_combo_set_active (UM_EDITABLE_COMBO (widget), act_user_get_account_type (user));
widget = get_widget (d, "account-password-button");
um_editable_button_set_text (UM_EDITABLE_BUTTON (widget), get_password_mode_text (user));
enable = um_user_is_local_account (user);
enable = act_user_is_local_account (user);
gtk_widget_set_sensitive (widget, enable);
widget = get_widget (d, "autologin-switch");
g_signal_handlers_block_by_func (widget, autologin_changed, d);
gtk_switch_set_active (GTK_SWITCH (widget), um_user_get_automatic_login (user));
gtk_switch_set_active (GTK_SWITCH (widget), act_user_get_automatic_login (user));
g_signal_handlers_unblock_by_func (widget, autologin_changed, d);
if (um_user_get_locked (user))
if (act_user_get_locked (user))
gtk_widget_set_sensitive (widget, FALSE);
widget = get_widget (d, "account-language-combo");
model = um_editable_combo_get_model (UM_EDITABLE_COMBO (widget));
cc_add_user_languages (model);
lang = g_strdup (um_user_get_language (user));
lang = g_strdup (act_user_get_language (user));
if (!lang)
lang = cc_common_language_get_current_language ();
cc_common_language_get_iter_for_language (model, lang, &iter);
um_editable_combo_set_active_iter (UM_EDITABLE_COMBO (widget), &iter);
if (cc_common_language_get_iter_for_language (model, lang, &iter))
um_editable_combo_set_active_iter (UM_EDITABLE_COMBO (widget), &iter);
g_free (lang);
/* Fingerprint: show when self, possible, and local account */
@ -642,8 +640,8 @@ show_user (UmUser *user, CcUserPanelPrivate *d)
label = get_widget (d, "account-fingerprint-label");
label2 = get_widget (d, "account-fingerprint-value-label");
label3 = get_widget (d, "account-fingerprint-button-label");
show = (um_user_get_uid (user) == getuid() &&
um_user_is_local_account (user) &&
show = (act_user_get_uid (user) == getuid() &&
act_user_is_local_account (user) &&
set_fingerprint_label (label2, label3));
gtk_widget_set_visible (label, show);
gtk_widget_set_visible (widget, show);
@ -651,7 +649,7 @@ show_user (UmUser *user, CcUserPanelPrivate *d)
/* Autologin: show when local account */
widget = get_widget (d, "autologin-switch");
label = get_widget (d, "autologin-label");
show = um_user_is_local_account (user);
show = act_user_is_local_account (user);
gtk_widget_set_visible (widget, show);
gtk_widget_set_visible (label, show);
@ -659,9 +657,9 @@ show_user (UmUser *user, CcUserPanelPrivate *d)
widget = get_widget (d, "last-login-value-label");
label = get_widget (d, "last-login-label");
current = um_user_manager_get_user_by_id (d->um, getuid ());
show = um_user_get_uid (user) == getuid () ||
um_user_get_account_type (current) == UM_ACCOUNT_TYPE_ADMINISTRATOR;
current = act_user_manager_get_user_by_id (d->um, getuid ());
show = act_user_get_uid (user) == getuid () ||
act_user_get_account_type (current) == ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR;
if (show) {
text = get_login_time_text (user);
gtk_label_set_text (GTK_LABEL (widget), text);
@ -678,7 +676,7 @@ selected_user_changed (GtkTreeSelection *selection, CcUserPanelPrivate *d)
{
GtkTreeModel *model;
GtkTreeIter iter;
UmUser *user;
ActUser *user;
if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
gtk_tree_model_get (model, &iter, USER_COL, &user, -1);
@ -697,13 +695,13 @@ change_name_done (GtkWidget *entry,
CcUserPanelPrivate *d)
{
const gchar *text;
UmUser *user;
ActUser *user;
user = get_selected_user (d);
text = cc_editable_entry_get_text (CC_EDITABLE_ENTRY (entry));
if (g_strcmp0 (text, um_user_get_real_name (user)) != 0) {
um_user_set_real_name (user, text);
if (g_strcmp0 (text, act_user_get_real_name (user)) != 0) {
act_user_set_real_name (user, text);
}
g_object_unref (user);
@ -713,7 +711,7 @@ static void
account_type_changed (UmEditableCombo *combo,
CcUserPanelPrivate *d)
{
UmUser *user;
ActUser *user;
GtkTreeModel *model;
GtkTreeIter iter;
gint account_type;
@ -724,8 +722,8 @@ account_type_changed (UmEditableCombo *combo,
um_editable_combo_get_active_iter (combo, &iter);
gtk_tree_model_get (model, &iter, 1, &account_type, -1);
if (account_type != um_user_get_account_type (user)) {
um_user_set_account_type (user, account_type);
if (account_type != act_user_get_account_type (user)) {
act_user_set_account_type (user, account_type);
}
g_object_unref (user);
@ -737,7 +735,7 @@ language_response (GtkDialog *dialog,
CcUserPanelPrivate *d)
{
GtkWidget *combo;
UmUser *user;
ActUser *user;
gchar *lang;
GtkTreeModel *model;
GtkTreeIter iter;
@ -749,10 +747,10 @@ language_response (GtkDialog *dialog,
if (response_id == GTK_RESPONSE_OK) {
lang = cc_language_chooser_get_language (GTK_WIDGET (dialog));
um_user_set_language (user, lang);
act_user_set_language (user, lang);
}
else {
lang = g_strdup (um_user_get_language (user));
lang = g_strdup (act_user_get_language (user));
if (!lang)
lang = cc_common_language_get_current_language ();
}
@ -773,7 +771,7 @@ language_changed (UmEditableCombo *combo,
GtkTreeModel *model;
GtkTreeIter iter;
gchar *lang;
UmUser *user;
ActUser *user;
if (!um_editable_combo_get_active_iter (combo, &iter))
return;
@ -784,8 +782,8 @@ language_changed (UmEditableCombo *combo,
gtk_tree_model_get (model, &iter, 0, &lang, -1);
if (lang) {
if (g_strcmp0 (lang, um_user_get_language (user)) != 0) {
um_user_set_language (user, lang);
if (g_strcmp0 (lang, act_user_get_language (user)) != 0) {
act_user_set_language (user, lang);
}
g_free (lang);
goto out;
@ -816,7 +814,7 @@ out:
static void
change_password (GtkButton *button, CcUserPanelPrivate *d)
{
UmUser *user;
ActUser *user;
user = get_selected_user (d);
@ -831,11 +829,11 @@ static void
change_fingerprint (GtkButton *button, CcUserPanelPrivate *d)
{
GtkWidget *label, *label2;
UmUser *user;
ActUser *user;
user = get_selected_user (d);
g_assert (g_strcmp0 (g_get_user_name (), um_user_get_user_name (user)) == 0);
g_assert (g_strcmp0 (g_get_user_name (), act_user_get_user_name (user)) == 0);
label = get_widget (d, "account-fingerprint-value-label");
label2 = get_widget (d, "account-fingerprint-button-label");
@ -850,7 +848,7 @@ sort_users (GtkTreeModel *model,
GtkTreeIter *b,
gpointer data)
{
UmUser *ua, *ub;
ActUser *ua, *ub;
gint sa, sb;
gint result;
@ -864,7 +862,7 @@ sort_users (GtkTreeModel *model,
result = 1;
}
else {
result = um_user_collate (ua, ub);
result = act_user_collate (ua, ub);
}
if (ua) {
@ -894,14 +892,15 @@ dont_select_headings (GtkTreeSelection *selection,
}
static void
users_loaded (UmUserManager *manager,
users_loaded (ActUserManager *manager,
GParamSpec *pspec,
CcUserPanelPrivate *d)
{
GSList *list, *l;
UmUser *user;
ActUser *user;
GtkWidget *dialog;
if (um_user_manager_no_service (d->um)) {
if (act_user_manager_no_service (d->um)) {
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
GTK_DIALOG_MODAL,
GTK_MESSAGE_OTHER,
@ -917,17 +916,18 @@ users_loaded (UmUserManager *manager,
gtk_widget_set_sensitive (d->main_box, FALSE);
}
list = um_user_manager_list_users (d->um);
list = act_user_manager_list_users (d->um);
g_debug ("Got %d users\n", g_slist_length (list));
g_signal_connect (d->um, "user-changed", G_CALLBACK (user_changed), d);
g_signal_connect (d->um, "user-is-logged-in-changed", G_CALLBACK (user_changed), d);
for (l = list; l; l = l->next) {
user = l->data;
g_debug ("adding user %s\n", um_user_get_real_name (user));
g_debug ("adding user %s\n", act_user_get_real_name (user));
user_added (d->um, user, d);
}
g_slist_free (list);
g_slist_free_full (list, g_object_unref);
g_signal_connect (d->um, "user-added", G_CALLBACK (user_added), d);
g_signal_connect (d->um, "user-removed", G_CALLBACK (user_removed), d);
@ -972,7 +972,7 @@ on_permission_changed (GPermission *permission,
CcUserPanelPrivate *d = data;
gboolean is_authorized;
gboolean self_selected;
UmUser *user;
ActUser *user;
GtkWidget *widget;
user = get_selected_user (d);
@ -981,7 +981,7 @@ on_permission_changed (GPermission *permission,
}
is_authorized = g_permission_get_allowed (G_PERMISSION (d->permission));
self_selected = um_user_get_uid (user) == geteuid ();
self_selected = act_user_get_uid (user) == geteuid ();
widget = get_widget (d, "add-user-toolbutton");
gtk_widget_set_sensitive (widget, is_authorized);
@ -1024,13 +1024,13 @@ on_permission_changed (GPermission *permission,
g_object_unref (icon);
}
if (!um_user_is_local_account (user)) {
if (!act_user_is_local_account (user)) {
um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), FALSE);
remove_unlock_tooltip (get_widget (d, "account-type-combo"));
gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), FALSE);
remove_unlock_tooltip (get_widget (d, "autologin-switch"));
} else if (is_authorized && um_user_is_local_account (user)) {
} else if (is_authorized && act_user_is_local_account (user)) {
um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), TRUE);
remove_unlock_tooltip (get_widget (d, "account-type-combo"));
gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), TRUE);
@ -1045,7 +1045,7 @@ on_permission_changed (GPermission *permission,
/* The full name entry: insensitive if remote or not authorized and not self */
widget = get_widget (d, "full-name-entry");
if (!um_user_is_local_account (user)) {
if (!act_user_is_local_account (user)) {
cc_editable_entry_set_editable (CC_EDITABLE_ENTRY (widget), FALSE);
remove_unlock_tooltip (widget);
@ -1095,7 +1095,7 @@ match_user (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer search_data)
{
UmUser *user;
ActUser *user;
const gchar *name;
gchar *normalized_key = NULL;
gchar *normalized_name = NULL;
@ -1120,10 +1120,10 @@ match_user (GtkTreeModel *model,
for (i = 0; i < 2; i++) {
if (i == 0) {
name = um_user_get_real_name (user);
name = act_user_get_real_name (user);
}
else {
name = um_user_get_user_name (user);
name = act_user_get_user_name (user);
}
g_free (normalized_name);
normalized_name = g_utf8_normalize (name, -1, G_NORMALIZE_ALL);
@ -1171,7 +1171,7 @@ setup_main_window (CcUserPanelPrivate *d)
userlist = get_widget (d, "list-treeview");
store = gtk_list_store_new (NUM_USER_LIST_COLS,
UM_TYPE_USER,
ACT_TYPE_USER,
GDK_TYPE_PIXBUF,
G_TYPE_STRING,
G_TYPE_BOOLEAN,
@ -1187,7 +1187,7 @@ setup_main_window (CcUserPanelPrivate *d)
match_user, NULL, NULL);
g_object_unref (model);
g_signal_connect (d->um, "users-loaded", G_CALLBACK (users_loaded), d);
g_signal_connect (d->um, "notify::is-loaded", G_CALLBACK (users_loaded), d);
gtk_widget_style_get (userlist, "expander-size", &expander_size, NULL);
gtk_tree_view_set_level_indentation (GTK_TREE_VIEW (userlist), - (expander_size + 6));
@ -1310,7 +1310,7 @@ cc_user_panel_init (CcUserPanel *self)
gtk_widget_set_size_request (GTK_WIDGET (self), -1, 350);
d->builder = gtk_builder_new ();
d->um = um_user_manager_ref_default ();
d->um = act_user_manager_get_default ();
filename = UIDIR "/user-accounts-dialog.ui";
if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
@ -1341,10 +1341,6 @@ cc_user_panel_dispose (GObject *object)
{
CcUserPanelPrivate *priv = UM_USER_PANEL (object)->priv;
if (priv->um) {
g_object_unref (priv->um);
priv->um = NULL;
}
if (priv->builder) {
g_object_unref (priv->builder);
priv->builder = NULL;

File diff suppressed because it is too large Load diff

View file

@ -1,116 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
* Copyright (C) 2007-2008 William Jon McCann <mccann@jhu.edu>
*
* 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 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Facade object for user data, owned by UmUserManager
*/
#ifndef __UM_USER__
#define __UM_USER__
#include <sys/types.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "um-account-type.h"
G_BEGIN_DECLS
#define UM_TYPE_USER (um_user_get_type ())
#define UM_USER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), UM_TYPE_USER, UmUser))
#define UM_IS_USER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), UM_TYPE_USER))
typedef enum {
UM_PASSWORD_MODE_REGULAR,
UM_PASSWORD_MODE_SET_AT_LOGIN,
UM_PASSWORD_MODE_NONE,
UM_PASSWORD_MODE_DISABLED,
UM_PASSWORD_MODE_ENABLED
} UmPasswordMode;
typedef enum {
UM_ICON_STYLE_NONE = 0,
UM_ICON_STYLE_FRAME = 1 << 0,
UM_ICON_STYLE_STATUS = 1 << 1
} UmIconStyle;
typedef struct _UmUser UmUser;
GType um_user_get_type (void) G_GNUC_CONST;
UmUser *um_user_new_from_object_path (const gchar *path);
const gchar *um_user_get_object_path (UmUser *user);
uid_t um_user_get_uid (UmUser *user);
const gchar *um_user_get_user_name (UmUser *user);
const gchar *um_user_get_real_name (UmUser *user);
const gchar *um_user_get_display_name (UmUser *user);
gint um_user_get_account_type (UmUser *user);
const gchar *um_user_get_email (UmUser *user);
const gchar *um_user_get_language (UmUser *user);
const gchar *um_user_get_location (UmUser *user);
const gchar *um_user_get_home_directory (UmUser *user);
const gchar *um_user_get_shell (UmUser *user);
gulong um_user_get_login_frequency (UmUser *user);
gint64 um_user_get_login_time (UmUser *user);
gint um_user_get_password_mode (UmUser *user);
const gchar *um_user_get_password_hint (UmUser *user);
const gchar *um_user_get_icon_file (UmUser *user);
gboolean um_user_get_locked (UmUser *user);
gboolean um_user_get_automatic_login (UmUser *user);
gboolean um_user_is_system_account (UmUser *user);
gboolean um_user_is_local_account (UmUser *user);
void um_user_set_user_name (UmUser *user,
const gchar *user_name);
void um_user_set_real_name (UmUser *user,
const gchar *real_name);
void um_user_set_email (UmUser *user,
const gchar *email);
void um_user_set_language (UmUser *user,
const gchar *language);
void um_user_set_location (UmUser *user,
const gchar *location);
void um_user_set_icon_file (UmUser *user,
const gchar *filename);
void um_user_set_icon_data (UmUser *user,
GdkPixbuf *pixbuf);
void um_user_set_account_type (UmUser *user,
gint account_type);
void um_user_set_automatic_login (UmUser *user,
gboolean enabled);
void um_user_set_password (UmUser *user,
int password_mode,
const gchar *plain,
const gchar *password_hint);
gboolean um_user_is_logged_in (UmUser *user);
GdkPixbuf *um_user_render_icon (UmUser *user,
UmIconStyle style,
gint icon_size);
gint um_user_collate (UmUser *user1,
UmUser *user2);
void um_user_show_short_display_name (UmUser *user);
void um_user_show_full_display_name (UmUser *user);
G_END_DECLS
#endif

View file

@ -27,8 +27,11 @@
#include <pwd.h>
#include <utmp.h>
#include <glib.h>
#include <gio/gio.h>
#include <gio/gunixoutputstream.h>
#include <glib/gi18n.h>
#include <sys/stat.h>
#include <glib/gstdio.h>
#include "um-utils.h"
@ -275,6 +278,7 @@ icon_released (GtkEntry *entry,
}
void
set_entry_validation_error (GtkEntry *entry,
const gchar *text)
@ -782,3 +786,231 @@ get_smart_date (GDateTime *date)
return label;
}
static gboolean
check_user_file (const char *filename,
gssize max_file_size)
{
struct stat fileinfo;
if (max_file_size < 0) {
max_file_size = G_MAXSIZE;
}
/* Exists/Readable? */
if (stat (filename, &fileinfo) < 0) {
g_debug ("File does not exist");
return FALSE;
}
/* Is a regular file */
if (G_UNLIKELY (!S_ISREG (fileinfo.st_mode))) {
g_debug ("File is not a regular file");
return FALSE;
}
/* Size is sane? */
if (G_UNLIKELY (fileinfo.st_size > max_file_size)) {
g_debug ("File is too large");
return FALSE;
}
return TRUE;
}
static GdkPixbuf *
frame_pixbuf (GdkPixbuf *source)
{
GdkPixbuf *dest;
cairo_t *cr;
cairo_surface_t *surface;
guint w;
guint h;
int frame_width;
double radius;
frame_width = 2;
w = gdk_pixbuf_get_width (source) + frame_width * 2;
h = gdk_pixbuf_get_height (source) + frame_width * 2;
radius = w / 10;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
w, h);
cr = cairo_create (surface);
cairo_surface_destroy (surface);
/* set up image */
cairo_rectangle (cr, 0, 0, w, h);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
cairo_fill (cr);
rounded_rectangle (cr, 1.0, 0.5, 0.5, radius, w - 1, h - 1);
cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3);
cairo_fill_preserve (cr);
gdk_cairo_set_source_pixbuf (cr, source, frame_width, frame_width);
cairo_fill (cr);
dest = gdk_pixbuf_get_from_surface (surface, 0, 0, w, h);
cairo_destroy (cr);
return dest;
}
static GdkPixbuf *
logged_in_pixbuf (GdkPixbuf *pixbuf)
{
cairo_format_t format;
cairo_surface_t *surface;
cairo_pattern_t *pattern;
cairo_t *cr;
gint width, height;
GdkRGBA color;
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
g_return_val_if_fail (width > 15 && height > 15, pixbuf);
format = gdk_pixbuf_get_has_alpha (pixbuf) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
surface = cairo_image_surface_create (format, width, height);
cr = cairo_create (surface);
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
cairo_paint (cr);
/* Draw pattern */
cairo_rectangle (cr, 0, 0, width, height);
pattern = cairo_pattern_create_radial (width - 9.5, height - 10, 0, width - 8.5, height - 7.5, 7.7);
cairo_pattern_add_color_stop_rgb (pattern, 0, 0.4, 0.9, 0);
cairo_pattern_add_color_stop_rgb (pattern, 0.7, 0.3, 0.6, 0);
cairo_pattern_add_color_stop_rgb (pattern, 0.8, 0.4, 0.4, 0.4);
cairo_pattern_add_color_stop_rgba (pattern, 1.0, 0, 0, 0, 0);
cairo_set_source (cr, pattern);
cairo_fill (cr);
/* Draw border */
cairo_set_line_width (cr, 0.9);
cairo_arc (cr, width - 8.5, height - 8.5, 6, 0, 2 * G_PI);
gdk_rgba_parse (&color, "#ffffff");
gdk_cairo_set_source_rgba (cr, &color);
cairo_stroke (cr);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
cairo_surface_finish (surface);
cairo_destroy (cr);
return pixbuf;
}
#define MAX_FILE_SIZE 65536
GdkPixbuf *
render_user_icon (ActUser *user,
UmIconStyle style,
gint icon_size)
{
GdkPixbuf *pixbuf;
GdkPixbuf *framed;
gboolean res;
GError *error;
const gchar *icon_file;
g_return_val_if_fail (ACT_IS_USER (user), NULL);
g_return_val_if_fail (icon_size > 12, NULL);
icon_file = act_user_get_icon_file (user);
pixbuf = NULL;
if (icon_file) {
res = check_user_file (icon_file, MAX_FILE_SIZE);
if (res) {
pixbuf = gdk_pixbuf_new_from_file_at_size (icon_file,
icon_size,
icon_size,
NULL);
}
else {
pixbuf = NULL;
}
}
if (pixbuf != NULL) {
goto out;
}
error = NULL;
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
"avatar-default",
icon_size,
GTK_ICON_LOOKUP_FORCE_SIZE,
&error);
if (error) {
g_warning ("%s", error->message);
g_error_free (error);
}
out:
if (pixbuf != NULL && (style & UM_ICON_STYLE_FRAME)) {
framed = frame_pixbuf (pixbuf);
if (framed != NULL) {
g_object_unref (pixbuf);
pixbuf = framed;
}
}
if (pixbuf != NULL && (style & UM_ICON_STYLE_STATUS) && act_user_is_logged_in (user)) {
framed = logged_in_pixbuf (pixbuf);
if (framed != NULL) {
g_object_unref (pixbuf);
pixbuf = framed;
}
}
return pixbuf;
}
void
set_user_icon_data (ActUser *user,
GdkPixbuf *pixbuf)
{
gchar *path;
gint fd;
GOutputStream *stream;
GError *error;
path = g_build_filename (g_get_tmp_dir (), "gnome-control-center-user-icon-XXXXXX", NULL);
fd = g_mkstemp (path);
if (fd == -1) {
g_warning ("failed to create temporary file for image data");
g_free (path);
return;
}
stream = g_unix_output_stream_new (fd, TRUE);
error = NULL;
if (!gdk_pixbuf_save_to_stream (pixbuf, stream, "png", NULL, &error, NULL)) {
g_warning ("failed to save image: %s", error->message);
g_error_free (error);
g_object_unref (stream);
return;
}
g_object_unref (stream);
act_user_set_icon_file (user, path);
/* if we ever make the dbus call async, the g_remove call needs
* to wait for its completion
*/
g_remove (path);
g_free (path);
}

View file

@ -23,9 +23,16 @@
#define __UM_UTILS_H__
#include <gtk/gtk.h>
#include <act/act.h>
G_BEGIN_DECLS
typedef enum {
UM_ICON_STYLE_NONE = 0,
UM_ICON_STYLE_FRAME = 1 << 0,
UM_ICON_STYLE_STATUS = 1 << 1
} UmIconStyle;
void setup_tooltip_with_embedded_icon (GtkWidget *widget,
const gchar *text,
const gchar *placeholder,
@ -67,6 +74,13 @@ void generate_username_choices (const gchar *name,
gchar * get_smart_date (GDateTime *date);
GdkPixbuf * render_user_icon (ActUser *user,
UmIconStyle style,
gint icon_size);
void set_user_icon_data (ActUser *user,
GdkPixbuf *pixbuf);
G_END_DECLS
#endif