summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Jon McCann <mccann@jhu.edu>2007-07-20 17:42:01 -0400
committerWilliam Jon McCann <mccann@jhu.edu>2007-07-20 17:42:01 -0400
commit289fff6aaaa206572efa768c4063111582d79f9d (patch)
treeafd152d571aa98d68a1ca72e1c2e3fa1c1e2917d
parentf6027221567fcb9ead1823e2da4eb9783f2db9ce (diff)
Add preliminary support for seats with devices
-rw-r--r--data/00-primary.seat5
-rw-r--r--data/Makefile.am4
-rw-r--r--src/ck-manager.c54
-rw-r--r--src/ck-seat.c219
-rw-r--r--src/ck-seat.h36
-rw-r--r--src/ck-seat.xml9
6 files changed, 319 insertions, 8 deletions
diff --git a/data/00-primary.seat b/data/00-primary.seat
new file mode 100644
index 0000000..51effa7
--- /dev/null
+++ b/data/00-primary.seat
@@ -0,0 +1,5 @@
+[Seat Entry]
+Version=1.0
+Name=Primary seat
+Hidden=false
+Devices=linux-sysfs:/sys/devices/pci0000:00/0000:00:01.0; \ No newline at end of file
diff --git a/data/Makefile.am b/data/Makefile.am
index f9216c4..aa0f52f 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -3,6 +3,9 @@ NULL =
dbusconfdir = $(DBUS_SYS_DIR)
dbusconf_DATA = ConsoleKit.conf
+seatdir = $(sysconfdir)/ConsoleKit/seats.d
+seat_DATA = 00-primary.seat
+
SCRIPT_IN_FILES = ConsoleKit.in
initddir=$(sysconfdir)/rc.d/init.d
initd_SCRIPTS= \
@@ -21,6 +24,7 @@ edit = sed \
EXTRA_DIST = \
$(dbusconf_DATA) \
+ $(seat_DATA) \
$(SCRIPT_IN_FILES) \
$(NULL)
diff --git a/src/ck-manager.c b/src/ck-manager.c
index 99eeed6..3007437 100644
--- a/src/ck-manager.c
+++ b/src/ck-manager.c
@@ -47,6 +47,8 @@
#define CK_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CK_TYPE_MANAGER, CkManagerPrivate))
+#define CK_SEAT_DIR SYSCONFDIR "/ConsoleKit/seats.d"
+
#define CK_DBUS_PATH "/org/freedesktop/ConsoleKit"
#define CK_MANAGER_DBUS_PATH CK_DBUS_PATH "/Manager"
#define CK_MANAGER_DBUS_NAME "org.freedesktop.ConsoleKit.Manager"
@@ -1545,11 +1547,59 @@ ck_manager_get_seats (CkManager *manager,
}
static void
-create_seats (CkManager *manager)
+add_seat_for_file (CkManager *manager,
+ const char *filename)
{
+ char *sid;
CkSeat *seat;
- seat = add_new_seat (manager, CK_SEAT_KIND_STATIC);
+ sid = generate_seat_id (manager);
+
+ seat = ck_seat_new_from_file (sid, filename);
+ if (seat == NULL) {
+ /* returns null if connection to bus fails */
+ g_free (sid);
+ return;
+ }
+
+ g_hash_table_insert (manager->priv->seats, sid, seat);
+
+ g_debug ("Added seat: %s", sid);
+
+ g_signal_emit (manager, signals [SEAT_ADDED], 0, sid);
+}
+
+static gboolean
+load_seats_from_dir (CkManager *manager)
+{
+ GDir *d;
+ GError *error;
+ char *file;
+
+ error = NULL;
+ d = g_dir_open (CK_SEAT_DIR,
+ 0,
+ &error);
+ if (d == NULL) {
+ g_warning ("Couldn't open seat dir: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ while ((file = g_dir_read_name (d)) != NULL) {
+ char *path;
+ path = g_build_filename (CK_SEAT_DIR, file, NULL);
+ add_seat_for_file (manager, path);
+ g_free (path);
+ }
+
+ g_dir_close (d);
+}
+
+static void
+create_seats (CkManager *manager)
+{
+ load_seats_from_dir (manager);
}
static void
diff --git a/src/ck-seat.c b/src/ck-seat.c
index a77e0b1..fb2d288 100644
--- a/src/ck-seat.c
+++ b/src/ck-seat.c
@@ -53,11 +53,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 +72,8 @@ enum {
ACTIVE_SESSION_CHANGED,
SESSION_ADDED,
SESSION_REMOVED,
+ DEVICE_ADDED,
+ DEVICE_REMOVED,
LAST_SIGNAL
};
@@ -605,6 +609,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 +747,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 +899,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 +948,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 +971,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 +998,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;
+}
diff --git a/src/ck-seat.h b/src/ck-seat.h
index 4707bf9..63ab3d5 100644
--- a/src/ck-seat.h
+++ b/src/ck-seat.h
@@ -47,12 +47,16 @@ typedef struct
{
GObjectClass parent_class;
- void (* active_session_changed) (CkSeat *seat,
- const char *ssid);
- void (* session_added) (CkSeat *seat,
- const char *ssid);
- void (* session_removed) (CkSeat *seat,
- const char *ssid);
+ void (* active_session_changed) (CkSeat *seat,
+ const char *ssid);
+ void (* session_added) (CkSeat *seat,
+ const char *ssid);
+ void (* session_removed) (CkSeat *seat,
+ const char *ssid);
+ void (* device_added) (CkSeat *seat,
+ GValueArray *device);
+ void (* device_removed) (CkSeat *seat,
+ GValueArray *device);
} CkSeatClass;
typedef enum
@@ -71,10 +75,21 @@ typedef enum
#define CK_SEAT_ERROR ck_seat_error_quark ()
+
+#define CK_TYPE_DEVICE (dbus_g_type_get_struct ("GValueArray", \
+ G_TYPE_STRING, \
+ G_TYPE_STRING, \
+ G_TYPE_INVALID))
+
GQuark ck_seat_error_quark (void);
GType ck_seat_get_type (void);
CkSeat * ck_seat_new (const char *sid,
CkSeatKind kind);
+CkSeat * ck_seat_new_from_file (const char *sid,
+ const char *path);
+CkSeat * ck_seat_new_with_devices (const char *sid,
+ CkSeatKind kind,
+ GPtrArray *devices);
gboolean ck_seat_get_kind (CkSeat *seat,
CkSeatKind *kind,
GError **error);
@@ -87,6 +102,12 @@ gboolean ck_seat_remove_session (CkSeat *seat,
gboolean ck_seat_set_active_session (CkSeat *seat,
CkSession *session,
GError **error);
+gboolean ck_seat_add_device (CkSeat *seat,
+ GValueArray *device,
+ GError **error);
+gboolean ck_seat_remove_device (CkSeat *seat,
+ GValueArray *device,
+ GError **error);
/* exported methods */
gboolean ck_seat_get_id (CkSeat *seat,
@@ -95,6 +116,9 @@ gboolean ck_seat_get_id (CkSeat *seat,
gboolean ck_seat_get_sessions (CkSeat *seat,
GPtrArray **sessions,
GError **error);
+gboolean ck_seat_get_devices (CkSeat *seat,
+ GPtrArray **devices,
+ GError **error);
gboolean ck_seat_get_active_session (CkSeat *seat,
char **ssid,
GError **error);
diff --git a/src/ck-seat.xml b/src/ck-seat.xml
index 5fda057..b66fcaa 100644
--- a/src/ck-seat.xml
+++ b/src/ck-seat.xml
@@ -7,6 +7,9 @@
<method name="GetSessions">
<arg name="sessions" direction="out" type="ao"/>
</method>
+ <method name="GetDevices">
+ <arg name="devices" direction="out" type="a(ss)"/>
+ </method>
<method name="GetActiveSession">
<arg name="ssid" direction="out" type="o"/>
</method>
@@ -26,5 +29,11 @@
<signal name="SessionRemoved">
<arg name="ssid" type="o"/>
</signal>
+ <signal name="DeviceAdded">
+ <arg name="device" type="(ss)"/>
+ </signal>
+ <signal name="DeviceRemoved">
+ <arg name="device" type="(ss)"/>
+ </signal>
</interface>
</node>