aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2010-03-18 13:50:42 -0500
committerTed Gould <ted@gould.cx>2010-03-18 13:50:42 -0500
commitefedfa60d052a58f678575052e0ac98bc324612a (patch)
tree23368eb32b9f150b841da96ccf1c3c29a544181c
parentc4a714f3964fdea272f766f6e040eef664d6d97d (diff)
parent5704cdb0447a2297003da2128f7fb11b2d5bd8db (diff)
downloadayatana-indicator-session-efedfa60d052a58f678575052e0ac98bc324612a.tar.gz
ayatana-indicator-session-efedfa60d052a58f678575052e0ac98bc324612a.tar.bz2
ayatana-indicator-session-efedfa60d052a58f678575052e0ac98bc324612a.zip
Handle updating of sessions and mark the guest account when it has an open session.
-rw-r--r--.bzrignore2
-rw-r--r--src/Makefile.am18
-rw-r--r--src/consolekit-session.xml435
-rw-r--r--src/gdm-local-display-factory.xml20
-rw-r--r--src/indicator-session.c15
-rw-r--r--src/session-service.c12
-rw-r--r--src/users-service-dbus.c211
-rw-r--r--src/users-service-dbus.h7
8 files changed, 634 insertions, 86 deletions
diff --git a/.bzrignore b/.bzrignore
index f58310b..0ba1e24 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -58,3 +58,5 @@ src/consolekit-manager-client.h
src/session-dbus-client.h
src/session-dbus-server.h
src/upower-client.h
+src/gdm-local-display-factory-client.h
+src/consolekit-session-client.h
diff --git a/src/Makefile.am b/src/Makefile.am
index db41db6..24e00e4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,6 +26,20 @@ consolekit-manager-client.h: $(srcdir)/consolekit-manager.xml
--output=consolekit-manager-client.h \
$(srcdir)/consolekit-manager.xml
+consolekit-session-client.h: $(srcdir)/consolekit-session.xml
+ dbus-binding-tool \
+ --prefix=_consolekit_session_client \
+ --mode=glib-client \
+ --output=consolekit-session-client.h \
+ $(srcdir)/consolekit-session.xml
+
+gdm-local-display-factory-client.h: $(srcdir)/gdm-local-display-factory.xml
+ dbus-binding-tool \
+ --prefix=_gdm_local_display_factory_client \
+ --mode=glib-client \
+ --output=gdm-local-display-factory-client.h \
+ $(srcdir)/gdm-local-display-factory.xml
+
users-service-client.h: $(srcdir)/users-service.xml
dbus-binding-tool \
--prefix=_users_service_client \
@@ -113,6 +127,8 @@ gtk_logout_helper_LDADD = \
BUILT_SOURCES = \
consolekit-manager-client.h \
+ consolekit-session-client.h \
+ gdm-local-display-factory-client.h \
session-dbus-client.h \
session-dbus-server.h \
upower-client.h \
@@ -122,6 +138,8 @@ BUILT_SOURCES = \
EXTRA_DIST = \
consolekit-manager.xml \
+ consolekit-session.xml \
+ gdm-local-display-factory.xml \
session-dbus.xml \
upower.xml \
users-service.xml \
diff --git a/src/consolekit-session.xml b/src/consolekit-session.xml
new file mode 100644
index 0000000..b6e1cdb
--- /dev/null
+++ b/src/consolekit-session.xml
@@ -0,0 +1,435 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+
+ <interface name="org.freedesktop.ConsoleKit.Session">
+ <doc:doc>
+ <doc:description>
+ <doc:para>Session objects represent and store information
+ related to a user session.
+ </doc:para>
+ <doc:para>The properties associated with the Session
+ specifically refer to the properties of the "session leader".
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <method name="GetId">
+ <arg name="ssid" direction="out" type="o">
+ <doc:doc>
+ <doc:summary>Session ID</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns the ID for Session.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </method>
+ <method name="GetSeatId">
+ <arg name="sid" direction="out" type="o">
+ <doc:doc>
+ <doc:summary>Seat ID</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns the ID for the Seat the Session is
+ attached to.</doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="interface" to="Seat">org.freedesktop.ConsoleKit.Seat</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetSessionType">
+ <arg name="type" direction="out" type="s">
+ <doc:doc>
+ <doc:summary>Session type</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description>
+ <doc:para>Returns the type of the session.</doc:para>
+ <doc:para>Warning: we haven't yet defined the allowed values for this property.
+ It is probably best to avoid this until we do.
+ </doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="property" to="Session:session-type">session-type</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetUser">
+ <arg name="uid" direction="out" type="u">
+ <doc:doc>
+ <doc:summary>User ID</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns the user that the session belongs to.</doc:para>
+ </doc:description>
+ <doc:deprecated version="0.1.3" instead="GetUnixUser"/>
+ <doc:seealso><doc:ref type="property" to="Session:user">user</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetUnixUser">
+ <arg name="uid" direction="out" type="u">
+ <doc:doc>
+ <doc:summary>POSIX User ID</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns the POSIX user ID that the session belongs to.</doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="property" to="Session:unix-user">unix-user</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetX11Display">
+ <arg name="display" direction="out" type="s">
+ <doc:doc>
+ <doc:summary>The value of the X11 display</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns the value of the X11 DISPLAY for this session
+ if one is present.</doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="property" to="Session:x11-display">x11-display</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetX11DisplayDevice">
+ <arg name="x11_display_device" direction="out" type="s">
+ <doc:doc>
+ <doc:summary>The value of the X11 display device</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns the value of the display device (aka TTY) that the
+ X11 display for the session is connected to. If there is no x11-display set then this value
+ is undefined.</doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="property" to="Session:x11-display-device">x11-display-device</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetDisplayDevice">
+ <arg name="display_device" direction="out" type="s">
+ <doc:doc>
+ <doc:summary>The value of the display device</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns the value of the display device (aka TTY) that the
+ session is connected to.</doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="property" to="Session:display-device">display-device</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetRemoteHostName">
+ <arg name="remote_host_name" direction="out" type="s">
+ <doc:doc>
+ <doc:summary>The remote host name</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns the value of the remote host name for the session.
+ </doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="property" to="Session:remote-host-name">remote-host-name</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetLoginSessionId">
+ <arg name="login_session_id" direction="out" type="s">
+ <doc:doc>
+ <doc:summary>The value of the native system login session ID</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns the value of the login session ID that the
+ underlying system uses to enforce session boundaries. If there is no login session ID
+ set then this value is an empty string.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </method>
+ <method name="IsActive">
+ <arg name="active" direction="out" type="b">
+ <doc:doc>
+ <doc:summary>TRUE if the session is active, otherwise FALSE</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns whether the session is active on the Seat that
+ it is attached to.</doc:para>
+ <doc:para>If the session is not attached to a seat this value is undefined.
+ </doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="property" to="Session:active">active</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="IsLocal">
+ <arg name="local" direction="out" type="b">
+ <doc:doc>
+ <doc:summary>TRUE if the session is local, otherwise FALSE</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description><doc:para>Returns whether the session is local</doc:para>
+ <doc:para>FIXME: we need to come up with a concrete definition for this value.
+ It was originally used as a way to identify XDMCP sessions that originate
+ from a remote system.
+ </doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="property" to="Session:is-local">is-local</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetCreationTime">
+ <arg name="iso8601_datetime" type="s" direction="out">
+ <doc:doc>
+ <doc:summary>An ISO 8601 format date-type string</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description>
+ <doc:para>Returns an ISO 8601 date-time string that corresponds to
+ the time that the session was opened.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </method>
+
+ <method name="Activate">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>Attempt to activate the this session. In most
+ cases, if successful, this will cause the session to
+ become visible and become active on the seat that it
+ is attached to.</doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="method" to="Seat.ActivateSession">Seat.ActivateSession()</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="Lock">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>This will cause a <doc:ref type="signal" to="Session::Lock">Lock</doc:ref>
+ signal to be emitted for this session.
+ </doc:para>
+ </doc:description>
+ <doc:permission>This method is restricted to privileged users by D-Bus policy.</doc:permission>
+ <doc:seealso><doc:ref type="signal" to="Session::Lock">Lock signal</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="Unlock">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>This will cause an <doc:ref type="signal" to="Session::Unlock">Unlock</doc:ref>
+ signal to be emitted for this session.
+ </doc:para>
+ <doc:para>This can be used by login managers to unlock a session before it is
+ re-activated during fast-user-switching.
+ </doc:para>
+ </doc:description>
+ <doc:permission>This method is restricted to privileged users by D-Bus policy.</doc:permission>
+ <doc:seealso><doc:ref type="signal" to="Session::Unlock">Unlock signal</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+
+ <method name="GetIdleHint">
+ <arg name="idle_hint" type="b" direction="out">
+ <doc:doc>
+ <doc:summary>The value of the idle-hint</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description>
+ <doc:para>Gets the value of the <doc:ref type="property" to="Session:idle-hint">idle-hint</doc:ref>
+ property.
+ </doc:para>
+ </doc:description>
+ <doc:seealso><doc:ref type="property" to="Session:idle-hint">idle-hint</doc:ref></doc:seealso>
+ </doc:doc>
+ </method>
+ <method name="GetIdleSinceHint">
+ <arg name="iso8601_datetime" type="s" direction="out">
+ <doc:doc>
+ <doc:summary>An ISO 8601 format date-type string</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description>
+ <doc:para>Returns an ISO 8601 date-time string that corresponds to
+ the time of the last change of the idle-hint.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </method>
+ <method name="SetIdleHint">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg name="idle_hint" type="b" direction="in">
+ <doc:doc>
+ <doc:summary>boolean value to set the idle-hint to</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description>
+ <doc:para>This may be used by the session to indicate that
+ it is idle.
+ </doc:para>
+ <doc:para>Use of this method is restricted to the user
+ that owns the session.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </method>
+
+ <signal name="ActiveChanged">
+ <arg name="is_active" type="b">
+ <doc:doc>
+ <doc:summary>TRUE if the session is active, otherwise FALSE</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description>
+ <doc:para>Emitted when the active property has changed.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </signal>
+ <signal name="IdleHintChanged">
+ <arg name="hint" type="b">
+ <doc:doc>
+ <doc:summary>the new value of idle-hint</doc:summary>
+ </doc:doc>
+ </arg>
+ <doc:doc>
+ <doc:description>
+ <doc:para>Emitted when the idle-hint property has changed.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </signal>
+ <signal name="Lock">
+ <doc:doc>
+ <doc:description>
+ <doc:para>Emitted in response to a call to the <doc:ref type="method" to="Session.Lock">Lock()</doc:ref> method.</doc:para>
+ <doc:para>It is intended that the screensaver for the session should lock the screen in response to this signal.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </signal>
+ <signal name="Unlock">
+ <doc:doc>
+ <doc:description>
+ <doc:para>Emitted in response to a call to the <doc:ref type="method" to="Session.Unlock">Unlock()</doc:ref> method.</doc:para>
+ <doc:para>It is intended that the screensaver for the session should unlock the screen in response to this signal.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </signal>
+
+ <property name="unix-user" type="u" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>The user assigned to the session.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </property>
+ <property name="user" type="u" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>The user assigned to the session.</doc:para>
+ </doc:description>
+ <doc:deprecated version="0.1.3" instead="unix-user"/>
+ </doc:doc>
+ </property>
+ <property name="session-type" type="s" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>The type of the session.</doc:para>
+ <doc:para>Warning: we haven't yet defined the allowed values for this property.
+ It is probably best to avoid this until we do.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </property>
+ <property name="remote-host-name" type="s" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>The remote host name for the session.
+ </doc:para>
+ <doc:para>This will be set in situations where the session is
+ opened and controlled from a remote system.
+ </doc:para>
+ <doc:para>For example, this value will be set when the
+ session is created from an SSH or XDMCP connection.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </property>
+ <property name="display-device" type="s" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>The display device (aka TTY) that the
+ session is connected to.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </property>
+ <property name="x11-display" type="s" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>Value of the X11 DISPLAY for this session
+ if one is present.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </property>
+ <property name="x11-display-device" type="s" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ The display device (aka TTY) that the X11 display for the
+ session is connected to. If there is no x11-display set then
+ this value is undefined.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </property>
+ <property name="active" type="b" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Whether the session is active on the Seat that
+ it is attached to.</doc:para>
+ <doc:para>If the session is not attached to a seat this value is undefined.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </property>
+ <property name="is-local" type="b" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Whether the session is local</doc:para>
+ <doc:para>FIXME: we need to come up with a concrete definition for this value.
+ It was originally used as a way to identify XDMCP sessions that originate
+ from a remote system.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </property>
+ <property name="idle-hint" type="b" access="readwrite">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ This is a hint used to indicate that the session may be idle.
+ </doc:para>
+ <doc:para>
+ For sessions with a <doc:ref type="property" to="Session:x11-display">x11-display</doc:ref> set (ie. graphical
+ sessions), it is up to each session to delegate the
+ responsibility for updating this value. Typically, the
+ screensaver will set this.
+ </doc:para>
+ <doc:para>However, for non-graphical sessions with a <doc:ref type="property" to="Session:display-device">display-device</doc:ref> set
+ the Session object itself will periodically update this value based
+ on the activity detected on the display-device itself.
+ </doc:para>
+ <doc:para>
+ This should not be considered authoritative.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ </property>
+
+ </interface>
+</node>
diff --git a/src/gdm-local-display-factory.xml b/src/gdm-local-display-factory.xml
new file mode 100644
index 0000000..66fb77c
--- /dev/null
+++ b/src/gdm-local-display-factory.xml
@@ -0,0 +1,20 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/org/gnome/DisplayManager/LocalDisplayFactory">
+ <interface name="org.gnome.DisplayManager.LocalDisplayFactory">
+ <method name="CreateProductDisplay">
+ <arg name="parent_display_id" direction="in" type="o"/>
+ <arg name="relay_address" direction="in" type="s"/>
+ <arg name="id" direction="out" type="o"/>
+ </method>
+ <method name="CreateTransientDisplay">
+ <arg name="id" direction="out" type="o"/>
+ </method>
+ <method name="StartGuestSession">
+ <arg name="id" direction="out" type="o"/>
+ </method>
+ <method name="SwitchToUser">
+ <arg name="username" direction="in" type="s"/>
+ <arg name="id" direction="out" type="o"/>
+ </method>
+ </interface>
+</node>
diff --git a/src/indicator-session.c b/src/indicator-session.c
index e92c36b..b54a5d9 100644
--- a/src/indicator-session.c
+++ b/src/indicator-session.c
@@ -217,6 +217,19 @@ get_icon (IndicatorObject * io)
return INDICATOR_SESSION(io)->status_image;
}
+static void
+user_property_change (DbusmenuMenuitem * item, const gchar * property, const GValue * value, gpointer user_data)
+{
+ if (g_strcmp0(property, USER_ITEM_PROP_LOGGED_IN) == 0) {
+ if (g_value_get_boolean(value)) {
+ gtk_widget_show(GTK_WIDGET(user_data));
+ } else {
+ gtk_widget_hide(GTK_WIDGET(user_data));
+ }
+ }
+ return;
+}
+
/* Builds an item with a hip little logged in icon. */
static gboolean
new_user_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
@@ -263,6 +276,8 @@ new_user_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuCl
dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
+ g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(user_property_change), icon);
+
return TRUE;
}
diff --git a/src/session-service.c b/src/session-service.c
index ee1a9af..514a86f 100644
--- a/src/session-service.c
+++ b/src/session-service.c
@@ -386,6 +386,13 @@ activate_guest_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_da
lock_if_possible();
+ if (dbusmenu_menuitem_property_get_bool(mi, USER_ITEM_PROP_LOGGED_IN)) {
+ if (users_service_dbus_activate_guest_session(USERS_SERVICE_DBUS(user_data))) {
+ return;
+ }
+ g_warning("Unable to activate guest session, falling back to command line activation.");
+ }
+
if (!g_spawn_command_line_async(GUEST_SESSION_LAUNCHER, &error)) {
g_warning("Unable to start guest session: %s", error->message);
g_error_free(error);
@@ -519,6 +526,9 @@ rebuild_items (DbusmenuMenuitem *root,
lock_screen_update_item(lock_menuitem);
}
+ /* Set to NULL just incase we don't end up building one */
+ users_service_dbus_set_guest_item(service, NULL);
+
/* Build all of the user switching items */
if (can_activate == TRUE)
{
@@ -536,6 +546,7 @@ rebuild_items (DbusmenuMenuitem *root,
dbusmenu_menuitem_property_set_bool (guest_mi, USER_ITEM_PROP_LOGGED_IN, FALSE);
dbusmenu_menuitem_child_append (root, guest_mi);
g_signal_connect (G_OBJECT (guest_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_guest_session), NULL);
+ users_service_dbus_set_guest_item(service, guest_mi);
}
if (check_new_session ())
@@ -597,6 +608,7 @@ rebuild_items (DbusmenuMenuitem *root,
}
dbusmenu_menuitem_child_append (root, mi);
g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_user_session), user);
+ user->menuitem = mi;
}
}
diff --git a/src/users-service-dbus.c b/src/users-service-dbus.c
index 4aefdff..86007c3 100644
--- a/src/users-service-dbus.c
+++ b/src/users-service-dbus.c
@@ -31,10 +31,16 @@
#include <dbus/dbus-glib-lowlevel.h>
#include "dbus-shared-names.h"
+#include "gdm-local-display-factory-client.h"
#include "users-service-dbus.h"
#include "users-service-client.h"
#include "users-service-marshal.h"
#include "consolekit-manager-client.h"
+#include "consolekit-session-client.h"
+
+#define CK_ADDR "org.freedesktop.ConsoleKit"
+#define CK_SESSION_IFACE "org.freedesktop.ConsoleKit.Session"
+
static void users_service_dbus_class_init (UsersServiceDbusClass *klass);
static void users_service_dbus_init (UsersServiceDbus *self);
@@ -65,7 +71,7 @@ static void seat_proxy_session_removed (DBusGProxy *seat_
static gboolean do_add_session (UsersServiceDbus *service,
UserData *user,
const gchar *ssid);
-static gchar * get_seat_internal (UsersServiceDbus *self);
+static gchar * get_seat_internal (DBusGProxy *proxy);
/* Private */
typedef struct _UsersServiceDbusPrivate UsersServiceDbusPrivate;
@@ -80,12 +86,16 @@ struct _UsersServiceDbusPrivate
DBusGConnection *system_bus;
DBusGProxy *gdm_proxy;
+ DBusGProxy *gdm_local_proxy;
DBusGProxy *ck_proxy;
DBusGProxy *seat_proxy;
DBusGProxy *session_proxy;
GHashTable *exclusions;
GHashTable *sessions;
+
+ DbusmenuMenuitem * guest_item;
+ gchar * guest_session_id;
};
#define USERS_SERVICE_DBUS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbusPrivate))
@@ -155,6 +165,8 @@ users_service_dbus_init (UsersServiceDbus *self)
priv->users = NULL;
priv->count = 0;
+ priv->guest_item = NULL;
+ priv->guest_session_id = NULL;
/* Get the system bus */
priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
@@ -198,6 +210,13 @@ users_service_dbus_dispose (GObject *object)
static void
users_service_dbus_finalize (GObject *object)
{
+ UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (object);
+
+ if (priv->guest_session_id != NULL) {
+ g_free(priv->guest_session_id);
+ priv->guest_session_id = NULL;
+ }
+
G_OBJECT_CLASS (users_service_dbus_parent_class)->finalize (object);
}
@@ -266,6 +285,11 @@ create_gdm_proxy (UsersServiceDbus *self)
G_CALLBACK (user_updated),
self,
NULL);
+
+ priv->gdm_local_proxy = dbus_g_proxy_new_for_name (priv->system_bus,
+ "org.gnome.DisplayManager",
+ "/org/gnome/DisplayManager/LocalDisplayFactory",
+ "org.gnome.DisplayManager.LocalDisplayFactory");
}
static void
@@ -341,9 +365,9 @@ create_cksession_proxy (UsersServiceDbus *service)
UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service);
priv->session_proxy = dbus_g_proxy_new_for_name (priv->system_bus,
- "org.freedesktop.ConsoleKit",
+ CK_ADDR,
priv->ssid,
- "org.freedesktop.ConsoleKit.Session");
+ CK_SESSION_IFACE);
if (!priv->session_proxy)
{
@@ -383,24 +407,18 @@ get_seat (UsersServiceDbus *service)
priv->ssid = ssid;
create_cksession_proxy (service);
- seat = get_seat_internal (service);
+ seat = get_seat_internal (priv->session_proxy);
return seat;
}
static gchar *
-get_seat_internal (UsersServiceDbus *self)
+get_seat_internal (DBusGProxy *proxy)
{
- UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
GError *error = NULL;
gchar *seat = NULL;
- if (!dbus_g_proxy_call (priv->session_proxy,
- "GetSeatId",
- &error,
- G_TYPE_INVALID,
- DBUS_TYPE_G_OBJECT_PATH, &seat,
- G_TYPE_INVALID))
+ if (!org_freedesktop_ConsoleKit_Session_get_seat_id (proxy, &seat, &error))
{
if (error)
{
@@ -421,13 +439,22 @@ get_unix_user (UsersServiceDbus *service,
UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service);
GError *error = NULL;
guint uid;
+ DBusGProxy *session_proxy;
+
+ g_debug("Building session proxy for: %s", session_id);
+ session_proxy = dbus_g_proxy_new_for_name_owner(priv->system_bus,
+ CK_ADDR,
+ session_id,
+ CK_SESSION_IFACE,
+ &error);
+
+ if (error != NULL) {
+ g_warning("Unable to get CK Session proxy: %s", error->message);
+ g_error_free(error);
+ return FALSE;
+ }
- if (dbus_g_proxy_call (priv->session_proxy,
- "GetUnixUser",
- &error,
- G_TYPE_INVALID,
- G_TYPE_UINT, &uid,
- G_TYPE_INVALID))
+ if (!org_freedesktop_ConsoleKit_Session_get_unix_user(session_proxy, &uid, &error))
{
if (error)
{
@@ -435,6 +462,7 @@ get_unix_user (UsersServiceDbus *service,
g_error_free (error);
}
+ g_object_unref(session_proxy);
return FALSE;
}
@@ -443,6 +471,7 @@ get_unix_user (UsersServiceDbus *service,
*uidp = (uid_t)uid;
}
+ g_object_unref(session_proxy);
return TRUE;
}
@@ -455,19 +484,29 @@ do_add_session (UsersServiceDbus *service,
GError *error = NULL;
gchar *seat = NULL;
gchar *xdisplay = NULL;
+ DBusGProxy * session_proxy;
GList *l;
- seat = get_seat_internal (service);
+ session_proxy = dbus_g_proxy_new_for_name_owner(priv->system_bus,
+ CK_ADDR,
+ ssid,
+ CK_SESSION_IFACE,
+ &error);
- if (!seat || !priv->seat || strcmp (seat, priv->seat) != 0)
+ if (error != NULL) {
+ g_warning("Unable to get CK Session proxy: %s", error->message);
+ g_error_free(error);
return FALSE;
+ }
- if (!dbus_g_proxy_call (priv->session_proxy,
- "GetX11Display",
- &error,
- G_TYPE_INVALID,
- G_TYPE_STRING, &xdisplay,
- G_TYPE_INVALID))
+ seat = get_seat_internal (session_proxy);
+
+ if (!seat || !priv->seat || strcmp (seat, priv->seat) != 0) {
+ g_object_unref(session_proxy);
+ return FALSE;
+ }
+
+ if (!org_freedesktop_ConsoleKit_Session_get_x11_display (session_proxy, &xdisplay, &error))
{
if (error)
{
@@ -475,9 +514,12 @@ do_add_session (UsersServiceDbus *service,
g_error_free (error);
}
+ g_object_unref(session_proxy);
return FALSE;
}
+ g_object_unref(session_proxy);
+
if (!xdisplay || xdisplay[0] == '\0')
return FALSE;
@@ -491,6 +533,10 @@ do_add_session (UsersServiceDbus *service,
g_debug ("Adding session %s", ssid);
user->sessions = g_list_prepend (user->sessions, g_strdup (ssid));
+
+ if (user->menuitem != NULL) {
+ dbusmenu_menuitem_property_set_bool(user->menuitem, USER_ITEM_PROP_LOGGED_IN, TRUE);
+ }
}
else
{
@@ -556,6 +602,17 @@ seat_proxy_session_added (DBusGProxy *seat_proxy,
return;
}
+ /* We need to special case guest here because it doesn't
+ show up in the GDM user tables. */
+ if (g_strcmp0("guest", pwent->pw_name) == 0) {
+ if (priv->guest_item != NULL) {
+ dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, TRUE);
+ }
+ priv->guest_session_id = g_strdup(session_id);
+ g_debug("Found guest session: %s", priv->guest_session_id);
+ return;
+ }
+
user = g_hash_table_lookup (priv->users, pwent->pw_name);
if (!user)
{
@@ -576,8 +633,17 @@ seat_proxy_session_removed (DBusGProxy *seat_proxy,
GList *l;
username = g_hash_table_lookup (priv->sessions, session_id);
- if (!username)
+ if (!username) {
+ if (g_strcmp0(session_id, priv->guest_session_id) == 0) {
+ g_debug("Removing guest session: %s", priv->guest_session_id);
+ if (priv->guest_item != NULL) {
+ dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, FALSE);
+ }
+ g_free(priv->guest_session_id);
+ priv->guest_session_id = NULL;
+ }
return;
+ }
user = g_hash_table_lookup (priv->users, username);
if (!user)
@@ -592,6 +658,9 @@ seat_proxy_session_removed (DBusGProxy *seat_proxy,
g_free (l->data);
user->sessions = g_list_delete_link (user->sessions, l);
+ if (user->menuitem != NULL && user->sessions == NULL) {
+ dbusmenu_menuitem_property_set_bool(user->menuitem, USER_ITEM_PROP_LOGGED_IN, FALSE);
+ }
}
else
{
@@ -657,6 +726,7 @@ sync_users (UsersServiceDbus *self)
user->login_count = g_value_get_int (g_value_array_get_nth (values, 4));
user->icon_url = g_strdup (g_value_get_string (g_value_array_get_nth (values, 5)));
user->real_name_conflict = FALSE;
+ user->menuitem = NULL;
g_hash_table_insert (priv->users,
g_strdup (user->user_name),
@@ -706,21 +776,16 @@ session_is_login_window (UsersServiceDbus *self,
char *type = NULL;
if (!(proxy = dbus_g_proxy_new_for_name (priv->system_bus,
- "org.freedesktop.ConsoleKit",
+ CK_ADDR,
ssid,
- "org.freedesktop.ConsoleKit.Session")))
+ CK_SESSION_IFACE)))
{
g_warning ("Failed to get ConsoleKit proxy");
return FALSE;
}
- if (!dbus_g_proxy_call (proxy,
- "GetSessionType",
- &error,
- G_TYPE_INVALID,
- G_TYPE_STRING, &type,
- G_TYPE_INVALID))
+ if (!org_freedesktop_ConsoleKit_Session_get_session_type (proxy, &type, &error))
{
g_warning ("Can't call GetSessionType: %s", error->message);
g_error_free (error);
@@ -1005,61 +1070,21 @@ users_service_dbus_get_user_list (UsersServiceDbus *self)
return g_hash_table_get_values (priv->users);
}
+/* Activates the guest account if it can. */
+gboolean
+users_service_dbus_activate_guest_session (UsersServiceDbus *self)
+{
+ UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
+ return org_gnome_DisplayManager_LocalDisplayFactory_switch_to_user(priv->gdm_local_proxy, "guest", NULL, NULL);
+}
+
+/* Activates a specific user */
gboolean
users_service_dbus_activate_user_session (UsersServiceDbus *self,
UserData *user)
{
- UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
- DBusMessage *message = NULL;
- DBusMessage *reply = NULL;
- DBusError error;
-
- dbus_error_init (&error);
-
- if (!(message = dbus_message_new_method_call ("org.gnome.DisplayManager",
- "/org/gnome/DisplayManager/LocalDisplayFactory",
- "org.gnome.DisplayManager.LocalDisplayFactory",
- "SwitchToUser")))
- {
- g_warning ("failed to create new message");
- return FALSE;
- }
-
- if (!dbus_message_append_args (message,
- DBUS_TYPE_STRING, &user->user_name,
- DBUS_TYPE_INVALID))
- {
- g_warning ("failed to append args");
- return FALSE;
- }
-
- if (!(reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (priv->system_bus),
- message,
- -1,
- &error)))
- {
- if (dbus_error_is_set (&error))
- {
- g_warning ("Failed to send message: %s", error.message);
- dbus_error_free (&error);
-
- return FALSE;
- }
- }
-
- if (message)
- {
- dbus_message_unref (message);
- }
-
- if (reply)
- {
- dbus_message_unref (reply);
- }
-
- dbus_error_free (&error);
-
- return TRUE;
+ UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
+ return org_gnome_DisplayManager_LocalDisplayFactory_switch_to_user(priv->gdm_local_proxy, user->user_name, NULL, NULL);
}
gboolean
@@ -1094,3 +1119,17 @@ users_service_dbus_can_activate_session (UsersServiceDbus *self)
return can_activate;
}
+
+/* Sets the menu item that represents the guest account */
+void
+users_service_dbus_set_guest_item (UsersServiceDbus * self, DbusmenuMenuitem * mi)
+{
+ UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
+ priv->guest_item = mi;
+
+ if (priv->guest_session_id != NULL) {
+ dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, TRUE);
+ }
+
+ return;
+}
diff --git a/src/users-service-dbus.h b/src/users-service-dbus.h
index bba88a7..4798d64 100644
--- a/src/users-service-dbus.h
+++ b/src/users-service-dbus.h
@@ -22,6 +22,7 @@
#include <glib.h>
#include <glib-object.h>
+#include <libdbusmenu-glib/menuitem.h>
G_BEGIN_DECLS
@@ -47,7 +48,10 @@ struct _UserData
GList *sessions;
+ /* Whether the real name here conflicts with another in the system */
gboolean real_name_conflict;
+ /* The menuitem representing this user if there is one. */
+ DbusmenuMenuitem * menuitem;
UsersServiceDbus *service;
};
@@ -80,6 +84,9 @@ GList *users_service_dbus_get_user_list (UsersServiceDbus *self);
gboolean users_service_dbus_can_activate_session (UsersServiceDbus *self);
gboolean users_service_dbus_activate_user_session (UsersServiceDbus *self,
UserData *user);
+gboolean users_service_dbus_activate_guest_session (UsersServiceDbus *self);
+void users_service_dbus_set_guest_item (UsersServiceDbus * self,
+ DbusmenuMenuitem * mi);
G_END_DECLS