diff options
Diffstat (limited to 'src/ck-seat.c')
-rw-r--r-- | src/ck-seat.c | 234 |
1 files changed, 225 insertions, 9 deletions
diff --git a/src/ck-seat.c b/src/ck-seat.c index a77e0b1..e04b569 100644 --- a/src/ck-seat.c +++ b/src/ck-seat.c @@ -25,13 +25,6 @@ #include <fcntl.h> #include <unistd.h> #include <string.h> -#ifdef HAVE_PATHS_H -#include <paths.h> -#endif /* HAVE_PATHS_H */ - -#ifndef _PATH_TTY -#define _PATH_TTY "/dev/tty" -#endif #include <glib.h> #include <glib/gi18n.h> @@ -41,6 +34,8 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> +#include "ck-sysdeps.h" + #include "ck-seat.h" #include "ck-seat-glue.h" #include "ck-marshal.h" @@ -53,11 +48,13 @@ #define CK_DBUS_PATH "/org/freedesktop/ConsoleKit" #define CK_DBUS_NAME "org.freedesktop.ConsoleKit" + struct CkSeatPrivate { char *id; CkSeatKind kind; GHashTable *sessions; + GPtrArray *devices; CkSession *active_session; @@ -70,6 +67,8 @@ enum { ACTIVE_SESSION_CHANGED, SESSION_ADDED, SESSION_REMOVED, + DEVICE_ADDED, + DEVICE_REMOVED, LAST_SIGNAL }; @@ -169,6 +168,7 @@ _seat_activate_session (CkSeat *seat, CkSession *session, DBusGMethodInvocation *context) { + gboolean res; gboolean ret; guint num; char *device; @@ -202,7 +202,8 @@ _seat_activate_session (CkSeat *seat, ck_session_get_display_device (session, &device, NULL); - if (device == NULL || (sscanf (device, _PATH_TTY "%u", &num) != 1)) { + res = ck_get_console_num_from_device (device, &num); + if (! res) { GError *error; error = g_error_new (CK_SEAT_ERROR, CK_SEAT_ERROR_GENERAL, @@ -486,7 +487,7 @@ update_active_vt (CkSeat *seat, CkSession *session; char *device; - device = g_strdup_printf (_PATH_TTY "%u", num); + device = ck_get_console_device_for_num (num); g_debug ("Active device: %s", device); @@ -605,6 +606,60 @@ ck_seat_can_activate_sessions (CkSeat *seat, return TRUE; } +static gboolean +ck_seat_has_device (CkSeat *seat, + GValueArray *device, + gboolean *result, + GError *error) +{ + g_return_val_if_fail (CK_IS_SEAT (seat), FALSE); + + return TRUE; +} + +gboolean +ck_seat_add_device (CkSeat *seat, + GValueArray *device, + GError **error) +{ + gboolean present; + + g_return_val_if_fail (CK_IS_SEAT (seat), FALSE); + + /* FIXME: check if already present */ + present = FALSE; + ck_seat_has_device (seat, device, &present, NULL); + if (present) { + g_set_error (error, CK_SEAT_ERROR, CK_SEAT_ERROR_GENERAL, "%s", "Device already present"); + return FALSE; + } + + g_ptr_array_add (seat->priv->devices, g_boxed_copy (CK_TYPE_DEVICE, device)); + + g_debug ("Emitting device added signal"); + + g_signal_emit (seat, signals [DEVICE_ADDED], 0, device); + + return TRUE; +} + +gboolean +ck_seat_remove_device (CkSeat *seat, + GValueArray *device, + GError **error) +{ + g_return_val_if_fail (CK_IS_SEAT (seat), FALSE); + + /* FIXME: check if already present */ + if (0) { + g_debug ("Emitting device removed signal"); + + g_signal_emit (seat, signals [DEVICE_REMOVED], 0, device); + } + + return TRUE; +} + gboolean ck_seat_get_kind (CkSeat *seat, CkSeatKind *kind, @@ -689,6 +744,38 @@ ck_seat_get_sessions (CkSeat *seat, } static void +copy_devices (gpointer data, + GPtrArray **array) +{ + g_ptr_array_add (*array, data); +} + +/* + Example: + dbus-send --system --dest=org.freedesktop.ConsoleKit \ + --type=method_call --print-reply --reply-timeout=2000 \ + /org/freedesktop/ConsoleKit/Seat1 \ + org.freedesktop.ConsoleKit.Seat.GetDevices +*/ + +gboolean +ck_seat_get_devices (CkSeat *seat, + GPtrArray **devices, + GError **error) +{ + g_return_val_if_fail (CK_IS_SEAT (seat), FALSE); + + if (devices == NULL) { + return FALSE; + } + + *devices = g_ptr_array_sized_new (seat->priv->devices->len); + g_ptr_array_foreach (seat->priv->devices, (GFunc)copy_devices, devices); + + return TRUE; +} + +static void _ck_seat_set_id (CkSeat *seat, const char *id) { @@ -809,6 +896,25 @@ ck_seat_class_init (CkSeatClass *klass) G_TYPE_NONE, 1, G_TYPE_STRING); + signals [DEVICE_ADDED] = g_signal_new ("device-added", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSeatClass, device_added), + NULL, + NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + 1, CK_TYPE_DEVICE); + signals [DEVICE_REMOVED] = g_signal_new ("device-removed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (CkSeatClass, device_removed), + NULL, + NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + 1, CK_TYPE_DEVICE); + g_object_class_install_property (object_class, PROP_ID, g_param_spec_string ("id", @@ -839,6 +945,7 @@ ck_seat_init (CkSeat *seat) g_str_equal, g_free, (GDestroyNotify) g_object_unref); + seat->priv->devices = g_ptr_array_new (); } static void @@ -861,6 +968,7 @@ ck_seat_finalize (GObject *object) g_object_unref (seat->priv->active_session); } + g_ptr_array_free (seat->priv->devices, TRUE); g_hash_table_destroy (seat->priv->sessions); g_free (seat->priv->id); @@ -887,3 +995,111 @@ ck_seat_new (const char *sid, return CK_SEAT (object); } + +CkSeat * +ck_seat_new_with_devices (const char *sid, + CkSeatKind kind, + GPtrArray *devices) +{ + GObject *object; + gboolean res; + int i; + + object = g_object_new (CK_TYPE_SEAT, + "id", sid, + "kind", kind, + NULL); + + if (devices != NULL) { + for (i = 0; i < devices->len; i++) { + ck_seat_add_device (CK_SEAT (object), g_ptr_array_index (devices, i), NULL); + } + } + + res = register_seat (CK_SEAT (object)); + if (! res) { + g_object_unref (object); + return NULL; + } + + return CK_SEAT (object); +} + +CkSeat * +ck_seat_new_from_file (const char *sid, + const char *path) +{ + GKeyFile *key_file; + gboolean res; + GError *error; + char *group; + CkSeat *seat; + gboolean hidden; + GPtrArray *devices; + char **device_list; + gsize ndevices; + gsize i; + + key_file = g_key_file_new (); + error = NULL; + res = g_key_file_load_from_file (key_file, + path, + G_KEY_FILE_NONE, + &error); + if (! res) { + g_warning ("Unable to load seats from file %s: %s", path, error->message); + g_error_free (error); + return NULL; + } + + group = g_key_file_get_start_group (key_file); + if (group == NULL || strcmp (group, "Seat Entry") != 0) { + g_warning ("Not a seat file: %s", path); + return NULL; + } + + hidden = g_key_file_get_boolean (key_file, group, "Hidden", NULL); + if (hidden) { + g_debug ("Seat is hidden"); + return NULL; + } + + device_list = g_key_file_get_string_list (key_file, group, "Devices", &ndevices, NULL); + + g_debug ("Creating seat %s with %d devices", sid, ndevices); + + devices = g_ptr_array_sized_new (ndevices); + + for (i = 0; i < ndevices; i++) { + char **split; + GValue device_val = { 0, }; + + split = g_strsplit (device_list[i], ":", 2); + + if (split == NULL) { + continue; + } + + g_debug ("Adding device: %s %s", split[0], split[1]); + + g_value_init (&device_val, CK_TYPE_DEVICE); + g_value_take_boxed (&device_val, + dbus_g_type_specialized_construct (CK_TYPE_DEVICE)); + dbus_g_type_struct_set (&device_val, + 0, split[0], + 1, split[1], + G_MAXUINT); + + g_ptr_array_add (devices, g_value_get_boxed (&device_val)); + + g_strfreev (split); + } + + g_free (group); + + seat = ck_seat_new_with_devices (sid, CK_SEAT_KIND_STATIC, devices); + + g_ptr_array_free (devices, TRUE); + + return seat; +} |