From a08530e838218b3c5859550058e78b8f1abee434 Mon Sep 17 00:00:00 2001 From: William Jon McCann Date: Wed, 25 Oct 2006 14:38:19 -0400 Subject: Initial import --- src/ck-session.c | 744 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 744 insertions(+) create mode 100644 src/ck-session.c (limited to 'src/ck-session.c') diff --git a/src/ck-session.c b/src/ck-session.c new file mode 100644 index 0000000..278d7bc --- /dev/null +++ b/src/ck-session.c @@ -0,0 +1,744 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2006 William Jon McCann + * + * 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. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#define DBUS_API_SUBJECT_TO_CHANGE +#include +#include + +#include "ck-session.h" +#include "ck-session-glue.h" +#include "ck-marshal.h" +#include "ck-debug.h" + +#define CK_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CK_TYPE_SESSION, CkSessionPrivate)) + +#define CK_DBUS_PATH "/org/freedesktop/ConsoleKit" +#define CK_DBUS_NAME "org.freedesktop.ConsoleKit" + +struct CkSessionPrivate +{ + char *id; + char *cookie; + char *seat_id; + + char *session_type; + char *display_device; + char *xdisplay; + char *host_name; + guint uid; + + gboolean active; + gboolean is_local; + + DBusGConnection *connection; +}; + +enum { + ACTIVATE, + LOCK, + UNLOCK, + ACTIVE_CHANGED, + LAST_SIGNAL +}; + +enum { + PROP_0, + PROP_ID, + PROP_COOKIE, + PROP_USER, + PROP_X11_DISPLAY, + PROP_DISPLAY_DEVICE, + PROP_SESSION_TYPE, + PROP_HOST_NAME, + PROP_IS_LOCAL, + PROP_ACTIVE, +}; + +static guint signals [LAST_SIGNAL] = { 0, }; + +static void ck_session_class_init (CkSessionClass *klass); +static void ck_session_init (CkSession *session); +static void ck_session_finalize (GObject *object); + +G_DEFINE_TYPE (CkSession, ck_session, G_TYPE_OBJECT) + +GQuark +ck_session_error_quark (void) +{ + static GQuark ret = 0; + if (ret == 0) { + ret = g_quark_from_static_string ("ck_session_error"); + } + + return ret; +} + +static gboolean +register_session (CkSession *session) +{ + GError *error = NULL; + + error = NULL; + session->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (session->priv->connection == NULL) { + if (error != NULL) { + g_critical ("error getting system bus: %s", error->message); + g_error_free (error); + } + return FALSE; + } + + dbus_g_connection_register_g_object (session->priv->connection, session->priv->id, G_OBJECT (session)); + + return TRUE; +} + + +/* + lock and unlock are separate functions because: + 1. we don't maintain state for locked + 2. so security policy can be handled separately +*/ +gboolean +ck_session_lock (CkSession *session, + DBusGMethodInvocation *context) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_signal_emit (session, signals [LOCK], 0); + + dbus_g_method_return (context, TRUE); + + return TRUE; +} + +gboolean +ck_session_unlock (CkSession *session, + DBusGMethodInvocation *context) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_signal_emit (session, signals [UNLOCK], 0); + + dbus_g_method_return (context, TRUE); + + return TRUE; +} + +gboolean +ck_session_activate (CkSession *session, + DBusGMethodInvocation *context) +{ + gboolean res; + + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + res = FALSE; + g_signal_emit (session, signals [ACTIVATE], 0, context, &res); + if (! res) { + GError *error; + + /* if the signal is not handled then either: + a) aren't attached to seat + b) seat doesn't support activation changes */ + ck_debug ("Activate signal not handled"); + + error = g_error_new (CK_SESSION_ERROR, + CK_SESSION_ERROR_GENERAL, + _("Unable to activate session")); + dbus_g_method_return_error (context, error); + g_error_free (error); + return FALSE; + } + + return TRUE; +} + +gboolean +ck_session_set_active (CkSession *session, + gboolean active, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (session->priv->active != active) { + session->priv->active = active; + g_signal_emit (session, signals [ACTIVE_CHANGED], 0, active); + } + + return TRUE; +} + +gboolean +ck_session_set_is_local (CkSession *session, + gboolean is_local, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (session->priv->is_local != is_local) { + session->priv->is_local = is_local; + } + + return TRUE; +} + +gboolean +ck_session_get_id (CkSession *session, + char **id, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (id != NULL) { + *id = g_strdup (session->priv->id); + } + + return TRUE; +} + +gboolean +ck_session_get_seat_id (CkSession *session, + char **id, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (id != NULL) { + *id = g_strdup (session->priv->seat_id); + } + + return TRUE; +} + +gboolean +ck_session_get_user (CkSession *session, + guint *uid, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (uid != NULL) { + *uid = session->priv->uid; + } + + return TRUE; +} + +gboolean +ck_session_get_x11_display (CkSession *session, + char **xdisplay, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (xdisplay != NULL) { + *xdisplay = g_strdup (session->priv->xdisplay); + } + + return TRUE; +} + +gboolean +ck_session_get_display_device (CkSession *session, + char **display_device, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (display_device != NULL) { + *display_device = g_strdup (session->priv->display_device); + } + + return TRUE; +} + +gboolean +ck_session_get_host_name (CkSession *session, + char **host_name, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (host_name != NULL) { + *host_name = g_strdup (session->priv->host_name); + } + + return TRUE; +} + +gboolean +ck_session_get_session_type (CkSession *session, + char **type, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (type != NULL) { + *type = g_strdup (session->priv->session_type); + } + + return TRUE; +} + +gboolean +ck_session_is_active (CkSession *session, + gboolean *active, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (active != NULL) { + *active = session->priv->active; + } + + return TRUE; +} + +gboolean +ck_session_is_local (CkSession *session, + gboolean *local, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (local != NULL) { + *local = session->priv->is_local; + } + + return TRUE; +} + +gboolean +ck_session_set_id (CkSession *session, + const char *id, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_free (session->priv->id); + session->priv->id = g_strdup (id); + + return TRUE; +} + +gboolean +ck_session_set_cookie (CkSession *session, + const char *cookie, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_free (session->priv->cookie); + session->priv->cookie = g_strdup (cookie); + + return TRUE; +} + +gboolean +ck_session_set_seat_id (CkSession *session, + const char *id, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_free (session->priv->seat_id); + session->priv->seat_id = g_strdup (id); + + return TRUE; +} + +gboolean +ck_session_set_user (CkSession *session, + guint uid, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + session->priv->uid = uid; + + return TRUE; +} + +gboolean +ck_session_set_x11_display (CkSession *session, + const char *xdisplay, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_free (session->priv->xdisplay); + session->priv->xdisplay = g_strdup (xdisplay); + + return TRUE; +} + +gboolean +ck_session_set_display_device (CkSession *session, + const char *display_device, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_free (session->priv->display_device); + session->priv->display_device = g_strdup (display_device); + + return TRUE; +} + +gboolean +ck_session_set_host_name (CkSession *session, + const char *host_name, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_free (session->priv->host_name); + session->priv->host_name = g_strdup (host_name); + + return TRUE; +} + +gboolean +ck_session_set_session_type (CkSession *session, + const char *type, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + g_free (session->priv->session_type); + session->priv->session_type = g_strdup (type); + + return TRUE; +} + +static void +ck_session_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + CkSession *self; + + self = CK_SESSION (object); + + switch (prop_id) { + case PROP_ACTIVE: + ck_session_set_active (self, g_value_get_boolean (value), NULL); + break; + case PROP_IS_LOCAL: + ck_session_set_is_local (self, g_value_get_boolean (value), NULL); + break; + case PROP_ID: + ck_session_set_id (self, g_value_get_string (value), NULL); + break; + case PROP_COOKIE: + ck_session_set_cookie (self, g_value_get_string (value), NULL); + break; + case PROP_SESSION_TYPE: + ck_session_set_session_type (self, g_value_get_string (value), NULL); + break; + case PROP_X11_DISPLAY: + ck_session_set_x11_display (self, g_value_get_string (value), NULL); + break; + case PROP_DISPLAY_DEVICE: + ck_session_set_display_device (self, g_value_get_string (value), NULL); + break; + case PROP_USER: + ck_session_set_user (self, g_value_get_uint (value), NULL); + break; + case PROP_HOST_NAME: + ck_session_set_host_name (self, g_value_get_string (value), NULL); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ck_session_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + CkSession *self; + + self = CK_SESSION (object); + + switch (prop_id) { + case PROP_ACTIVE: + g_value_set_boolean (value, self->priv->active); + break; + case PROP_IS_LOCAL: + g_value_set_boolean (value, self->priv->is_local); + break; + case PROP_ID: + g_value_set_string (value, self->priv->id); + break; + case PROP_COOKIE: + g_value_set_string (value, self->priv->cookie); + break; + case PROP_SESSION_TYPE: + g_value_set_string (value, self->priv->session_type); + break; + case PROP_X11_DISPLAY: + g_value_set_string (value, self->priv->xdisplay); + break; + case PROP_DISPLAY_DEVICE: + g_value_set_string (value, self->priv->display_device); + break; + case PROP_USER: + g_value_set_uint (value, self->priv->uid); + break; + case PROP_HOST_NAME: + g_value_set_string (value, self->priv->host_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ck_session_class_init (CkSessionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = ck_session_get_property; + object_class->set_property = ck_session_set_property; + object_class->finalize = ck_session_finalize; + + signals [ACTIVE_CHANGED] = + g_signal_new ("active-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSessionClass, active_changed), + NULL, + NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, + 1, G_TYPE_BOOLEAN); + signals [ACTIVATE] = + g_signal_new ("activate", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSessionClass, activate), + NULL, + NULL, + ck_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, + 1, G_TYPE_POINTER); + signals [LOCK] = + g_signal_new ("lock", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSessionClass, lock), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + signals [UNLOCK] = + g_signal_new ("unlock", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSessionClass, unlock), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + g_object_class_install_property (object_class, + PROP_ACTIVE, + g_param_spec_boolean ("active", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_IS_LOCAL, + g_param_spec_boolean ("is-local", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_ID, + g_param_spec_string ("id", + "id", + "id", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_COOKIE, + g_param_spec_string ("cookie", + "cookie", + "cookie", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_SESSION_TYPE, + g_param_spec_string ("session-type", + "session-type", + "session type", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_X11_DISPLAY, + g_param_spec_string ("x11-display", + "x11-display", + "X11 Display", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_DISPLAY_DEVICE, + g_param_spec_string ("display-device", + "display-device", + "Display device", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_HOST_NAME, + g_param_spec_string ("host-name", + "host-name", + "Host name", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_USER, + g_param_spec_uint ("user", + "User Id", + "User Id", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_type_class_add_private (klass, sizeof (CkSessionPrivate)); + + dbus_g_object_type_install_info (CK_TYPE_SESSION, &dbus_glib_ck_session_object_info); +} + +static void +ck_session_init (CkSession *session) +{ + session->priv = CK_SESSION_GET_PRIVATE (session); + +} + +static void +ck_session_finalize (GObject *object) +{ + CkSession *session; + + g_return_if_fail (object != NULL); + g_return_if_fail (CK_IS_SESSION (object)); + + session = CK_SESSION (object); + + g_return_if_fail (session->priv != NULL); + + g_free (session->priv->id); + g_free (session->priv->seat_id); + g_free (session->priv->session_type); + g_free (session->priv->xdisplay); + g_free (session->priv->host_name); + + G_OBJECT_CLASS (ck_session_parent_class)->finalize (object); +} + +CkSession * +ck_session_new (const char *ssid, + const char *cookie) +{ + GObject *object; + gboolean res; + + object = g_object_new (CK_TYPE_SESSION, + "id", ssid, + "cookie", cookie, + NULL); + res = register_session (CK_SESSION (object)); + if (! res) { + g_object_unref (object); + return NULL; + } + + return CK_SESSION (object); +} + +#define CK_TYPE_PARAMETER_STRUCT (dbus_g_type_get_struct ("GValueArray", \ + G_TYPE_STRING, \ + G_TYPE_VALUE, \ + G_TYPE_INVALID)) + +CkSession * +ck_session_new_with_parameters (const char *ssid, + const char *cookie, + const GPtrArray *parameters) +{ + GObject *object; + gboolean res; + int i; + + object = g_object_new (CK_TYPE_SESSION, + "id", ssid, + "cookie", cookie, + NULL); + + for (i = 0; i < parameters->len; i++) { + GValue val_struct = { 0, }; + const char *prop_name; + GValue *prop_val; + + g_value_init (&val_struct, CK_TYPE_PARAMETER_STRUCT); + g_value_set_static_boxed (&val_struct, g_ptr_array_index (parameters, i)); + + dbus_g_type_struct_get (&val_struct, + 0, &prop_name, + 1, &prop_val, + G_MAXUINT); + + g_object_set_property (object, prop_name, prop_val); + } + + res = register_session (CK_SESSION (object)); + if (! res) { + g_object_unref (object); + return NULL; + } + + return CK_SESSION (object); +} -- cgit