diff options
-rw-r--r-- | data/00-primary.seat | 5 | ||||
-rw-r--r-- | data/Makefile.am | 4 | ||||
-rw-r--r-- | src/ck-manager.c | 54 | ||||
-rw-r--r-- | src/ck-seat.c | 219 | ||||
-rw-r--r-- | src/ck-seat.h | 36 | ||||
-rw-r--r-- | src/ck-seat.xml | 9 |
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> |