summaryrefslogtreecommitdiff
path: root/src/ck-seat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ck-seat.c')
-rw-r--r--src/ck-seat.c234
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;
+}