1 diff --git a/configure.ac b/configure.ac
2 index 117d788..2ff6020 100644
5 @@ -203,6 +203,18 @@ AM_CONDITIONAL(CK_COMPILE_SOLARIS, test x$CK_BACKEND = xsolaris, [Compiling for
8 dnl ---------------------------------------------------------------------------
10 +dnl ---------------------------------------------------------------------------
12 +X11_DIR=`$PKG_CONFIG --variable=bindir xorg-server 2>/dev/null`
13 +if test "x$X11_DIR" = x; then
14 + AC_PATH_PROGS([XSERVER], [Xorg X],,[$PATH:/usr/X11/bin:/usr/bin])
15 + test "x$XSERVER" != x && X11_DIR=`dirname "$XSERVER"`
17 +test "x$X11_DIR" = x && X11_DIR=$bindir
20 +dnl ---------------------------------------------------------------------------
22 dnl ---------------------------------------------------------------------------
24 @@ -303,6 +315,14 @@ if test "x$enable_inotify" = "xyes" ; then
27 dnl ---------------------------------------------------------------------------
28 +dnl check for strverscmp
29 +dnl ---------------------------------------------------------------------------
31 +AC_CHECK_FUNCS(strverscmp, [have_strverscmp=yes], [])
33 +AM_CONDITIONAL(USE_SELF_STRVERSCMP, test "x$have_strverscmp" = "xno", [Define if we do not have strverscmp])
35 +dnl ---------------------------------------------------------------------------
37 dnl ---------------------------------------------------------------------------
39 @@ -401,6 +421,8 @@ tools/linux/Makefile
40 tools/freebsd/Makefile
41 tools/solaris/Makefile
43 +data/displays.d/Makefile
44 +data/sessions.d/Makefile
46 doc/dbus/ConsoleKit.xml
48 diff --git a/data/00-primary.seat b/data/00-primary.seat
49 index 6e61db4..0632382 100644
50 --- a/data/00-primary.seat
51 +++ b/data/00-primary.seat
56 +# Specified Seat ID, if this value is NULL, ConsoleKit will decide one.
57 +# The ID only contain the ASICC characters "[A-Z][a-z][0-9]_"
59 +Description=start one static local display at :0
61 +# Indicate whether to create this seat or not. If it is set true, then CK will
62 +# not create this seat. Default value is false.
65 \ No newline at end of file
67 +# Indicate input/output devices including keyboard-pointer-video
68 +# card-monitor-sound-usb devices,
69 +# This key will not implemented now, it might need be divided into
70 +# several keys in the future:
78 +# List of sessions to start on the seat, separated by ';'
79 +# Each session is defined in sessions.d/
81 diff --git a/data/ConsoleKit.conf b/data/ConsoleKit.conf
82 index 948f95f..8cf490a 100644
83 --- a/data/ConsoleKit.conf
84 +++ b/data/ConsoleKit.conf
86 send_member="CloseSession"/>
87 <allow send_destination="org.freedesktop.ConsoleKit"
88 send_interface="org.freedesktop.ConsoleKit.Manager"
89 + send_member="GetUnmanagedSeats"/>
90 + <allow send_destination="org.freedesktop.ConsoleKit"
91 + send_interface="org.freedesktop.ConsoleKit.Manager"
92 send_member="GetSeats"/>
93 <allow send_destination="org.freedesktop.ConsoleKit"
94 send_interface="org.freedesktop.ConsoleKit.Manager"
96 <allow send_destination="org.freedesktop.ConsoleKit"
97 send_interface="org.freedesktop.ConsoleKit.Manager"
98 send_member="GetSystemIdleSinceHint"/>
99 + <allow send_destination="org.freedesktop.ConsoleKit"
100 + send_interface="org.freedesktop.ConsoleKit.Manager"
101 + send_member="AddSeat"/>
102 + <allow send_destination="org.freedesktop.ConsoleKit"
103 + send_interface="org.freedesktop.ConsoleKit.Manager"
104 + send_member="RemoveSeat"/>
105 + <allow send_destination="org.freedesktop.ConsoleKit"
106 + send_interface="org.freedesktop.ConsoleKit.Manager"
107 + send_member="AddSession"/>
108 + <allow send_destination="org.freedesktop.ConsoleKit"
109 + send_interface="org.freedesktop.ConsoleKit.Manager"
110 + send_member="RemoveSession"/>
112 <allow send_destination="org.freedesktop.ConsoleKit"
113 send_interface="org.freedesktop.ConsoleKit.Seat"
115 <allow send_destination="org.freedesktop.ConsoleKit"
116 send_interface="org.freedesktop.ConsoleKit.Seat"
117 send_member="ActivateSession"/>
118 + <allow send_destination="org.freedesktop.ConsoleKit"
119 + send_interface="org.freedesktop.ConsoleKit.Seat"
120 + send_member="ManageSeat"/>
122 <allow send_destination="org.freedesktop.ConsoleKit"
123 send_interface="org.freedesktop.ConsoleKit.Session"
125 send_member="GetSessionType"/>
126 <allow send_destination="org.freedesktop.ConsoleKit"
127 send_interface="org.freedesktop.ConsoleKit.Session"
128 + send_member="GetDisplayType"/>
129 + <allow send_destination="org.freedesktop.ConsoleKit"
130 + send_interface="org.freedesktop.ConsoleKit.Session"
131 send_member="GetUser"/>
132 <allow send_destination="org.freedesktop.ConsoleKit"
133 send_interface="org.freedesktop.ConsoleKit.Session"
135 send_member="IsLocal"/>
136 <allow send_destination="org.freedesktop.ConsoleKit"
137 send_interface="org.freedesktop.ConsoleKit.Session"
138 + send_member="IsDynamic"/>
139 + <allow send_destination="org.freedesktop.ConsoleKit"
140 + send_interface="org.freedesktop.ConsoleKit.Session"
141 + send_member="IsOpen"/>
142 + <allow send_destination="org.freedesktop.ConsoleKit"
143 + send_interface="org.freedesktop.ConsoleKit.Session"
144 send_member="GetCreationTime"/>
145 <allow send_destination="org.freedesktop.ConsoleKit"
146 send_interface="org.freedesktop.ConsoleKit.Session"
147 @@ -136,12 +163,11 @@
148 send_member="GetIdleHint"/>
149 <allow send_destination="org.freedesktop.ConsoleKit"
150 send_interface="org.freedesktop.ConsoleKit.Session"
151 - send_member="SetIdleHint"/>
152 - <allow send_destination="org.freedesktop.ConsoleKit"
153 - send_interface="org.freedesktop.ConsoleKit.Session"
154 send_member="GetIdleSinceHint"/>
155 <allow send_interface="org.freedesktop.ConsoleKit.Session"
156 send_member="SetIdleHint"/>
157 + <allow send_interface="org.freedesktop.ConsoleKit.Session"
158 + send_member="SetRemoveOnClose"/>
162 diff --git a/data/Makefile.am b/data/Makefile.am
163 index 041b431..2054e96 100644
164 --- a/data/Makefile.am
165 +++ b/data/Makefile.am
174 dbusconfdir = $(DBUS_SYS_DIR)
175 dbusconf_DATA = ConsoleKit.conf
177 diff --git a/data/displays.d/Headless.display.in b/data/displays.d/Headless.display.in
179 index 0000000..754d2bf
181 +++ b/data/displays.d/Headless.display.in
187 +Exec=@X11_DIR@/Xvfb $display -auth $auth
188 diff --git a/data/displays.d/Local.display.in b/data/displays.d/Local.display.in
190 index 0000000..b845a7b
192 +++ b/data/displays.d/Local.display.in
198 +Exec=@X11_DIR@/Xorg $display -br -verbose -auth $auth -nolisten tcp $vt
199 diff --git a/data/displays.d/LocalVNC.display.in b/data/displays.d/LocalVNC.display.in
201 index 0000000..6ad336b
203 +++ b/data/displays.d/LocalVNC.display.in
209 +Exec=@X11_DIR@/Xvnc $display -auth $auth -query localhost
210 diff --git a/data/displays.d/Makefile.am b/data/displays.d/Makefile.am
212 index 0000000..1fab1d2
214 +++ b/data/displays.d/Makefile.am
218 +displaydir = $(sysconfdir)/ConsoleKit/displays.d
219 +display_in_files = \
221 + RemoteMachine.display.in \
222 + LocalVNC.display.in \
223 + Headless.display.in
225 +display_DATA = $(display_in_files:.display.in=.display)
227 +Local.display: Local.display.in Makefile
228 + sed -e "s|\@X11_DIR\@|$(X11_DIR)|" $< > $@
229 +RemoteMachine.display: RemoteMachine.display.in Makefile
230 + sed -e "s|\@X11_DIR\@|$(X11_DIR)|" $< > $@
231 +LocalVNC.display: LocalVNC.display.in Makefile
232 + sed -e "s|\@X11_DIR\@|$(X11_DIR)|" $< > $@
233 +Headless.display: Headless.display.in Makefile
234 + sed -e "s|\@X11_DIR\@|$(X11_DIR)|" $< > $@
237 + $(display_in_files) \
240 +MAINTAINERCLEANFILES = \
244 +CLEANFILES = $(display_DATA)
245 diff --git a/data/displays.d/RemoteMachine.display.in b/data/displays.d/RemoteMachine.display.in
247 index 0000000..7c69451
249 +++ b/data/displays.d/RemoteMachine.display.in
255 +Exec=@X11_DIR@/Xorg $display -br -verbose -auth $auth -indirect $vt
256 diff --git a/data/sessions.d/Headless.session b/data/sessions.d/Headless.session
258 index 0000000..d376af9
260 +++ b/data/sessions.d/Headless.session
265 +Description=Login Window running on headless display
266 +DisplayTemplate=Headless
270 diff --git a/data/sessions.d/Local.session b/data/sessions.d/Local.session
272 index 0000000..9d3b975
274 +++ b/data/sessions.d/Local.session
279 +Description=Local Login Screen
280 +DisplayTemplate=Local
285 diff --git a/data/sessions.d/LocalVNC.session b/data/sessions.d/LocalVNC.session
287 index 0000000..c05802f
289 +++ b/data/sessions.d/LocalVNC.session
294 +Description=Connect to local VNC server running on same machine
295 +DisplayTemplate=LocalVNC
299 diff --git a/data/sessions.d/Makefile.am b/data/sessions.d/Makefile.am
301 index 0000000..f17ffdc
303 +++ b/data/sessions.d/Makefile.am
307 +sessiondir = $(sysconfdir)/ConsoleKit/sessions.d
318 +MAINTAINERCLEANFILES = \
321 diff --git a/data/sessions.d/Remote.session b/data/sessions.d/Remote.session
323 index 0000000..e88f975
325 +++ b/data/sessions.d/Remote.session
330 +Description=Connect to chooser on nearby remote machine
331 +DisplayTemplate=RemoteMachine
336 diff --git a/doc/dbus/ck-terms.xml b/doc/dbus/ck-terms.xml
337 index d3d544d..1b43ca6 100644
338 --- a/doc/dbus/ck-terms.xml
339 +++ b/doc/dbus/ck-terms.xml
340 @@ -64,4 +64,11 @@ True, hardware, multi-seat capabilities will be added in a later release.
345 + <title>Seat manager</title>
347 +The seat manager is the process responsible for starting and stopping sessions on a seat.
352 diff --git a/libck-connector/ck-connector.c b/libck-connector/ck-connector.c
353 index 7f6f87f..87a7d4a 100644
354 --- a/libck-connector/ck-connector.c
355 +++ b/libck-connector/ck-connector.c
356 @@ -76,8 +76,11 @@ static struct {
357 { "display-device", DBUS_TYPE_STRING },
358 { "x11-display-device", DBUS_TYPE_STRING },
359 { "x11-display", DBUS_TYPE_STRING },
360 + { "seat-id", DBUS_TYPE_STRING },
361 + { "session", DBUS_TYPE_STRING },
362 { "remote-host-name", DBUS_TYPE_STRING },
363 { "session-type", DBUS_TYPE_STRING },
364 + { "display-type", DBUS_TYPE_STRING },
365 { "is-local", DBUS_TYPE_BOOLEAN },
366 { "unix-user", DBUS_TYPE_INT32 },
368 diff --git a/src/Makefile.am b/src/Makefile.am
369 index 6ab05c8..97a59ef 100644
370 --- a/src/Makefile.am
371 +++ b/src/Makefile.am
372 @@ -107,6 +107,8 @@ console_kit_daemon_SOURCES = \
376 + ck-display-template.h \
377 + ck-display-template.c \
380 ck-session-leader.h \
381 @@ -122,6 +124,13 @@ console_kit_daemon_SOURCES = \
385 +if USE_SELF_STRVERSCMP
386 +console_kit_daemon_SOURCES += \
393 FILE_MONITOR_BACKEND = ck-file-monitor-inotify.c
395 diff --git a/src/ck-display-template.c b/src/ck-display-template.c
397 index 0000000..9206103
399 +++ b/src/ck-display-template.c
401 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
403 + * Authors: halton.huo@sun.com, Ray Strode <rstrode@redhat.com>
404 + * Copyright (C) 2009 Sun Microsystems, Inc.
407 + * This program is free software; you can redistribute it and/or modify
408 + * it under the terms of the GNU General Public License as published by
409 + * the Free Software Foundation; either version 2 of the License, or
410 + * (at your option) any later version.
412 + * This program is distributed in the hope that it will be useful,
413 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
414 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
415 + * GNU General Public License for more details.
417 + * You should have received a copy of the GNU General Public License
418 + * along with this program; if not, write to the Free Software
419 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
427 +#include <glib-object.h>
429 +#include "ck-display-template.h"
431 +#define CK_DISPLAY_TEMPLATE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CK_TYPE_DISPLAY_TEMPLATE, CkDisplayTemplatePrivate))
433 +#define CK_DISPLAY_TEMPLATES_DIR SYSCONFDIR "/ConsoleKit/displays.d"
435 +struct CkDisplayTemplatePrivate
439 + GHashTable *parameters;
449 +static void ck_display_template_class_init (CkDisplayTemplateClass *klass);
450 +static void ck_display_template_init (CkDisplayTemplate *display);
451 +static void ck_display_template_finalize (GObject *object);
452 +static gboolean ck_display_template_load (CkDisplayTemplate *display);
454 +static GHashTable *ck_display_templates;
456 +G_DEFINE_TYPE (CkDisplayTemplate, ck_display_template, G_TYPE_OBJECT)
459 +_ck_display_template_set_name (CkDisplayTemplate *display,
462 + g_free (display->priv->name);
463 + display->priv->name = g_strdup (name);
467 +_ck_display_template_set_type_string (CkDisplayTemplate *display,
470 + g_free (display->priv->type);
471 + display->priv->type = g_strdup (type);
475 +_ck_display_template_set_parameters (CkDisplayTemplate *display,
476 + GHashTable *parameters)
478 + if (display->priv->parameters != NULL) {
479 + g_hash_table_unref (display->priv->parameters);
482 + if (parameters == NULL) {
483 + display->priv->parameters = g_hash_table_new_full (g_str_hash, g_str_equal,
484 + (GDestroyNotify) g_free,
485 + (GDestroyNotify) g_free);
487 + display->priv->parameters = g_hash_table_ref (parameters);
492 +ck_display_template_set_property (GObject *object,
494 + const GValue *value,
497 + CkDisplayTemplate *self;
499 + self = CK_DISPLAY_TEMPLATE (object);
503 + _ck_display_template_set_name (self, g_value_get_string (value));
506 + _ck_display_template_set_type_string (self, g_value_get_string (value));
508 + case PROP_PARAMETERS:
509 + _ck_display_template_set_parameters (self, g_value_get_boxed (value));
512 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
518 +ck_display_template_get_property (GObject *object,
523 + CkDisplayTemplate *self;
525 + self = CK_DISPLAY_TEMPLATE (object);
529 + g_value_set_string (value, self->priv->name);
532 + g_value_set_string (value, self->priv->type);
534 + case PROP_PARAMETERS:
535 + g_value_set_boxed (value, self->priv->parameters);
538 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
544 +ck_display_template_class_init (CkDisplayTemplateClass *klass)
546 + GObjectClass *object_class = G_OBJECT_CLASS (klass);
548 + object_class->get_property = ck_display_template_get_property;
549 + object_class->set_property = ck_display_template_set_property;
550 + object_class->finalize = ck_display_template_finalize;
552 + g_object_class_install_property (object_class,
554 + g_param_spec_string ("name",
555 + "display type name",
556 + "display type name",
558 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
559 + g_object_class_install_property (object_class,
561 + g_param_spec_string ("type",
565 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
566 + g_object_class_install_property (object_class,
568 + g_param_spec_boxed ("parameters",
572 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
573 + g_type_class_add_private (klass, sizeof (CkDisplayTemplatePrivate));
577 +ck_display_template_init (CkDisplayTemplate *display)
579 + display->priv = CK_DISPLAY_TEMPLATE_GET_PRIVATE (display);
581 + display->priv->name = NULL;
582 + display->priv->type = NULL;
583 + display->priv->parameters = g_hash_table_new_full (g_str_hash, g_str_equal,
584 + (GDestroyNotify) g_free,
585 + (GDestroyNotify) g_free);
589 +ck_display_template_finalize (GObject *object)
591 + CkDisplayTemplate *display;
593 + g_return_if_fail (object != NULL);
594 + g_return_if_fail (CK_IS_DISPLAY_TEMPLATE (object));
596 + display = CK_DISPLAY_TEMPLATE (object);
598 + g_return_if_fail (display->priv != NULL);
600 + g_free (display->priv->name);
601 + g_free (display->priv->type);
602 + g_hash_table_unref (display->priv->parameters);
604 + G_OBJECT_CLASS (ck_display_template_parent_class)->finalize (object);
608 +ck_display_template_load (CkDisplayTemplate *display)
610 + GKeyFile *key_file;
619 + GHashTable *parameters;
621 + name = ck_display_template_get_name (display);
623 + g_return_val_if_fail (name && !g_str_equal (name, ""), FALSE);
625 + filename = g_strdup_printf ("%s/%s.display", CK_DISPLAY_TEMPLATES_DIR, name);
627 + key_file = g_key_file_new ();
630 + res = g_key_file_load_from_file (key_file,
635 + g_warning ("Unable to load display from file %s: %s", filename, error->message);
636 + g_error_free (error);
641 + group = g_key_file_get_start_group (key_file);
643 + if (group == NULL || strcmp (group, "Display") != 0) {
644 + g_warning ("Not a display type file: %s", filename);
646 + g_key_file_free (key_file);
650 + hidden = g_key_file_get_boolean (key_file, group, "Hidden", NULL);
652 + type = g_key_file_get_string (key_file, group, "Type", NULL);
654 + if (type == NULL) {
655 + g_warning ("Unable to read type from display file");
657 + g_key_file_free (key_file);
661 + display->priv->type = type;
663 + parameters = g_hash_table_new_full (g_str_hash, g_str_equal,
664 + (GDestroyNotify) g_free,
665 + (GDestroyNotify) g_free);
667 + type_keys = g_key_file_get_keys (key_file, type, NULL, NULL);
669 + if (type_keys != NULL) {
671 + for (i = 0; type_keys[i] != NULL; i++) {
674 + string = g_key_file_get_string (key_file, type, type_keys[i], NULL);
675 + g_hash_table_insert (parameters, g_strdup (type_keys[i]), string);
677 + g_strfreev (type_keys);
680 + _ck_display_template_set_parameters (display, parameters);
681 + g_hash_table_unref (parameters);
684 + g_key_file_free (key_file);
689 +ck_display_template_get_from_name (const char *name)
691 + CkDisplayTemplate *display_template;
693 + if (ck_display_templates == NULL) {
694 + ck_display_templates = g_hash_table_new_full (g_str_hash, g_str_equal,
695 + (GDestroyNotify) g_free,
696 + (GDestroyNotify) g_object_unref);
699 + display_template = g_hash_table_lookup (ck_display_templates, name);
701 + if (display_template == NULL) {
704 + object = g_object_new (CK_TYPE_DISPLAY_TEMPLATE,
708 + if (!ck_display_template_load (CK_DISPLAY_TEMPLATE (object))) {
709 + g_object_unref (object);
713 + g_hash_table_insert (ck_display_templates, g_strdup (name), object);
714 + display_template = CK_DISPLAY_TEMPLATE (object);
717 + return g_object_ref (display_template);
720 +G_CONST_RETURN char*
721 +ck_display_template_get_name (CkDisplayTemplate *display)
723 + g_return_val_if_fail (CK_IS_DISPLAY_TEMPLATE (display), NULL);
725 + return display->priv->name;
728 +G_CONST_RETURN char *
729 +ck_display_template_get_type_string (CkDisplayTemplate *display)
731 + return display->priv->type;
735 +ck_display_template_get_parameters (CkDisplayTemplate *display)
737 + g_return_val_if_fail (CK_IS_DISPLAY_TEMPLATE (display), NULL);
739 + return g_hash_table_ref (display->priv->parameters);
742 diff --git a/src/ck-display-template.h b/src/ck-display-template.h
744 index 0000000..fa74e67
746 +++ b/src/ck-display-template.h
748 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
750 + * Authors: halton.huo@sun.com
751 + * Copyright (C) 2009 Sun Microsystems, Inc.
753 + * This program is free software; you can redistribute it and/or modify
754 + * it under the terms of the GNU General Public License as published by
755 + * the Free Software Foundation; either version 2 of the License, or
756 + * (at your option) any later version.
758 + * This program is distributed in the hope that it will be useful,
759 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
760 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
761 + * GNU General Public License for more details.
763 + * You should have received a copy of the GNU General Public License
764 + * along with this program; if not, write to the Free Software
765 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
769 +#ifndef __CK_DISPLAY_TEMPLATE_H
770 +#define __CK_DISPLAY_TEMPLATE_H
772 +#include <glib-object.h>
776 +#define CK_TYPE_DISPLAY_TEMPLATE (ck_display_template_get_type ())
777 +#define CK_DISPLAY_TEMPLATE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CK_TYPE_DISPLAY_TEMPLATE, CkDisplayTemplate))
778 +#define CK_DISPLAY_TEMPLATE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CK_TYPE_DISPLAY_TEMPLATE, CkDisplayTemplateClass))
779 +#define CK_IS_DISPLAY_TEMPLATE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CK_TYPE_DISPLAY_TEMPLATE))
780 +#define CK_IS_DISPLAY_TEMPLATE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CK_TYPE_DISPLAY_TEMPLATE))
781 +#define CK_DISPLAY_TEMPLATE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CK_TYPE_DISPLAY_TEMPLATE, CkDisplayTemplateClass))
783 +typedef struct CkDisplayTemplatePrivate CkDisplayTemplatePrivate;
788 + CkDisplayTemplatePrivate *priv;
789 +} CkDisplayTemplate;
793 + GObjectClass parent_class;
794 +} CkDisplayTemplateClass;
796 +GType ck_display_template_get_type (void);
797 +CkDisplayTemplate * ck_display_template_get_from_name (const char *name);
798 +G_CONST_RETURN char * ck_display_template_get_name (CkDisplayTemplate *display);
799 +G_CONST_RETURN char * ck_display_template_get_type_string (CkDisplayTemplate *display);
800 +GHashTable * ck_display_template_get_parameters (CkDisplayTemplate *display);
804 +#endif /* __CK_DISPLAY_TEMPLATE_H */
805 diff --git a/src/ck-log-event.c b/src/ck-log-event.c
806 index 66f439c..d13a0f8 100644
807 --- a/src/ck-log-event.c
808 +++ b/src/ck-log-event.c
809 @@ -79,6 +79,8 @@ event_seat_session_added_free (CkLogSeat
810 event->session_id = NULL;
811 g_free (event->session_type);
812 event->session_type = NULL;
813 + g_free (event->display_type);
814 + event->display_type = NULL;
815 g_free (event->session_x11_display);
816 event->session_x11_display = NULL;
817 g_free (event->session_x11_display_device);
818 @@ -103,6 +105,8 @@ event_seat_session_removed_free (CkLogSe
819 event->session_id = NULL;
820 g_free (event->session_type);
821 event->session_type = NULL;
822 + g_free (event->display_type);
823 + event->display_type = NULL;
824 g_free (event->session_x11_display);
825 event->session_x11_display = NULL;
826 g_free (event->session_x11_display_device);
827 @@ -213,6 +217,7 @@ event_seat_session_added_copy (CkLogSeat
828 event_copy->seat_id = g_strdup (event->seat_id);
829 event_copy->session_id = g_strdup (event->session_id);
830 event_copy->session_type = g_strdup (event->session_type);
831 + event_copy->display_type = g_strdup (event->display_type);
832 event_copy->session_x11_display = g_strdup (event->session_x11_display);
833 event_copy->session_x11_display_device = g_strdup (event->session_x11_display_device);
834 event_copy->session_display_device = g_strdup (event->session_display_device);
835 @@ -232,6 +237,7 @@ event_seat_session_removed_copy (CkLogSe
836 event_copy->seat_id = g_strdup (event->seat_id);
837 event_copy->session_id = g_strdup (event->session_id);
838 event_copy->session_type = g_strdup (event->session_type);
839 + event_copy->display_type = g_strdup (event->display_type);
840 event_copy->session_x11_display = g_strdup (event->session_x11_display);
841 event_copy->session_x11_display_device = g_strdup (event->session_x11_display_device);
842 event_copy->session_display_device = g_strdup (event->session_display_device);
843 @@ -415,10 +421,11 @@ add_log_for_seat_session_added (GString
845 e = (CkLogSeatSessionAddedEvent *)event;
846 g_string_append_printf (str,
847 - "seat-id='%s' session-id='%s' session-type='%s' session-x11-display='%s' session-x11-display-device='%s' session-display-device='%s' session-remote-host-name='%s' session-is-local=%s session-unix-user=%u session-creation-time='%s'",
848 + "seat-id='%s' session-id='%s' session-type='%s' display-type='%s' session-x11-display='%s' session-x11-display-device='%s' session-display-device='%s' session-remote-host-name='%s' session-is-local=%s session-unix-user=%u session-creation-time='%s'",
849 e->seat_id ? e->seat_id : "",
850 e->session_id ? e->session_id : "",
851 e->session_type ? e->session_type : "",
852 + e->display_type ? e->display_type : "",
853 e->session_x11_display ? e->session_x11_display : "",
854 e->session_x11_display_device ? e->session_x11_display_device : "",
855 e->session_display_device ? e->session_display_device : "",
856 @@ -436,10 +443,11 @@ add_log_for_seat_session_removed (GStrin
858 e = (CkLogSeatSessionRemovedEvent *)event;
859 g_string_append_printf (str,
860 - "seat-id='%s' session-id='%s' session-type='%s' session-x11-display='%s' session-x11-display-device='%s' session-display-device='%s' session-remote-host-name='%s' session-is-local=%s session-unix-user=%u session-creation-time='%s'",
861 + "seat-id='%s' session-id='%s' session-type='%s' display-type='%s' session-x11-display='%s' session-x11-display-device='%s' session-display-device='%s' session-remote-host-name='%s' session-is-local=%s session-unix-user=%u session-creation-time='%s'",
862 e->seat_id ? e->seat_id : "",
863 e->session_id ? e->session_id : "",
864 e->session_type ? e->session_type : "",
865 + e->display_type ? e->display_type : "",
866 e->session_x11_display ? e->session_x11_display : "",
867 e->session_x11_display_device ? e->session_x11_display_device : "",
868 e->session_display_device ? e->session_display_device : "",
869 @@ -939,7 +947,7 @@ parse_log_for_seat_session_added (const
873 - re = g_regex_new ("seat-id='(?P<seatid>[a-zA-Z0-9/]+)' session-id='(?P<sessionid>[a-zA-Z0-9/]+)' session-type='(?P<sessiontype>[a-zA-Z0-9 ]*)' session-x11-display='(?P<sessionx11display>[0-9a-zA-Z.:]*)' session-x11-display-device='(?P<sessionx11displaydevice>[^']*)' session-display-device='(?P<sessiondisplaydevice>[^']*)' session-remote-host-name='(?P<sessionremovehostname>[^']*)' session-is-local=(?P<sessionislocal>[a-zA-Z]*) session-unix-user=(?P<sessionunixuser>[0-9]*) session-creation-time='(?P<sessioncreationtime>[^']*)'", 0, 0, &error);
874 + re = g_regex_new ("seat-id='(?P<seatid>[a-zA-Z0-9/]+)' session-id='(?P<sessionid>[a-zA-Z0-9/]+)' session-type='(?P<sessiontype>[a-zA-Z0-9 ]*)' display-type='(?P<displaytype>[a-zA-Z0-9 ]*)' session-x11-display='(?P<sessionx11display>[0-9a-zA-Z.:]*)' session-x11-display-device='(?P<sessionx11displaydevice>[^']*)' session-display-device='(?P<sessiondisplaydevice>[^']*)' session-remote-host-name='(?P<sessionremovehostname>[^']*)' session-is-local=(?P<sessionislocal>[a-zA-Z]*) session-unix-user=(?P<sessionunixuser>[0-9]*) session-creation-time='(?P<sessioncreationtime>[^']*)'", 0, 0, &error);
876 g_warning ("%s", error->message);
878 @@ -957,6 +965,7 @@ parse_log_for_seat_session_added (const
879 e->seat_id = g_match_info_fetch_named (match_info, "seatid");
880 e->session_id = g_match_info_fetch_named (match_info, "sessionid");
881 e->session_type = g_match_info_fetch_named (match_info, "sessiontype");
882 + e->display_type = g_match_info_fetch_named (match_info, "displaytype");
883 e->session_x11_display = g_match_info_fetch_named (match_info, "sessionx11display");
884 e->session_x11_display_device = g_match_info_fetch_named (match_info, "sessionx11displaydevice");
885 e->session_display_device = g_match_info_fetch_named (match_info, "sessiondisplaydevice");
886 @@ -1014,7 +1023,7 @@ parse_log_for_seat_session_removed (cons
890 - re = g_regex_new ("seat-id='(?P<seatid>[a-zA-Z0-9/]+)' session-id='(?P<sessionid>[a-zA-Z0-9/]+)' session-type='(?P<sessiontype>[a-zA-Z0-9 ]*)' session-x11-display='(?P<sessionx11display>[0-9a-zA-Z.:]*)' session-x11-display-device='(?P<sessionx11displaydevice>[^']*)' session-display-device='(?P<sessiondisplaydevice>[^']*)' session-remote-host-name='(?P<sessionremovehostname>[^']*)' session-is-local=(?P<sessionislocal>[a-zA-Z]*) session-unix-user=(?P<sessionunixuser>[0-9]*) session-creation-time='(?P<sessioncreationtime>[^']*)'", 0, 0, &error);
891 + re = g_regex_new ("seat-id='(?P<seatid>[a-zA-Z0-9/]+)' session-id='(?P<sessionid>[a-zA-Z0-9/]+)' session-type='(?P<sessiontype>[a-zA-Z0-9 ]*)' display-type='(?P<displaytype>[a-zA-Z0-9 ]*)' session-x11-display='(?P<sessionx11display>[0-9a-zA-Z.:]*)' session-x11-display-device='(?P<sessionx11displaydevice>[^']*)' session-display-device='(?P<sessiondisplaydevice>[^']*)' session-remote-host-name='(?P<sessionremovehostname>[^']*)' session-is-local=(?P<sessionislocal>[a-zA-Z]*) session-unix-user=(?P<sessionunixuser>[0-9]*) session-creation-time='(?P<sessioncreationtime>[^']*)'", 0, 0, &error);
893 g_warning ("%s", error->message);
895 @@ -1032,6 +1041,7 @@ parse_log_for_seat_session_removed (cons
896 e->seat_id = g_match_info_fetch_named (match_info, "seatid");
897 e->session_id = g_match_info_fetch_named (match_info, "sessionid");
898 e->session_type = g_match_info_fetch_named (match_info, "sessiontype");
899 + e->display_type = g_match_info_fetch_named (match_info, "displaytype");
900 e->session_x11_display = g_match_info_fetch_named (match_info, "sessionx11display");
901 e->session_x11_display_device = g_match_info_fetch_named (match_info, "sessionx11displaydevice");
902 e->session_display_device = g_match_info_fetch_named (match_info, "sessiondisplaydevice");
903 diff --git a/src/ck-log-event.h b/src/ck-log-event.h
904 index 65571f0..2d4ed4e 100644
905 --- a/src/ck-log-event.h
906 +++ b/src/ck-log-event.h
907 @@ -68,6 +68,7 @@ typedef struct
912 } CkLogSeatAddedEvent;
915 @@ -81,11 +82,13 @@ typedef struct
919 + char *display_type;
920 char *session_x11_display;
921 char *session_x11_display_device;
922 char *session_display_device;
923 char *session_remote_host_name;
924 gboolean session_is_local;
925 + gboolean session_is_dynamic;
926 guint session_unix_user;
927 char *session_creation_time;
928 } CkLogSeatSessionAddedEvent;
929 @@ -95,11 +98,13 @@ typedef struct
933 + char *display_type;
934 char *session_x11_display;
935 char *session_x11_display_device;
936 char *session_display_device;
937 char *session_remote_host_name;
938 gboolean session_is_local;
939 + gboolean session_is_dynamic;
940 guint session_unix_user;
941 char *session_creation_time;
942 } CkLogSeatSessionRemovedEvent;
943 --- ConsoleKit-0.4.1/src/ck-manager.c.1 2010-09-06 17:41:32.942210394 +0800
944 +++ ConsoleKit-0.4.1/src/ck-manager.c 2010-09-06 17:41:56.671280731 +0800
949 +#ifndef HAVE_STRVERSCMP
950 +#include "strverscmp.h"
953 #include "ck-manager.h"
954 #include "ck-manager-glue.h"
956 +#include "ck-display-template.h"
957 #include "ck-session-leader.h"
958 #include "ck-session.h"
959 #include "ck-marshal.h"
962 #define CK_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CK_TYPE_MANAGER, CkManagerPrivate))
964 +#define CK_TYPE_PARAMETER_STRUCT (dbus_g_type_get_struct ("GValueArray", \
969 #define CK_SEAT_DIR SYSCONFDIR "/ConsoleKit/seats.d"
970 #define LOG_FILE LOCALSTATEDIR "/log/ConsoleKit/history"
971 #define CK_DBUS_PATH "/org/freedesktop/ConsoleKit"
972 #define CK_MANAGER_DBUS_PATH CK_DBUS_PATH "/Manager"
973 #define CK_MANAGER_DBUS_NAME "org.freedesktop.ConsoleKit.Manager"
975 +#define IS_STR_SET(x) (x != NULL && x[0] != '\0')
977 struct CkManagerPrivate
980 @@ -391,6 +403,7 @@ log_seat_added_event (CkManager *manage
983 CkSeatKind seat_kind;
986 memset (&event, 0, sizeof (CkLogEvent));
988 @@ -400,9 +413,11 @@ log_seat_added_event (CkManager *manage
990 ck_seat_get_id (seat, &sid, NULL);
991 ck_seat_get_kind (seat, &seat_kind, NULL);
992 + ck_seat_get_type_string (seat, &seat_type, NULL);
994 event.event.seat_added.seat_id = (char *)get_object_id_basename (sid);
995 event.event.seat_added.seat_kind = (int)seat_kind;
996 + event.event.seat_added.seat_type = (char *)seat_type;
999 res = ck_event_logger_queue_event (manager->priv->logger, &event, &error);
1000 @@ -412,6 +427,7 @@ log_seat_added_event (CkManager *manage
1004 + g_free (seat_type);
1008 @@ -516,6 +532,7 @@ log_seat_session_added_event (CkManager
1009 if (session != NULL) {
1010 g_object_get (session,
1011 "session-type", &event.event.seat_session_added.session_type,
1012 + "display-type", &event.event.seat_session_added.display_type,
1013 "x11-display", &event.event.seat_session_added.session_x11_display,
1014 "x11-display-device", &event.event.seat_session_added.session_x11_display_device,
1015 "display-device", &event.event.seat_session_added.session_display_device,
1016 @@ -571,6 +588,7 @@ log_seat_session_removed_event (CkManage
1017 if (session != NULL) {
1018 g_object_get (session,
1019 "session-type", &event.event.seat_session_removed.session_type,
1020 + "display-type", &event.event.seat_session_removed.display_type,
1021 "x11-display", &event.event.seat_session_removed.session_x11_display,
1022 "x11-display-device", &event.event.seat_session_removed.session_x11_display_device,
1023 "display-device", &event.event.seat_session_removed.session_display_device,
1024 @@ -844,6 +862,8 @@ ready_cb (PolkitAuthority *authority,
1025 PolkitAuthorizationResult *ret;
1028 + g_debug ("CkManager: Ready.");
1031 ret = polkit_authority_check_authorization_finish (authority, res, &error);
1032 if (error != NULL) {
1033 @@ -974,6 +994,7 @@ session_is_real_user (CkSession *session
1035 /* filter out GDM user */
1036 if (username != NULL && strcmp (username, "gdm") == 0) {
1037 + g_debug ("CkManager: Session is not real user");
1041 @@ -982,6 +1003,7 @@ session_is_real_user (CkSession *session
1042 *userp = g_strdup (username);
1045 + g_debug ("CkManager: Session is real user");
1049 @@ -1242,6 +1264,7 @@ on_seat_active_session_changed_full (CkS
1053 + g_debug ("CkManager: Active session changed.");
1054 if (session != NULL) {
1055 ck_session_get_id (session, &ssid, NULL);
1057 @@ -1261,6 +1284,7 @@ on_seat_session_added_full (CkSeat *
1061 + g_debug ("CkManager: Session added.");
1062 ck_session_get_id (session, &ssid, NULL);
1064 ck_manager_dump (manager);
1065 @@ -1278,6 +1302,7 @@ on_seat_session_removed_full (CkSeat
1069 + g_debug ("CkManager: Seat Session removed.");
1070 ck_session_get_id (session, &ssid, NULL);
1072 ck_manager_dump (manager);
1073 @@ -1293,6 +1318,7 @@ on_seat_device_added (CkSeat *seat,
1074 GValueArray *device,
1077 + g_debug ("CkManager: Seat device added.");
1078 ck_manager_dump (manager);
1079 log_seat_device_added_event (manager, seat, device);
1081 @@ -1302,6 +1328,7 @@ on_seat_device_removed (CkSeat *sea
1082 GValueArray *device,
1085 + g_debug ("CkManager: Seat device removed.");
1086 ck_manager_dump (manager);
1087 log_seat_device_removed_event (manager, seat, device);
1089 @@ -1329,15 +1356,23 @@ disconnect_seat_signals (CkManager *mana
1093 -add_new_seat (CkManager *manager,
1095 +add_new_seat (CkManager *manager,
1096 + const char *give_sid,
1103 - sid = generate_seat_id (manager);
1104 + if (IS_STR_SET (give_sid)) {
1105 + sid = g_strdup (give_sid);
1107 + sid = generate_seat_id (manager);
1110 + g_debug ("CkManager: Add new seat '%s'.", sid);
1112 - seat = ck_seat_new (sid, kind);
1113 + seat = ck_seat_new (sid, kind, type);
1115 /* First we connect our own signals to the seat, followed by
1116 * the D-Bus signal hookup to make sure we can first dump the
1117 @@ -1362,7 +1397,7 @@ add_new_seat (CkManager *manager,
1118 ck_seat_run_programs (seat, NULL, NULL, "seat_added");
1120 g_debug ("Emitting seat-added: %s", sid);
1121 - g_signal_emit (manager, signals [SEAT_ADDED], 0, sid);
1122 + g_signal_emit (manager, signals [SEAT_ADDED], 0, sid, type);
1124 log_seat_added_event (manager, seat);
1126 @@ -1381,6 +1416,8 @@ remove_seat (CkManager *manager,
1128 ck_seat_get_id (seat, &sid, NULL);
1130 + g_debug ("CkManager: Remove seat '%s'", sid);
1132 /* Need to get the original key/value */
1133 res = g_hash_table_lookup_extended (manager->priv->seats,
1135 @@ -1420,64 +1457,22 @@ remove_seat (CkManager *manager,
1139 -#define IS_STR_SET(x) (x != NULL && x[0] != '\0')
1142 find_seat_for_session (CkManager *manager,
1146 - gboolean is_static_x11;
1147 - gboolean is_static_text;
1148 - char *display_device;
1149 - char *x11_display_device;
1150 - char *x11_display;
1151 - char *remote_host_name;
1152 - gboolean is_local;
1154 - is_static_text = FALSE;
1155 - is_static_x11 = FALSE;
1158 - display_device = NULL;
1159 - x11_display_device = NULL;
1160 - x11_display = NULL;
1161 - remote_host_name = NULL;
1164 - /* FIXME: use matching to group entries? */
1166 - ck_session_get_display_device (session, &display_device, NULL);
1167 - ck_session_get_x11_display_device (session, &x11_display_device, NULL);
1168 - ck_session_get_x11_display (session, &x11_display, NULL);
1169 - ck_session_get_remote_host_name (session, &remote_host_name, NULL);
1170 - ck_session_is_local (session, &is_local, NULL);
1172 - if (IS_STR_SET (x11_display)
1173 - && IS_STR_SET (x11_display_device)
1174 - && ! IS_STR_SET (remote_host_name)
1175 - && is_local == TRUE) {
1176 - is_static_x11 = TRUE;
1177 - } else if (! IS_STR_SET (x11_display)
1178 - && ! IS_STR_SET (x11_display_device)
1179 - && IS_STR_SET (display_device)
1180 - && ! IS_STR_SET (remote_host_name)
1181 - && is_local == TRUE) {
1182 - is_static_text = TRUE;
1186 + ck_session_get_seat_id (session, &sid, NULL);
1188 - if (is_static_x11 || is_static_text) {
1190 + if (! IS_STR_SET (sid)) {
1191 sid = g_strdup_printf ("%s/Seat%u", CK_DBUS_PATH, 1);
1192 - seat = g_hash_table_lookup (manager->priv->seats, sid);
1196 - g_free (display_device);
1197 - g_free (x11_display_device);
1198 - g_free (x11_display);
1199 - g_free (remote_host_name);
1200 + seat = g_hash_table_lookup (manager->priv->seats, sid);
1206 @@ -1612,36 +1607,52 @@ open_session_for_leader (CkManager
1213 + g_debug ("CkManager: Open session for leader.");
1214 ssid = ck_session_leader_peek_session_id (leader);
1215 cookie = ck_session_leader_peek_cookie (leader);
1217 - session = ck_session_new_with_parameters (ssid,
1220 + session = g_hash_table_lookup (manager->priv->sessions, ssid);
1222 if (session == NULL) {
1224 - g_debug ("Unable to create new session");
1225 - error = g_error_new (CK_MANAGER_ERROR,
1226 - CK_MANAGER_ERROR_GENERAL,
1227 - "Unable to create new session");
1228 - dbus_g_method_return_error (context, error);
1229 - g_error_free (error);
1230 + g_debug ("CkManager: Creating new session.");
1231 + session = ck_session_new_with_parameters (ssid,
1234 + if (session == NULL) {
1236 + g_debug ("CkManager: Unable to create new session");
1237 + error = g_error_new (CK_MANAGER_ERROR,
1238 + CK_MANAGER_ERROR_GENERAL,
1239 + "Unable to create new session");
1240 + dbus_g_method_return_error (context, error);
1241 + g_error_free (error);
1247 + g_hash_table_insert (manager->priv->sessions,
1249 + g_object_ref (session));
1252 + g_debug ("CkManager: Using found session.");
1253 + ck_session_set_parameters (session, parameters);
1256 - g_hash_table_insert (manager->priv->sessions,
1258 - g_object_ref (session));
1259 + ck_session_set_cookie (session, cookie, NULL);
1260 + ck_session_set_is_open (session, TRUE, NULL);
1263 seat = find_seat_for_session (manager, session);
1266 + ck_session_get_seat_id (session, &sid, NULL);
1267 /* create a new seat */
1268 - seat = add_new_seat (manager, CK_SEAT_KIND_DYNAMIC);
1269 + seat = add_new_seat (manager, sid, CK_SEAT_KIND_DYNAMIC, "Default");
1273 ck_seat_add_session (seat, session, NULL);
1274 @@ -1863,6 +1874,7 @@ generate_session_for_leader (CkManager
1278 + g_debug ("CkManager: Generate session for leader.");
1279 res = ck_session_leader_collect_parameters (leader,
1281 (CkSessionLeaderDoneFunc)collect_parameters_cb,
1282 @@ -1877,11 +1889,57 @@ generate_session_for_leader (CkManager
1287 +check_parameters_for_ssid (const GPtrArray *parameters)
1291 + if (parameters == NULL) {
1295 + for (i = 0; i < parameters->len; i++) {
1296 + GValue val_struct = { 0, };
1300 + g_value_init (&val_struct, CK_TYPE_PARAMETER_STRUCT);
1301 + g_value_set_static_boxed (&val_struct, g_ptr_array_index (parameters, i));
1303 + res = dbus_g_type_struct_get (&val_struct,
1307 + g_debug ("CkManager: Unable to read parameter name");
1311 + if (prop_name != NULL && strcmp (prop_name, "session") == 0) {
1312 + GValue prop_val = { 0, };
1313 + GValue *session_val;
1315 + g_value_init (&prop_val, G_TYPE_VALUE);
1316 + res = dbus_g_type_struct_get_member (&val_struct, 1, &prop_val);
1319 + g_debug ("CkManager: Unable to read parameter value");
1323 + session_val = g_value_get_boxed (&prop_val);
1325 + return g_value_dup_string (session_val);
1333 -create_session_for_sender (CkManager *manager,
1334 - const char *sender,
1335 - const GPtrArray *parameters,
1336 - DBusGMethodInvocation *context)
1337 +open_session_for_sender (CkManager *manager,
1338 + const char *sender,
1339 + const GPtrArray *parameters,
1340 + DBusGMethodInvocation *context)
1344 @@ -1889,6 +1947,7 @@ create_session_for_sender (CkManager
1347 CkSessionLeader *leader;
1348 + CkSession *session;
1350 g_debug ("CkManager: create session for sender: %s", sender);
1352 @@ -1907,9 +1966,21 @@ create_session_for_sender (CkManager
1355 cookie = generate_session_cookie (manager);
1356 - ssid = generate_session_id (manager);
1358 - g_debug ("Creating new session ssid: %s", ssid);
1359 + ssid = check_parameters_for_ssid (parameters);
1361 + if (IS_STR_SET (ssid)) {
1362 + session = g_hash_table_lookup (manager->priv->sessions, ssid);
1364 + /* FIXME: Need to verify that the session belongs to a seat
1365 + * managed by the sender
1367 + g_debug ("CkManager: Managing existing session ssid: %s", ssid);
1369 + ssid = generate_session_id (manager);
1371 + g_debug ("CkManager: Creating new session ssid: %s", ssid);
1374 leader = ck_session_leader_new ();
1375 ck_session_leader_set_uid (leader, uid);
1376 @@ -2148,7 +2219,7 @@ ck_manager_open_session (CkManager
1379 sender = dbus_g_method_get_sender (context);
1380 - ret = create_session_for_sender (manager, sender, NULL, context);
1381 + ret = open_session_for_sender (manager, sender, NULL, context);
1385 @@ -2163,7 +2234,7 @@ ck_manager_open_session_with_parameters
1388 sender = dbus_g_method_get_sender (context);
1389 - ret = create_session_for_sender (manager, sender, parameters, context);
1390 + ret = open_session_for_sender (manager, sender, parameters, context);
1394 @@ -2180,10 +2251,12 @@ remove_session_for_cookie (CkManager *m
1398 + gboolean should_remove_session;
1402 orig_session = NULL;
1403 + should_remove_session = FALSE;
1405 g_debug ("Removing session for cookie: %s", cookie);
1407 @@ -2210,6 +2283,17 @@ remove_session_for_cookie (CkManager *m
1411 + ck_session_set_is_open (orig_session, FALSE, NULL);
1412 + ck_session_set_cookie (orig_session, NULL, NULL);
1413 + ck_session_set_active (orig_session, FALSE, NULL);
1414 + ck_session_set_unix_user (orig_session, 0, NULL);
1415 + ck_session_set_x11_display (orig_session, NULL, NULL);
1416 + ck_session_set_x11_display_device (orig_session, NULL, NULL);
1417 + ck_session_set_display_device (orig_session, NULL, NULL);
1418 + ck_session_set_login_session_id (orig_session, NULL, NULL);
1419 + ck_session_set_remote_host_name (orig_session, NULL, NULL);
1420 + ck_session_set_under_request (orig_session, FALSE, NULL);
1422 /* Must keep a reference to the session in the manager until
1423 * all events for seats are cleared. So don't remove
1424 * or steal the session from the master list until
1425 @@ -2217,31 +2301,33 @@ remove_session_for_cookie (CkManager *m
1426 * for seat removals doesn't work.
1429 - /* remove from seat */
1431 - ck_session_get_seat_id (orig_session, &sid, NULL);
1432 - if (sid != NULL) {
1434 - seat = g_hash_table_lookup (manager->priv->seats, sid);
1435 - if (seat != NULL) {
1438 - ck_seat_remove_session (seat, orig_session, NULL);
1440 - kind = CK_SEAT_KIND_STATIC;
1441 - /* if dynamic seat has no sessions then remove it */
1442 - ck_seat_get_kind (seat, &kind, NULL);
1443 - if (kind == CK_SEAT_KIND_DYNAMIC) {
1444 - remove_seat (manager, seat);
1445 + ck_session_get_remove_on_close (orig_session, &should_remove_session, NULL);
1447 + if (should_remove_session) {
1448 + /* remove from seat */
1449 + g_debug ("CkManager: Should remove session");
1451 + ck_session_get_seat_id (orig_session, &sid, NULL);
1452 + if (sid != NULL) {
1454 + seat = g_hash_table_lookup (manager->priv->seats, sid);
1455 + if (seat != NULL) {
1458 + ck_seat_remove_session (seat, orig_session, NULL);
1460 + kind = CK_SEAT_KIND_STATIC;
1461 + /* if dynamic seat has no sessions then remove it */
1462 + ck_seat_get_kind (seat, &kind, NULL);
1469 - /* Remove the session from the list but don't call
1470 - * unref until we are done with it */
1471 - g_hash_table_steal (manager->priv->sessions,
1472 - ck_session_leader_peek_session_id (leader));
1473 + /* Remove the session from the list but don't call
1474 + * unref until we are done with it */
1475 + g_hash_table_steal (manager->priv->sessions,
1476 + ck_session_leader_peek_session_id (leader));
1479 ck_manager_dump (manager);
1481 @@ -2249,11 +2335,13 @@ remove_session_for_cookie (CkManager *m
1485 - if (orig_session != NULL) {
1486 - g_object_unref (orig_session);
1488 - g_free (orig_ssid);
1489 + if (should_remove_session) {
1490 + if (orig_session != NULL) {
1491 + g_object_unref (orig_session);
1494 + g_free (orig_ssid);
1499 @@ -2374,6 +2462,7 @@ remove_leader_for_connection (const char
1500 g_assert (leader != NULL);
1501 g_assert (data->service_name != NULL);
1503 + g_debug ("CkManager: Remove leader for connection");
1504 name = ck_session_leader_peek_service_name (leader);
1505 if (strcmp (name, data->service_name) == 0) {
1506 remove_session_for_cookie (data->manager, cookie, NULL);
1507 @@ -2391,6 +2480,8 @@ remove_sessions_for_connection (CkManage
1509 RemoveLeaderData data;
1511 + g_debug ("CkManager: Remove sessions for connection");
1513 data.service_name = service_name;
1514 data.manager = manager;
1516 @@ -2426,6 +2517,8 @@ register_manager (CkManager *manager)
1517 manager->priv->pol_ctx = polkit_authority_get ();
1520 + g_debug ("CkManager: Registering manager");
1523 manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
1524 if (manager->priv->connection == NULL) {
1525 @@ -2471,9 +2564,11 @@ ck_manager_class_init (CkManagerClass *k
1526 G_STRUCT_OFFSET (CkManagerClass, seat_added),
1529 - g_cclosure_marshal_VOID__BOXED,
1530 + ck_marshal_VOID__STRING_STRING,
1532 - 1, DBUS_TYPE_G_OBJECT_PATH);
1536 signals [SEAT_REMOVED] =
1537 g_signal_new ("seat-removed",
1538 G_TYPE_FROM_CLASS (object_class),
1539 @@ -2580,6 +2675,43 @@ ck_manager_get_seats (CkManager *manage
1543 +listify_unmanaged_seat_ids (char *id,
1545 + GPtrArray **array)
1547 + if (ck_seat_is_managed (seat)) {
1551 + g_ptr_array_add (*array, g_strdup (id));
1557 + dbus-send --system --dest=org.freedesktop.ConsoleKit \
1558 + --type=method_call --print-reply --reply-timeout=2000 \
1559 + /org/freedesktop/ConsoleKit/Manager \
1560 + org.freedesktop.ConsoleKit.Manager.GetUnmanagedSeats
1563 +ck_manager_get_unmanaged_seats (CkManager *manager,
1564 + GPtrArray **seats,
1567 + g_return_val_if_fail (CK_IS_MANAGER (manager), FALSE);
1569 + if (seats == NULL) {
1573 + *seats = g_ptr_array_new ();
1574 + g_hash_table_foreach (manager->priv->seats, (GHFunc)listify_unmanaged_seat_ids, seats);
1580 listify_session_ids (char *id,
1583 @@ -2604,16 +2736,321 @@ ck_manager_get_sessions (CkManager *man
1589 + dbus-send --system --dest=org.freedesktop.ConsoleKit \
1590 + --type=method_call --print-reply --reply-timeout=2000 \
1591 + /org/freedesktop/ConsoleKit/Manager \
1592 + org.freedesktop.ConsoleKit.Manager.AddSeat string:Default
1595 +ck_manager_add_seat (CkManager *manager,
1602 + g_debug ("CkManager: Add seat '%s'.", *sid);
1603 + g_return_val_if_fail (CK_IS_MANAGER (manager), FALSE);
1605 + seat = add_new_seat (manager, NULL, CK_SEAT_KIND_DYNAMIC, type);
1607 + if (!ck_seat_get_id (seat, sid, error)) {
1616 + dbus-send --system --dest=org.freedesktop.ConsoleKit \
1617 + --type=method_call --print-reply --reply-timeout=2000 \
1618 + /org/freedesktop/ConsoleKit/Manager \
1619 + org.freedesktop.ConsoleKit.Manager.AddSeatById \
1620 + objpath:/org/freedesktop/ConsoleKit/SeatTest \
1623 +ck_manager_add_seat_by_id (CkManager *manager,
1630 + g_return_val_if_fail (CK_IS_MANAGER (manager), FALSE);
1632 + seat = add_new_seat (manager, sid, CK_SEAT_KIND_DYNAMIC, type);
1634 + return !(seat == NULL);
1639 + dbus-send --system --dest=org.freedesktop.ConsoleKit \
1640 + --type=method_call --print-reply --reply-timeout=2000 \
1641 + /org/freedesktop/ConsoleKit/Manager \
1642 + org.freedesktop.ConsoleKit.Manager.RemoveSeat \
1643 + obj:/org/freedesktop/ConsoleKit/Seat2
1646 +ck_manager_remove_seat (CkManager *manager,
1648 + DBusGMethodInvocation *context)
1650 + CkSeat *seat = NULL;
1653 + g_debug ("CkManager: Remove seat '%s'.", sid);
1654 + g_return_val_if_fail (CK_IS_MANAGER (manager), FALSE);
1656 + seat = g_hash_table_lookup (manager->priv->seats, sid);
1658 + if (seat == NULL) {
1661 + error = g_error_new (CK_SEAT_ERROR,
1662 + CK_SEAT_ERROR_GENERAL,
1663 + _("Seat '%s' doesn't exist"),
1666 + dbus_g_method_return_error (context, error);
1667 + g_error_free (error);
1672 + ck_seat_get_kind (seat, &kind, NULL);
1674 + if (kind == CK_SEAT_KIND_STATIC) {
1677 + error = g_error_new (CK_SEAT_ERROR,
1678 + CK_SEAT_ERROR_GENERAL,
1679 + _("Seat '%s' is static and can't be removed"),
1682 + dbus_g_method_return_error (context, error);
1683 + g_error_free (error);
1688 + if (ck_seat_is_managed (seat)) {
1689 + ck_seat_request_removal (seat);
1691 + remove_seat (manager, seat);
1699 + dbus-send --system --dest=org.freedesktop.ConsoleKit \
1700 + --type=method_call --print-reply --reply-timeout=2000 \
1701 + /org/freedesktop/ConsoleKit/Manager \
1702 + org.freedesktop.ConsoleKit.Manager.AddSession \
1703 + objpath:/org/freedesktop/ConsoleKit/Seat2 \
1704 + string:"LoginWindow" \
1705 + dict:string:string:"vt","vt9","display",":123"
1708 +ck_manager_add_session (CkManager *manager,
1711 + const char *display_type,
1712 + GHashTable *variables,
1713 + DBusGMethodInvocation *context)
1716 + CkSession *session;
1719 + g_debug ("CkManager: Add session");
1720 + seat = g_hash_table_lookup (manager->priv->seats, sid);
1722 + if (seat == NULL) {
1725 + error = g_error_new (CK_SEAT_ERROR,
1726 + CK_SEAT_ERROR_GENERAL,
1727 + _("Seat '%s' doesn't exist"),
1730 + dbus_g_method_return_error (context, error);
1731 + g_error_free (error);
1736 + ssid = generate_session_id (manager);
1738 + session = ck_session_new (ssid, type, display_type, variables);
1740 + if (session == NULL) {
1743 + error = g_error_new (CK_SEAT_ERROR,
1744 + CK_SEAT_ERROR_GENERAL,
1745 + _("Session could not be added to seat '%s'"),
1748 + dbus_g_method_return_error (context, error);
1749 + g_error_free (error);
1754 + ck_session_set_seat_id (session, sid, NULL);
1755 + if (IS_STR_SET (type) && g_str_equal (type, "LoginWindow")) {
1756 + session_set_remove_on_close (session, FALSE, NULL);
1758 + session_set_remove_on_close (session, TRUE, NULL);
1761 + ck_seat_add_session (seat, session, NULL);
1763 + g_hash_table_insert (manager->priv->sessions,
1767 + dbus_g_method_return (context, ssid);
1773 + dbus-send --system --dest=org.freedesktop.ConsoleKit \
1774 + --type=method_call --print-reply --reply-timeout=2000 \
1775 + /org/freedesktop/ConsoleKit/Manager \
1776 + org.freedesktop.ConsoleKit.Manager.RemoveSession \
1777 + objpath:/org/freedesktop/ConsoleKit/Session2
1780 +ck_manager_remove_session (CkManager *manager,
1782 + DBusGMethodInvocation *context)
1784 + CkSession *session;
1790 + g_debug ("CkManager: Remove session.");
1791 + session = g_hash_table_lookup (manager->priv->sessions, ssid);
1793 + if (session == NULL) {
1796 + error = g_error_new (CK_SEAT_ERROR,
1797 + CK_SEAT_ERROR_GENERAL,
1798 + _("Session '%s' doesn't exist"),
1801 + dbus_g_method_return_error (context, error);
1802 + g_error_free (error);
1807 + ck_session_get_seat_id (session, &sid, NULL);
1808 + seat = g_hash_table_lookup (manager->priv->seats, sid);
1811 + if (seat == NULL) {
1812 + g_warning ("Session '%s' is not associated with a seat", ssid);
1813 + g_hash_table_remove (manager->priv->sessions, ssid);
1819 + ck_session_is_open (session, &is_open, NULL);
1820 + session_set_remove_on_close (session, TRUE, NULL);
1822 + /* We'll let the seat manager close us when it's ready
1824 + if (ck_seat_is_managed (seat) && is_open) {
1825 + ck_seat_request_close_session (seat, session, NULL);
1826 + dbus_g_method_return (context);
1831 + if (!ck_seat_remove_session (seat, session, &error)) {
1832 + if (error == NULL) {
1836 + dbus_g_method_return_error (context, error);
1837 + g_error_free (error);
1841 + g_hash_table_remove (manager->priv->sessions, ssid);
1842 + dbus_g_method_return (context);
1847 +add_sessions_from_seat (CkManager *manager,
1850 + GPtrArray *sessions;
1853 + g_debug ("CkManager: Add session from seat.");
1854 + ck_seat_get_sessions (seat, &sessions, NULL);
1856 + for (i = 0; i < sessions->len; i++) {
1858 + CkSession *session;
1860 + ssid = g_ptr_array_index (sessions, i);
1861 + session = ck_seat_get_session (seat, ssid);
1863 + g_hash_table_insert (manager->priv->sessions,
1868 + g_ptr_array_free (sessions, TRUE);
1872 add_seat_for_file (CkManager *manager,
1873 const char *filename)
1879 + g_debug ("CkManager: Add seat for file.");
1880 sid = generate_seat_id (manager);
1881 + orig_sid = g_strdup (sid);
1882 + seat = ck_seat_new_from_file (&sid, filename);
1884 + if (seat == NULL) {
1885 + /* returns null if connection to bus fails */
1887 + g_free (orig_sid);
1888 + manager->priv->seat_serial--;
1892 + if (!g_str_equal (orig_sid, sid)) {
1893 + manager->priv->seat_serial--;
1895 + g_free (orig_sid);
1897 - seat = ck_seat_new_from_file (sid, filename);
1898 + add_sessions_from_seat (manager, seat);
1900 + if (seat == NULL) {
1906 @@ -2636,7 +3073,7 @@ add_seat_for_file (CkManager *manager,
1907 ck_seat_run_programs (seat, NULL, NULL, "seat_added");
1909 g_debug ("Emitting seat-added: %s", sid);
1910 - g_signal_emit (manager, signals [SEAT_ADDED], 0, sid);
1911 + g_signal_emit (manager, signals [SEAT_ADDED], 0, sid, "Default");
1913 log_seat_added_event (manager, seat);
1915 @@ -2647,6 +3084,7 @@ load_seats_from_dir (CkManager *manager)
1919 + GQueue seat_queue;
1922 d = g_dir_open (CK_SEAT_DIR,
1923 @@ -2658,17 +3096,26 @@ load_seats_from_dir (CkManager *manager)
1927 + g_queue_init (&seat_queue);
1928 while ((file = g_dir_read_name (d)) != NULL) {
1929 if (g_str_has_suffix (file, ".seat")) {
1931 path = g_build_filename (CK_SEAT_DIR, file, NULL);
1932 - add_seat_for_file (manager, path);
1934 + g_queue_push_tail (&seat_queue, path);
1940 + g_queue_sort (&seat_queue, (GCompareDataFunc) strverscmp, NULL);
1942 + while (!g_queue_is_empty (&seat_queue)) {
1945 + path = g_queue_pop_head (&seat_queue);
1946 + add_seat_for_file (manager, path);
1953 @@ -2704,8 +3151,6 @@ ck_manager_init (CkManager *manager)
1954 (GDestroyNotify) g_object_unref);
1956 manager->priv->logger = ck_event_logger_new (LOG_FILE);
1958 - create_seats (manager);
1962 @@ -2750,7 +3195,48 @@ ck_manager_new (void)
1963 g_object_unref (manager_object);
1967 + create_seats (CK_MANAGER (manager_object));
1970 return CK_MANAGER (manager_object);
1974 +ck_manager_will_not_respawn (CkManager *manager,
1976 + DBusGMethodInvocation *context)
1980 + CkSession *session;
1983 + g_debug ("CkManager: Will not respawn: '%s'.", ssid);
1984 + session = g_hash_table_lookup (manager->priv->sessions, ssid);
1986 + if (session == NULL) {
1989 + error = g_error_new (CK_SEAT_ERROR,
1990 + CK_SEAT_ERROR_GENERAL,
1991 + _("Session '%s' doesn't exist"),
1994 + dbus_g_method_return_error (context, error);
1995 + g_error_free (error);
2000 + session_set_remove_on_close (session, FALSE, NULL);
2001 + ck_session_get_seat_id (session, &sid, NULL);
2002 + seat = g_hash_table_lookup (manager->priv->seats, sid);
2005 + ck_seat_no_respawn (seat, session, &error);
2007 + dbus_g_method_return (context);
2011 diff --git a/src/ck-manager.h b/src/ck-manager.h
2012 index 4bd56e8..4304e71 100644
2013 --- a/src/ck-manager.h
2014 +++ b/src/ck-manager.h
2015 @@ -49,7 +49,8 @@ typedef struct
2016 GObjectClass parent_class;
2018 void (* seat_added) (CkManager *manager,
2021 + const char *type);
2022 void (* seat_removed) (CkManager *manager,
2024 void (* system_idle_hint_changed) (CkManager *manager,
2025 @@ -96,6 +97,9 @@ gboolean ck_manager_get_sessi
2026 gboolean ck_manager_get_seats (CkManager *manager,
2029 +gboolean ck_manager_get_unmanaged_seats (CkManager *manager,
2030 + GPtrArray **seats,
2032 gboolean ck_manager_close_session (CkManager *manager,
2034 DBusGMethodInvocation *context);
2035 @@ -128,6 +132,31 @@ gboolean ck_manager_open_sess
2036 const GPtrArray *parameters,
2037 DBusGMethodInvocation *context);
2039 +gboolean ck_manager_add_seat (CkManager *manager,
2043 +gboolean ck_manager_add_seat_by_id (CkManager *manager,
2047 +gboolean ck_manager_remove_seat (CkManager *manager,
2049 + DBusGMethodInvocation *context);
2051 +gboolean ck_manager_add_session (CkManager *manager,
2054 + const char *display_type,
2055 + GHashTable *parameters,
2056 + DBusGMethodInvocation *context);
2057 +gboolean ck_manager_remove_session (CkManager *manager,
2059 + DBusGMethodInvocation *context);
2060 +gboolean ck_manager_will_not_respawn (CkManager *manager,
2061 + const char *cookie,
2062 + DBusGMethodInvocation *context);
2066 #endif /* __CK_MANAGER_H */
2067 diff --git a/src/ck-marshal.list b/src/ck-marshal.list
2068 index 7f60efc..f8029a6 100644
2069 --- a/src/ck-marshal.list
2070 +++ b/src/ck-marshal.list
2076 +VOID:STRING,BOOLEAN,STRING,POINTER,STRING,POINTER
2077 +VOID:STRING,STRING,STRING,POINTER,STRING,POINTER
2078 diff --git a/src/ck-seat.c b/src/ck-seat.c
2079 index af7db59..dd2a387 100644
2083 #include "ck-seat-glue.h"
2084 #include "ck-marshal.h"
2086 +#include "ck-display-template.h"
2087 #include "ck-session.h"
2088 #include "ck-vt-monitor.h"
2089 #include "ck-run-programs.h"
2091 #define CK_SEAT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CK_TYPE_SEAT, CkSeatPrivate))
2093 +#define CK_SESSION_DIR SYSCONFDIR "/ConsoleKit/sessions.d"
2095 #define CK_DBUS_PATH "/org/freedesktop/ConsoleKit"
2096 #define CK_DBUS_NAME "org.freedesktop.ConsoleKit"
2098 #define NONULL_STRING(x) ((x) != NULL ? (x) : "")
2099 +#define N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
2101 +#define IS_STR_SET(x) (x != NULL && x[0] != '\0')
2103 +#define CK_DBUS_TYPE_G_STRING_STRING_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING))
2105 struct CkSeatPrivate
2110 GHashTable *sessions;
2113 @@ -62,6 +71,8 @@ struct CkSeatPrivate
2114 CkVtMonitor *vt_monitor;
2116 DBusGConnection *connection;
2118 + DBusGProxy *manager_proxy;
2122 @@ -73,6 +84,10 @@ enum {
2123 SESSION_REMOVED_FULL,
2127 + OPEN_SESSION_REQUEST,
2128 + CLOSE_SESSION_REQUEST,
2133 @@ -80,6 +95,7 @@ enum {
2140 static guint signals [LAST_SIGNAL] = { 0, };
2141 @@ -286,6 +302,7 @@ ck_seat_activate_session (CkSeat
2147 g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
2149 @@ -297,12 +314,398 @@ ck_seat_activate_session (CkSeat
2150 session = g_hash_table_lookup (seat->priv->sessions, ssid);
2153 - ret = _seat_activate_session (seat, session, context);
2154 + ck_session_is_open (session, &is_open, NULL);
2156 + ret = ck_seat_request_open_session (seat, session, NULL);
2157 + dbus_g_method_return (context, NULL);
2159 + ret = _seat_activate_session (seat, session, context);
2166 +on_substitution_match (const GMatchInfo *match_info,
2168 + GHashTable *substitution_variables)
2171 + char *value = NULL;
2173 + match = g_match_info_fetch (match_info, 1);
2175 + if (substitution_variables != NULL)
2176 + value = g_hash_table_lookup (substitution_variables, match);
2178 + if (value != NULL) {
2179 + g_string_append (result, value);
2181 + char *original_string;
2183 + original_string = g_match_info_fetch (match_info, 0);
2184 + g_string_append (result, original_string);
2185 + g_free (original_string);
2193 +apply_substitutions (const char *value,
2194 + GHashTable *substitution_variables)
2196 + GRegex *expression;
2197 + char *expanded_string;
2199 + expression = g_regex_new ("\\$([^[:space:]]+)", 0, 0, NULL);
2200 + expanded_string = g_regex_replace_eval (expression,
2203 + (GRegexEvalCallback)
2204 + on_substitution_match,
2205 + substitution_variables,
2208 + if (expanded_string == NULL) {
2209 + expanded_string = g_strdup (value);
2212 + return expanded_string;
2215 +static GHashTable *
2216 +get_evaluated_parameter_map (GHashTable *parameters,
2217 + GHashTable *substitution_variables)
2219 + GHashTable *evaluated_parameters;
2220 + GHashTableIter iter;
2221 + gpointer key, value;
2223 + evaluated_parameters = g_hash_table_new_full (g_str_hash, g_str_equal,
2224 + (GDestroyNotify) g_free,
2225 + (GDestroyNotify) g_free);
2227 + g_hash_table_iter_init (&iter, parameters);
2228 + while (g_hash_table_iter_next (&iter, &key, &value)) {
2229 + char *expanded_string;
2231 + expanded_string = apply_substitutions ((char *) value,
2232 + substitution_variables);
2234 + g_hash_table_insert (evaluated_parameters,
2235 + g_strdup ((char *) key),
2239 + return evaluated_parameters;
2243 +request_session (gpointer key,
2245 + gpointer user_data)
2247 + CkSeat *seat = CK_SEAT (user_data);
2248 + CkSession *session = (CkSession *) value;
2250 + g_debug ("CkSeat: Request session");
2251 + ck_session_set_ever_open (session, FALSE, NULL);
2252 + ck_session_set_under_request (session, FALSE, NULL);
2253 + ck_seat_request_open_session (seat, session, NULL);
2257 +append_hash_table_to_dbus_message_iter (DBusMessageIter *iter,
2258 + GHashTable *hash_table)
2260 + GHashTableIter hash_table_iter;
2261 + gpointer key, value;
2262 + DBusMessageIter array_iter;
2264 + dbus_message_iter_open_container (iter,
2266 + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
2267 + DBUS_TYPE_STRING_AS_STRING
2268 + DBUS_TYPE_STRING_AS_STRING
2269 + DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
2273 + g_hash_table_iter_init (&hash_table_iter, hash_table);
2274 + while (g_hash_table_iter_next (&hash_table_iter, &key, &value)) {
2275 + DBusMessageIter dict_iter;
2277 + dbus_message_iter_open_container (&array_iter,
2278 + DBUS_TYPE_DICT_ENTRY,
2282 + dbus_message_iter_append_basic (&dict_iter, DBUS_TYPE_STRING, &key);
2283 + dbus_message_iter_append_basic (&dict_iter, DBUS_TYPE_STRING, &value);
2284 + dbus_message_iter_close_container (&array_iter, &dict_iter);
2286 + dbus_message_iter_close_container (iter, &array_iter);
2290 +emit_session_open_request (CkSeat *seat,
2292 + const char *session_type,
2293 + const char *display_template_name,
2294 + GHashTable *display_variables,
2295 + const char *display_type,
2296 + GHashTable *evaluated_parameters)
2298 + DBusMessage *message;
2299 + DBusConnection *connection;
2300 + DBusMessageIter iter;
2302 + if (!ck_seat_is_managed (seat))
2305 + message = dbus_message_new_signal (seat->priv->id,
2306 + "org.freedesktop.ConsoleKit.Seat",
2307 + "OpenSessionRequest");
2309 + dbus_message_set_destination (message,
2310 + dbus_g_proxy_get_bus_name (seat->priv->manager_proxy));
2312 + dbus_message_iter_init_append (message, &iter);
2313 + dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &ssid);
2314 + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &session_type);
2315 + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_template_name);
2316 + append_hash_table_to_dbus_message_iter (&iter, display_variables);
2317 + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_type);
2318 + append_hash_table_to_dbus_message_iter (&iter, evaluated_parameters);
2320 + connection = dbus_bus_get (DBUS_BUS_SYSTEM, NULL);
2321 + dbus_connection_send (connection, message, NULL);
2322 + dbus_connection_unref (connection);
2323 + dbus_message_unref (message);
2327 +ck_seat_request_open_session (CkSeat *seat,
2328 + CkSession *session,
2333 + CkDisplayTemplate *display_template;
2334 + GHashTable *display_variables;
2335 + GHashTable *display_parameters;
2336 + GHashTable *evaluated_parameters;
2338 + gboolean ever_open;
2339 + gboolean under_request;
2341 + ck_session_is_open (session, &is_open, NULL);
2347 + ck_session_get_under_request (session, &under_request, NULL);
2348 + if (under_request) {
2352 + ck_session_set_under_request (session, TRUE, NULL);
2354 + ck_session_get_ever_open (session, &ever_open, NULL);
2356 + display_template = ck_session_get_display_template (session);
2358 + if (display_template == NULL) {
2362 + ck_session_get_session_type (session, &type, NULL);
2364 + if (type == NULL) {
2365 + g_object_unref (display_template);
2369 + /* substitute $display $vt etc */
2370 + display_variables = ck_session_get_display_variables (session);
2371 + display_parameters = ck_display_template_get_parameters (display_template);
2373 + if (display_parameters == NULL) {
2375 + g_object_unref (display_template);
2376 + g_hash_table_unref (display_variables);
2381 + evaluated_parameters = get_evaluated_parameter_map (display_parameters, display_variables);
2383 + evaluated_parameters = get_evaluated_parameter_map (display_parameters, NULL);
2386 + g_hash_table_unref (display_parameters);
2388 + ck_session_get_id (session, &ssid, NULL);
2390 + emit_session_open_request (seat, ssid, type,
2391 + ck_display_template_get_name (display_template),
2392 + display_variables,
2393 + ck_display_template_get_type_string (display_template),
2394 + evaluated_parameters);
2398 + g_hash_table_unref (evaluated_parameters);
2399 + g_hash_table_unref (display_variables);
2400 + g_object_unref (display_template);
2406 +on_seat_manager_disappeared (CkSeat *seat)
2408 + g_debug ("CkSeat: Seat Manager Disappeared.");
2410 + g_signal_handlers_disconnect_by_func (seat->priv->manager_proxy,
2411 + G_CALLBACK (on_seat_manager_disappeared),
2413 + g_object_unref (seat->priv->manager_proxy);
2414 + seat->priv->manager_proxy = NULL;
2416 + /* FIXME: should probably emit a signal so a new display manager
2417 + * knows that the seat is now unmanaged
2419 + * (maybe only if its kind is static?)
2424 +ck_seat_manage (CkSeat *seat,
2425 + DBusGMethodInvocation *context)
2427 + char *sender_name;
2429 + g_debug ("CkSeat: Seat manage.");
2430 + sender_name = dbus_g_method_get_sender (context);
2432 + if (seat->priv->manager_proxy != NULL) {
2434 + const char *existing_manager_name;
2436 + existing_manager_name = dbus_g_proxy_get_bus_name (seat->priv->manager_proxy);
2438 + if (existing_manager_name == NULL) {
2439 + g_warning ("Seat manager lacks bus unique name");
2440 + existing_manager_name = "<unknown>";
2443 + error = g_error_new (CK_SEAT_ERROR,
2444 + CK_SEAT_ERROR_GENERAL,
2445 + _("Seat already managed (by '%s')"),
2446 + existing_manager_name);
2448 + dbus_g_method_return_error (context, error);
2449 + g_error_free (error);
2453 + /* FIXME: We pass in a bogus object path (the path we use on this side of
2454 + * the pipe) and interface here.
2456 + * We only use the proxy to watch for when the other side disappears, not
2457 + * for communicating with it. All communication is one-way using signals.
2459 + seat->priv->manager_proxy = dbus_g_proxy_new_for_name (seat->priv->connection,
2463 + "org.freedesktop.ConsoleKit.SeatManager");
2464 + g_free (sender_name);
2466 + g_signal_connect_swapped (seat->priv->manager_proxy,
2468 + G_CALLBACK (on_seat_manager_disappeared),
2471 + g_hash_table_foreach (seat->priv->sessions, request_session, seat);
2473 + dbus_g_method_return (context);
2478 +ck_seat_unmanage (CkSeat *seat,
2479 + DBusGMethodInvocation *context)
2482 + const char *existing_manager_name;
2483 + char *sender_name;
2485 + g_debug ("CkSeat: Seat unmanage.");
2486 + if (seat->priv->manager_proxy == NULL) {
2489 + error = g_error_new (CK_SEAT_ERROR,
2490 + CK_SEAT_ERROR_GENERAL,
2491 + _("Seat not managed"));
2493 + dbus_g_method_return_error (context, error);
2494 + g_error_free (error);
2498 + sender_name = dbus_g_method_get_sender (context);
2499 + existing_manager_name = dbus_g_proxy_get_bus_name (seat->priv->manager_proxy);
2501 + if (strcmp (sender_name, existing_manager_name) != 0) {
2503 + error = g_error_new (CK_SEAT_ERROR,
2504 + CK_SEAT_ERROR_GENERAL,
2505 + _("Seat managed by '%s' not '%s'"),
2506 + existing_manager_name,
2509 + dbus_g_method_return_error (context, error);
2510 + g_error_free (error);
2515 + on_seat_manager_disappeared (seat);
2517 + dbus_g_method_return (context);
2522 +ck_seat_request_removal (CkSeat *seat)
2524 + DBusMessage *message;
2525 + DBusConnection *connection;
2527 + g_return_if_fail (CK_IS_SEAT (seat));
2528 + g_return_if_fail (ck_seat_is_managed (seat));
2530 + g_debug ("CkSeat: Seat request removal.");
2532 + message = dbus_message_new_signal (seat->priv->id,
2533 + "org.freedesktop.ConsoleKit.Seat",
2536 + dbus_message_set_destination (message,
2537 + dbus_g_proxy_get_bus_name (seat->priv->manager_proxy));
2539 + connection = dbus_bus_get (DBUS_BUS_SYSTEM, NULL);
2540 + dbus_connection_send (connection, message, NULL);
2541 + dbus_connection_unref (connection);
2542 + dbus_message_unref (message);
2546 match_session_display_device (const char *key,
2548 const char *display_device)
2549 @@ -313,6 +716,8 @@ match_session_display_device (const char
2553 + g_debug ("CkSeat: Session display device.");
2555 if (session == NULL) {
2558 @@ -485,6 +890,8 @@ change_active_session (CkSeat *seat,
2560 CkSession *old_session;
2562 + g_debug ("CkSeat: Change active session.");
2564 if (seat->priv->active_session == session) {
2567 @@ -514,7 +921,10 @@ change_active_session (CkSeat *seat,
2568 * must be sent when the database dump is finished it is
2569 * important that the '-full' signalled is emitted first. */
2571 - g_signal_emit (seat, signals [ACTIVE_SESSION_CHANGED_FULL], 0, old_session, session);
2572 + if (CK_IS_SESSION (old_session)) {
2573 + g_signal_emit (seat, signals [ACTIVE_SESSION_CHANGED_FULL], 0, old_session, session);
2576 g_signal_emit (seat, signals [ACTIVE_SESSION_CHANGED], 0, ssid);
2578 if (old_session != NULL) {
2579 @@ -525,6 +935,42 @@ change_active_session (CkSeat *seat,
2583 +find_possible_session_to_activate (CkSeat *seat)
2585 + GHashTableIter iter;
2586 + gpointer key, value;
2588 + char *session_type = NULL;
2589 + CkSession *login_session = NULL;
2591 + g_debug ("CkSeat: Find possible session to activate");
2592 + g_hash_table_iter_init (&iter, seat->priv->sessions);
2593 + while (g_hash_table_iter_next (&iter, &key, &value)) {
2595 + ck_session_is_open (value, &is_open, NULL);
2598 + login_session = NULL;
2599 + change_active_session (seat, value);
2603 + ck_session_get_session_type (value, &session_type, NULL);
2604 + if (IS_STR_SET (session_type) &&
2605 + g_str_equal (session_type, "LoginWindow")) {
2606 + login_session = value;
2607 + g_free (session_type);
2611 + if (login_session != NULL) {
2612 + ck_session_set_ever_open (login_session, FALSE, NULL);
2613 + ck_seat_request_open_session (seat, login_session, NULL);
2619 update_active_vt (CkSeat *seat,
2622 @@ -536,7 +982,12 @@ update_active_vt (CkSeat *seat,
2623 g_debug ("Active device: %s", device);
2625 session = find_session_for_display_device (seat, device);
2626 - change_active_session (seat, session);
2628 + if (session == NULL) {
2629 + find_possible_session_to_activate (seat);
2631 + change_active_session (seat, session);
2636 @@ -546,12 +997,20 @@ maybe_update_active_session (CkSeat *sea
2640 - if (seat->priv->kind != CK_SEAT_KIND_STATIC) {
2643 + g_debug ("CkSeat: Check to see if we should update active session");
2645 - if (ck_vt_monitor_get_active (seat->priv->vt_monitor, &num, NULL)) {
2646 - update_active_vt (seat, num);
2647 + switch (seat->priv->kind){
2648 + case CK_SEAT_KIND_STATIC:
2649 + if (ck_vt_monitor_get_active (seat->priv->vt_monitor,
2651 + update_active_vt (seat, num);
2654 + case CK_SEAT_KIND_DYNAMIC:
2655 + find_possible_session_to_activate (seat);
2662 @@ -560,6 +1019,7 @@ session_activate (CkSession
2663 DBusGMethodInvocation *context,
2666 + g_debug ("CkSeat: Session activate.");
2667 _seat_activate_session (seat, session, context);
2669 /* always return TRUE to indicate that the signal was handled */
2670 @@ -583,6 +1043,8 @@ ck_seat_remove_session (CkSeat *
2672 ck_session_get_id (session, &ssid, NULL);
2674 + g_debug ("CkSeat: Removing session '%s'", ssid);
2676 /* Need to get the original key/value */
2677 res = g_hash_table_lookup_extended (seat->priv->sessions,
2679 @@ -627,18 +1089,118 @@ ck_seat_remove_session (CkSeat *
2684 +emit_session_close_request (CkSeat *seat,
2687 + DBusMessage *message;
2688 + DBusConnection *connection;
2689 + DBusMessageIter iter;
2691 + g_debug ("CkSeat: Emit Session Close request");
2693 + message = dbus_message_new_signal (seat->priv->id,
2694 + "org.freedesktop.ConsoleKit.Seat",
2695 + "CloseSessionRequest");
2697 + dbus_message_set_destination (message,
2698 + dbus_g_proxy_get_bus_name (seat->priv->manager_proxy));
2700 + dbus_message_iter_init_append (message, &iter);
2701 + dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &ssid);
2703 + connection = dbus_bus_get (DBUS_BUS_SYSTEM, NULL);
2704 + dbus_connection_send (connection, message, NULL);
2705 + dbus_connection_unref (connection);
2706 + dbus_message_unref (message);
2710 +ck_seat_request_close_session (CkSeat *seat,
2711 + CkSession *session,
2716 + g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
2717 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
2718 + g_return_val_if_fail (ck_seat_is_managed (seat), FALSE);
2720 + g_debug ("CkSeat: Request close session.");
2721 + ck_session_get_id (session, &ssid, NULL);
2723 + emit_session_close_request (seat, ssid);
2731 +ck_seat_no_respawn (CkSeat *seat,
2732 + CkSession *session,
2735 + DBusMessage *message;
2736 + DBusConnection *connection;
2737 + DBusMessageIter iter;
2740 + g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
2741 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
2742 + g_return_val_if_fail (ck_seat_is_managed (seat), FALSE);
2744 + g_debug ("CkSeat: No Respawn.");
2745 + ck_session_get_id (session, &ssid, NULL);
2747 + message = dbus_message_new_signal (seat->priv->id,
2748 + "org.freedesktop.ConsoleKit.Seat",
2751 + dbus_message_set_destination (message,
2752 + dbus_g_proxy_get_bus_name (seat->priv->manager_proxy));
2754 + dbus_message_iter_init_append (message, &iter);
2755 + dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &ssid);
2757 + connection = dbus_bus_get (DBUS_BUS_SYSTEM, NULL);
2758 + dbus_connection_send (connection, message, NULL);
2759 + dbus_connection_unref (connection);
2760 + dbus_message_unref (message);
2768 ck_seat_add_session (CkSeat *seat,
2773 + GHashTableIter iter;
2774 + gpointer key, value;
2777 g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
2779 + g_debug ("CkSeat: Add session.");
2780 ck_session_get_id (session, &ssid, NULL);
2782 - g_hash_table_insert (seat->priv->sessions, g_strdup (ssid), g_object_ref (session));
2784 + g_hash_table_iter_init (&iter, seat->priv->sessions);
2785 + while (g_hash_table_iter_next (&iter, &key, &value)) {
2786 + if (g_str_equal ((gchar *)key, ssid)) {
2793 + g_hash_table_insert (seat->priv->sessions, g_strdup (ssid), g_object_ref (session));
2795 + g_object_ref (session);
2797 ck_session_set_seat_id (session, seat->priv->id, NULL);
2799 @@ -655,6 +1217,10 @@ ck_seat_add_session (CkSeat *sea
2801 maybe_update_active_session (seat);
2803 + if (ck_seat_is_managed (seat)) {
2804 + ck_seat_request_open_session (seat, session, NULL);
2810 @@ -741,6 +1307,20 @@ ck_seat_get_kind (CkSeat *seat,
2814 +ck_seat_get_type_string (CkSeat *seat,
2818 + g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
2820 + if (type != NULL) {
2821 + *type = g_strdup (seat->priv->type);
2828 ck_seat_get_id (CkSeat *seat,
2831 @@ -772,6 +1352,7 @@ ck_seat_register (CkSeat *seat)
2832 g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
2835 + g_debug ("CkSeat: Register seat.");
2836 seat->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
2837 if (seat->priv->connection == NULL) {
2838 if (error != NULL) {
2839 @@ -859,6 +1440,14 @@ _ck_seat_set_kind (CkSeat *seat,
2843 +_ck_seat_set_type_string (CkSeat *seat,
2846 + g_free (seat->priv->type);
2847 + seat->priv->type = g_strdup (type);
2851 ck_seat_set_property (GObject *object,
2853 const GValue *value,
2854 @@ -875,6 +1464,9 @@ ck_seat_set_property (GObject
2856 _ck_seat_set_kind (self, g_value_get_enum (value));
2859 + _ck_seat_set_type_string (self, g_value_get_string (value));
2862 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2864 @@ -896,7 +1488,10 @@ ck_seat_get_property (GObject *object
2865 g_value_set_string (value, self->priv->id);
2868 - g_value_set_string (value, self->priv->id);
2869 + g_value_set_enum (value, self->priv->kind);
2872 + g_value_set_string (value, self->priv->type);
2875 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2876 @@ -1008,6 +1603,48 @@ ck_seat_class_init (CkSeatClass *klass)
2877 g_cclosure_marshal_VOID__BOXED,
2880 + signals [REMOVE_REQUEST] = g_signal_new ("remove-request",
2881 + G_TYPE_FROM_CLASS (object_class),
2882 + G_SIGNAL_RUN_LAST,
2883 + G_STRUCT_OFFSET (CkSeatClass, remove_request),
2886 + g_cclosure_marshal_VOID__VOID,
2888 + signals [OPEN_SESSION_REQUEST] = g_signal_new ("open-session-request",
2889 + G_TYPE_FROM_CLASS (object_class),
2890 + G_SIGNAL_RUN_LAST,
2891 + G_STRUCT_OFFSET (CkSeatClass, open_session_request),
2894 + ck_marshal_VOID__STRING_STRING_STRING_POINTER_STRING_POINTER,
2897 + DBUS_TYPE_G_OBJECT_PATH,
2900 + CK_DBUS_TYPE_G_STRING_STRING_HASHTABLE,
2902 + CK_DBUS_TYPE_G_STRING_STRING_HASHTABLE,
2904 + signals [CLOSE_SESSION_REQUEST] = g_signal_new ("close-session-request",
2905 + G_TYPE_FROM_CLASS (object_class),
2906 + G_SIGNAL_RUN_LAST,
2907 + G_STRUCT_OFFSET (CkSeatClass, close_session_request),
2910 + g_cclosure_marshal_VOID__VOID,
2912 + 1, DBUS_TYPE_G_OBJECT_PATH);
2913 + signals [NO_RESPAWN] = g_signal_new ("no-respawn",
2914 + G_TYPE_FROM_CLASS (object_class),
2915 + G_SIGNAL_RUN_LAST,
2916 + G_STRUCT_OFFSET (CkSeatClass, no_respawn),
2919 + g_cclosure_marshal_VOID__VOID,
2923 g_object_class_install_property (object_class,
2925 @@ -1025,6 +1662,13 @@ ck_seat_class_init (CkSeatClass *klass)
2926 CK_SEAT_KIND_DYNAMIC,
2927 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2929 + g_object_class_install_property (object_class,
2931 + g_param_spec_string ("type",
2935 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
2936 g_type_class_add_private (klass, sizeof (CkSeatPrivate));
2938 dbus_g_object_type_install_info (CK_TYPE_SEAT, &dbus_glib_ck_seat_object_info);
2939 @@ -1040,6 +1684,7 @@ ck_seat_init (CkSeat *seat)
2941 (GDestroyNotify) g_object_unref);
2942 seat->priv->devices = g_ptr_array_new ();
2943 + seat->priv->manager_proxy = NULL;
2947 @@ -1065,28 +1710,32 @@ ck_seat_finalize (GObject *object)
2948 g_ptr_array_free (seat->priv->devices, TRUE);
2949 g_hash_table_destroy (seat->priv->sessions);
2950 g_free (seat->priv->id);
2951 + g_free (seat->priv->type);
2953 G_OBJECT_CLASS (ck_seat_parent_class)->finalize (object);
2957 ck_seat_new (const char *sid,
2964 object = g_object_new (CK_TYPE_SEAT,
2970 return CK_SEAT (object);
2974 -ck_seat_new_with_devices (const char *sid,
2976 - GPtrArray *devices)
2977 +ck_seat_new_with_devices_and_sessions (const char *sid,
2979 + GPtrArray *devices,
2980 + GPtrArray *sessions)
2984 @@ -1101,27 +1750,62 @@ ck_seat_new_with_devices (const char *si
2985 ck_seat_add_device (CK_SEAT (object), g_ptr_array_index (devices, i), NULL);
2988 + if (sessions != NULL) {
2989 + for (i = 0; i < sessions->len; i++) {
2990 + ck_seat_add_session (CK_SEAT (object), g_ptr_array_index (sessions, i), NULL);
2995 return CK_SEAT (object);
2999 +generate_static_session_id (const char *sid,
3000 + const char *session_name)
3002 + const char *seat_name;
3005 + seat_name = strrchr (sid, '/');
3007 + if (seat_name == NULL) {
3008 + g_warning ("Seat id '%s' lacks a /", sid);
3014 + ssid = g_strdup_printf ("%s/Session%s%s",
3015 + CK_DBUS_PATH, seat_name,
3022 -ck_seat_new_from_file (const char *sid,
3023 +ck_seat_new_from_file (char **sid,
3026 - GKeyFile *key_file;
3032 - GPtrArray *devices;
3033 - char **device_list;
3036 + GKeyFile *key_file;
3043 + GPtrArray *sessions;
3044 + char **session_list;
3046 + GPtrArray *devices;
3047 + char **device_list;
3053 + g_debug ("CkSeat: New seat from file.");
3055 key_file = g_key_file_new ();
3057 res = g_key_file_load_from_file (key_file,
3058 @@ -1146,9 +1830,52 @@ ck_seat_new_from_file (const char *sid,
3062 + read_sid = g_key_file_get_string (key_file, group, "ID", NULL);
3063 + if (IS_STR_SET (read_sid)) {
3065 + *sid = g_strdup_printf ("%s/%s", CK_DBUS_PATH, read_sid);
3067 + g_free (read_sid);
3070 + session_list = g_key_file_get_string_list (key_file, group, "Sessions", &nsessions, NULL);
3072 + sessions = g_ptr_array_sized_new (nsessions);
3074 + for (i = 0; i < nsessions; i++) {
3078 + CkSession *session;
3080 + file = g_strconcat (session_list[i], ".session", NULL);
3081 + path = g_build_filename (CK_SESSION_DIR, file, NULL);
3084 + /* FIXME: we should probably use the same naming pool as
3085 + * sessions generated from ck-manager. We mangle the name
3086 + * here so we don't clash with names from ck-manager
3088 + ssid = generate_static_session_id (*sid, session_list[i]);
3090 + session = ck_session_new_from_file (ssid, path);
3092 + if (session == NULL) {
3093 + g_warning ("Unable to load session from file %s", path);
3098 + ck_session_set_seat_id (session, *sid, NULL);
3100 + g_ptr_array_add (sessions, session);
3103 + g_strfreev (session_list);
3105 device_list = g_key_file_get_string_list (key_file, group, "Devices", &ndevices, NULL);
3107 - g_debug ("Creating seat %s with %zd devices", sid, ndevices);
3108 + g_debug ("CkSeat: Creating seat %s with %zd devices", *sid, ndevices);
3110 devices = g_ptr_array_sized_new (ndevices);
3112 @@ -1177,11 +1904,12 @@ ck_seat_new_from_file (const char *sid,
3115 g_strfreev (device_list);
3118 - seat = ck_seat_new_with_devices (sid, CK_SEAT_KIND_STATIC, devices);
3119 + seat = ck_seat_new_with_devices_and_sessions (*sid, CK_SEAT_KIND_STATIC, devices, sessions);
3120 g_ptr_array_free (devices, TRUE);
3126 g_key_file_free (key_file);
3127 @@ -1356,10 +2084,15 @@ ck_seat_dump (CkSeat *seat,
3130 if (! ck_session_get_id (seat->priv->active_session, &session_id, &error)) {
3131 - g_warning ("Cannot get session id for active session on seat %s: %s",
3134 - g_error_free (error);
3136 + g_warning ("Cannot get session id for active session on seat %s: %s",
3139 + g_error_free (error);
3141 + g_warning ("Cannot get session id for active session on seat %s",
3145 g_key_file_set_string (key_file,
3147 @@ -1371,3 +2104,24 @@ ck_seat_dump (CkSeat *seat,
3149 g_free (group_name);
3153 +ck_seat_is_managed (CkSeat *seat)
3155 + return seat->priv->manager_proxy != NULL;
3159 +ck_seat_get_session (CkSeat *seat,
3162 + CkSession *session;
3164 + session = g_hash_table_lookup (seat->priv->sessions, ssid);
3166 + if (session == NULL) {
3170 + return g_object_ref (session);
3172 diff --git a/src/ck-seat.h b/src/ck-seat.h
3173 index fb9a955..6276021 100644
3176 @@ -47,6 +47,18 @@ typedef struct
3178 GObjectClass parent_class;
3180 + void (* remove_request) (CkSeat *seat);
3181 + void (* open_session_request) (CkSeat *seat,
3183 + const char *session_type,
3184 + const char *display_template_name,
3185 + GHashTable *display_variables,
3186 + const char *display_type,
3187 + GHashTable *parameters);
3188 + void (* close_session_request) (CkSeat *seat,
3189 + const char *ssid);
3190 + void (* no_respawn) (CkSeat *seat,
3191 + const char *ssid);
3192 void (* active_session_changed) (CkSeat *seat,
3194 void (* session_added) (CkSeat *seat,
3195 @@ -57,6 +69,11 @@ typedef struct
3196 GValueArray *device);
3197 void (* device_removed) (CkSeat *seat,
3198 GValueArray *device);
3199 + void (* session_to_add) (CkSeat *seat,
3200 + gboolean is_dynamic,
3201 + const char *command);
3202 + void (* session_to_remove) (CkSeat *seat,
3203 + int display_number);
3207 @@ -84,12 +101,14 @@ typedef enum
3208 GQuark ck_seat_error_quark (void);
3209 GType ck_seat_get_type (void);
3210 CkSeat * ck_seat_new (const char *sid,
3212 -CkSeat * ck_seat_new_from_file (const char *sid,
3213 - const char *path);
3214 -CkSeat * ck_seat_new_with_devices (const char *sid,
3216 - GPtrArray *devices);
3217 + const char *type);
3218 +CkSeat * ck_seat_new_from_file (char **sid,
3219 + const char *path);
3220 +CkSeat * ck_seat_new_with_devices_and_sessions (const char *sid,
3222 + GPtrArray *devices,
3223 + GPtrArray *sessions);
3225 gboolean ck_seat_register (CkSeat *seat);
3227 @@ -104,18 +123,31 @@ void ck_seat_dump
3228 gboolean ck_seat_get_kind (CkSeat *seat,
3231 +gboolean ck_seat_get_type_string (CkSeat *seat,
3234 gboolean ck_seat_add_session (CkSeat *seat,
3237 gboolean ck_seat_remove_session (CkSeat *seat,
3240 +gboolean ck_seat_request_open_session (CkSeat *seat,
3241 + CkSession *session,
3243 +gboolean ck_seat_request_close_session (CkSeat *seat,
3244 + CkSession *session,
3246 gboolean ck_seat_add_device (CkSeat *seat,
3247 GValueArray *device,
3249 gboolean ck_seat_remove_device (CkSeat *seat,
3250 GValueArray *device,
3252 +gboolean ck_seat_is_managed (CkSeat *seat);
3253 +CkSession *ck_seat_get_session (CkSeat *seat,
3254 + const char *ssid);
3255 +void ck_seat_request_removal (CkSeat *seat);
3257 /* exported methods */
3258 gboolean ck_seat_get_id (CkSeat *seat,
3259 @@ -137,6 +169,14 @@ gboolean ck_seat_can_activate
3260 gboolean ck_seat_activate_session (CkSeat *seat,
3262 DBusGMethodInvocation *context);
3263 +gboolean ck_seat_manage (CkSeat *seat,
3264 + DBusGMethodInvocation *context);
3265 +gboolean ck_seat_unmanage (CkSeat *seat,
3266 + DBusGMethodInvocation *context);
3268 +gboolean ck_seat_no_respawn (CkSeat *seat,
3269 + CkSession *session,
3274 diff --git a/src/ck-session-leader.c b/src/ck-session-leader.c
3275 index 3702602..908d2bb 100644
3276 --- a/src/ck-session-leader.c
3277 +++ b/src/ck-session-leader.c
3278 @@ -238,6 +238,7 @@ static struct {
3279 { "x11-display", add_param_string },
3280 { "remote-host-name", add_param_string },
3281 { "session-type", add_param_string },
3282 + { "display-type", add_param_string },
3283 { "is-local", add_param_boolean },
3284 { "unix-user", add_param_int },
3286 diff --git a/src/ck-session.c b/src/ck-session.c
3287 index d8db9dd..0354dd5 100644
3288 --- a/src/ck-session.c
3289 +++ b/src/ck-session.c
3291 #include "ck-session-glue.h"
3292 #include "ck-marshal.h"
3293 #include "ck-run-programs.h"
3294 +#include "ck-display-template.h"
3296 #define CK_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CK_TYPE_SESSION, CkSessionPrivate))
3298 @@ -57,6 +58,7 @@ struct CkSessionPrivate
3302 + char *display_type;
3303 char *login_session_id;
3304 char *display_device;
3305 char *x11_display_device;
3306 @@ -64,8 +66,15 @@ struct CkSessionPrivate
3307 char *remote_host_name;
3310 + CkDisplayTemplate *display_template;
3311 + GHashTable *display_variables;
3316 + gboolean ever_open;
3317 + gboolean under_request;
3318 + GMutex *mutex_under_request;
3320 GTimeVal creation_time;
3322 @@ -74,6 +83,8 @@ struct CkSessionPrivate
3324 GTimeVal idle_since_hint;
3326 + gboolean remove_on_close;
3328 DBusGConnection *connection;
3329 DBusGProxy *bus_proxy;
3331 @@ -91,17 +102,24 @@ enum {
3339 PROP_X11_DISPLAY_DEVICE,
3340 PROP_DISPLAY_DEVICE,
3342 + PROP_DISPLAY_TYPE,
3343 + PROP_DISPLAY_TEMPLATE,
3344 + PROP_DISPLAY_VARIABLES,
3345 PROP_REMOTE_HOST_NAME,
3346 PROP_LOGIN_SESSION_ID,
3352 + PROP_REMOVE_ON_CLOSE,
3355 static guint signals [LAST_SIGNAL] = { 0, };
3356 @@ -127,7 +145,9 @@ static gboolean
3357 register_session (CkSession *session)
3359 GError *error = NULL;
3360 + GObject *existing_session;
3362 + g_debug ("CkSession: Register session.");
3364 session->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
3365 if (session->priv->connection == NULL) {
3366 @@ -143,6 +163,15 @@ register_session (CkSession *session)
3368 DBUS_INTERFACE_DBUS);
3370 + existing_session = dbus_g_connection_lookup_g_object (session->priv->connection,
3371 + session->priv->id);
3373 + if (existing_session != NULL) {
3374 + g_warning ("Session '%s' was registered twice!",
3375 + session->priv->id);
3379 dbus_g_connection_register_g_object (session->priv->connection, session->priv->id, G_OBJECT (session));
3382 @@ -301,6 +330,40 @@ ck_session_set_idle_hint (CkSession
3386 +session_set_remove_on_close (CkSession *session,
3387 + gboolean remove_on_close,
3390 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3392 + if (session->priv->remove_on_close != remove_on_close) {
3393 + session->priv->remove_on_close = remove_on_close;
3396 + if (session->priv->remove_on_close == TRUE)
3397 + g_debug ("CkSession: Setting remove on close to true.");
3399 + g_debug ("CkSession: Setting remove on close to false.");
3406 + dbus-send --system --dest=org.freedesktop.ConsoleKit \
3407 + --type=method_call --print-reply --reply-timeout=2000 \
3408 + /org/freedesktop/ConsoleKit/Session1 \
3409 + org.freedesktop.ConsoleKit.Session.SetRemoveOnClose boolean:TRUE
3412 +ck_session_set_remove_on_close (CkSession *session,
3413 + gboolean remove_on_close,
3414 + DBusGMethodInvocation *context)
3416 + return session_set_remove_on_close (session, remove_on_close, NULL);
3420 ck_session_get_idle_hint (CkSession *session,
3421 gboolean *idle_hint,
3423 @@ -366,6 +429,7 @@ ck_session_activate (CkSession
3427 + g_debug ("CkSession: Session activate.");
3428 g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3431 @@ -396,6 +460,8 @@ ck_session_set_active (CkSession *s
3433 g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3435 + g_debug ("CkSession: Session set active.");
3437 if (session->priv->active != active) {
3438 session->priv->active = active;
3439 g_signal_emit (session, signals [ACTIVE_CHANGED], 0, active);
3440 @@ -419,6 +485,68 @@ ck_session_set_is_local (CkSession
3444 +ck_session_set_is_open (CkSession *session,
3448 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3450 + if (session->priv->is_open != is_open) {
3451 + session->priv->is_open = is_open;
3452 + session->priv->ever_open = TRUE;
3459 +ck_session_set_ever_open (CkSession *session,
3460 + gboolean ever_open,
3463 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3465 + if (session->priv->ever_open != ever_open) {
3466 + session->priv->ever_open = ever_open;
3473 +timeout_for_under_request (gpointer data)
3475 + CkSession *session = CK_SESSION (data);
3476 + g_mutex_lock (session->priv->mutex_under_request);
3477 + session->priv->under_request = FALSE;
3478 + g_mutex_unlock (session->priv->mutex_under_request);
3480 + g_debug ("CkSession: timeout for under request of session %s", session->priv->id);
3485 +ck_session_set_under_request (CkSession *session,
3486 + gboolean under_request,
3489 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3491 + g_mutex_lock (session->priv->mutex_under_request);
3492 + if (!under_request) {
3493 + session->priv->under_request = FALSE;
3495 + if (!session->priv->under_request) {
3496 + session->priv->under_request = TRUE;
3497 + g_timeout_add_seconds (1, timeout_for_under_request, session);
3500 + g_mutex_unlock (session->priv->mutex_under_request);
3506 ck_session_get_id (CkSession *session,
3509 @@ -554,6 +682,20 @@ ck_session_get_creation_time (CkSession
3513 +ck_session_get_remove_on_close (CkSession *session,
3514 + gboolean *remove_on_close,
3517 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3519 + if (remove_on_close != NULL) {
3520 + *remove_on_close = session->priv->remove_on_close;
3527 ck_session_get_session_type (CkSession *session,
3530 @@ -568,6 +710,20 @@ ck_session_get_session_type (CkSession
3534 +ck_session_get_display_type (CkSession *session,
3538 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3540 + if (type != NULL) {
3541 + *type = g_strdup (session->priv->display_type);
3548 ck_session_is_active (CkSession *session,
3551 @@ -596,6 +752,50 @@ ck_session_is_local (CkSession *ses
3555 +ck_session_is_open (CkSession *session,
3559 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3561 + if (open != NULL) {
3562 + *open = session->priv->is_open;
3569 +ck_session_get_ever_open (CkSession *session,
3573 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3575 + if (open != NULL) {
3576 + *open = session->priv->ever_open;
3583 +ck_session_get_under_request (CkSession *session,
3584 + gboolean *under_request,
3587 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3589 + if (under_request != NULL) {
3590 + g_mutex_lock (session->priv->mutex_under_request);
3591 + *under_request = session->priv->under_request;
3592 + g_mutex_unlock (session->priv->mutex_under_request);
3599 ck_session_set_id (CkSession *session,
3602 @@ -608,6 +808,21 @@ ck_session_set_id (CkSession *sessi
3607 +ck_session_set_display_variables (CkSession *session,
3608 + GHashTable *display_variables)
3610 + if (session->priv->display_variables != NULL) {
3611 + g_hash_table_unref (session->priv->display_variables);
3614 + if (display_variables != NULL) {
3615 + session->priv->display_variables = g_hash_table_ref (display_variables);
3617 + session->priv->display_variables = NULL;
3622 ck_session_set_cookie (CkSession *session,
3624 @@ -724,6 +939,54 @@ ck_session_set_session_type (CkSession
3629 +ck_session_set_display_type (CkSession *session,
3633 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3635 + g_free (session->priv->display_type);
3636 + session->priv->display_type = g_strdup (type);
3642 +ck_session_set_display_template (CkSession *session,
3643 + CkDisplayTemplate *display_template,
3646 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3648 + if (session->priv->display_template != NULL) {
3649 + g_object_unref (session->priv->display_template);
3652 + if (display_template != NULL) {
3653 + session->priv->display_template = g_object_ref (display_template);
3654 + ck_session_set_display_type (session, ck_display_template_get_name (display_template), error);
3656 + session->priv->display_template = NULL;
3663 +ck_session_get_display_variables (CkSession *session)
3665 + return g_hash_table_ref (session->priv->display_variables);
3668 +CkDisplayTemplate *
3669 +ck_session_get_display_template (CkSession *session)
3671 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3673 + return g_object_ref (session->priv->display_template);
3677 ck_session_set_property (GObject *object,
3679 @@ -741,15 +1004,33 @@ ck_session_set_property (GObject
3681 ck_session_set_is_local (self, g_value_get_boolean (value), NULL);
3683 + case PROP_IS_OPEN:
3684 + ck_session_set_is_open (self, g_value_get_boolean (value), NULL);
3686 + case PROP_EVER_OPEN:
3687 + ck_session_set_ever_open (self, g_value_get_boolean (value), NULL);
3690 ck_session_set_id (self, g_value_get_string (value), NULL);
3693 ck_session_set_cookie (self, g_value_get_string (value), NULL);
3695 + case PROP_SEAT_ID:
3696 + ck_session_set_seat_id (self, g_value_get_string (value), NULL);
3698 case PROP_SESSION_TYPE:
3699 ck_session_set_session_type (self, g_value_get_string (value), NULL);
3701 + case PROP_DISPLAY_TYPE:
3702 + ck_session_set_display_type (self, g_value_get_string (value), NULL);
3704 + case PROP_DISPLAY_TEMPLATE:
3705 + ck_session_set_display_template (self, g_value_get_object (value), NULL);
3707 + case PROP_DISPLAY_VARIABLES:
3708 + ck_session_set_display_variables (self, g_value_get_boxed (value));
3710 case PROP_X11_DISPLAY:
3711 ck_session_set_x11_display (self, g_value_get_string (value), NULL);
3713 @@ -774,6 +1055,9 @@ ck_session_set_property (GObject
3714 case PROP_IDLE_HINT:
3715 session_set_idle_hint_internal (self, g_value_get_boolean (value));
3717 + case PROP_REMOVE_ON_CLOSE:
3718 + session_set_remove_on_close (self, g_value_get_boolean (value), NULL);
3721 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3723 @@ -797,15 +1081,33 @@ ck_session_get_property (GObject *obj
3725 g_value_set_boolean (value, self->priv->is_local);
3727 + case PROP_IS_OPEN:
3728 + g_value_set_boolean (value, self->priv->is_open);
3730 + case PROP_EVER_OPEN:
3731 + g_value_set_boolean (value, self->priv->ever_open);
3734 g_value_set_string (value, self->priv->id);
3737 g_value_set_string (value, self->priv->cookie);
3739 + case PROP_SEAT_ID:
3740 + g_value_set_string (value, self->priv->seat_id);
3742 case PROP_SESSION_TYPE:
3743 g_value_set_string (value, self->priv->session_type);
3745 + case PROP_DISPLAY_TYPE:
3746 + g_value_set_string (value, self->priv->display_type);
3748 + case PROP_DISPLAY_TEMPLATE:
3749 + g_value_set_object (value, self->priv->display_template);
3751 + case PROP_DISPLAY_VARIABLES:
3752 + g_value_set_boxed (value, self->priv->display_variables);
3754 case PROP_X11_DISPLAY:
3755 g_value_set_string (value, self->priv->x11_display);
3757 @@ -830,6 +1132,9 @@ ck_session_get_property (GObject *obj
3758 case PROP_IDLE_HINT:
3759 g_value_set_boolean (value, self->priv->idle_hint);
3761 + case PROP_REMOVE_ON_CLOSE:
3762 + g_value_set_boolean (value, self->priv->remove_on_close);
3765 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3767 @@ -881,6 +1186,8 @@ session_add_activity_watch (CkSession *s
3769 session_remove_activity_watch (CkSession *session)
3771 + g_debug ("CkSession: Remove activity watch.");
3773 if (session->priv->idle_monitor == NULL) {
3776 @@ -999,6 +1306,13 @@ ck_session_class_init (CkSessionClass *k
3779 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
3780 + g_object_class_install_property (object_class,
3782 + g_param_spec_string ("seat-id",
3786 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
3788 g_object_class_install_property (object_class,
3790 @@ -1008,6 +1322,27 @@ ck_session_class_init (CkSessionClass *k
3792 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
3793 g_object_class_install_property (object_class,
3794 + PROP_DISPLAY_TYPE,
3795 + g_param_spec_string ("display-type",
3799 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
3800 + g_object_class_install_property (object_class,
3801 + PROP_DISPLAY_TEMPLATE,
3802 + g_param_spec_object ("display-template",
3803 + "Display Template",
3804 + "The display template",
3805 + CK_TYPE_DISPLAY_TEMPLATE,
3806 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
3807 + g_object_class_install_property (object_class,
3808 + PROP_DISPLAY_VARIABLES,
3809 + g_param_spec_boxed ("display-variables",
3810 + "Display Variables",
3811 + "Display type specific variables",
3812 + G_TYPE_HASH_TABLE,
3813 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
3814 + g_object_class_install_property (object_class,
3815 PROP_LOGIN_SESSION_ID,
3816 g_param_spec_string ("login-session-id",
3818 @@ -1070,6 +1405,14 @@ ck_session_class_init (CkSessionClass *k
3820 G_PARAM_READWRITE));
3822 + g_object_class_install_property (object_class,
3823 + PROP_REMOVE_ON_CLOSE,
3824 + g_param_spec_boolean ("remove-on-close",
3828 + G_PARAM_READWRITE));
3830 g_type_class_add_private (klass, sizeof (CkSessionPrivate));
3832 dbus_g_object_type_install_info (CK_TYPE_SESSION, &dbus_glib_ck_session_object_info);
3833 @@ -1080,8 +1423,16 @@ ck_session_init (CkSession *session)
3835 session->priv = CK_SESSION_GET_PRIVATE (session);
3837 + session->priv->display_variables = g_hash_table_new_full (g_str_hash,
3839 + (GDestroyNotify) g_free,
3840 + (GDestroyNotify) g_free);
3842 /* FIXME: should we have a property for this? */
3843 g_get_current_time (&session->priv->creation_time);
3845 + if (!session->priv->mutex_under_request)
3846 + session->priv->mutex_under_request = g_mutex_new ();
3850 @@ -1104,6 +1455,7 @@ ck_session_finalize (GObject *object)
3851 g_free (session->priv->cookie);
3852 g_free (session->priv->seat_id);
3853 g_free (session->priv->session_type);
3854 + g_free (session->priv->display_type);
3855 g_free (session->priv->login_session_id);
3856 g_free (session->priv->display_device);
3857 g_free (session->priv->x11_display_device);
3858 @@ -1114,16 +1466,138 @@ ck_session_finalize (GObject *object)
3862 +ck_session_new_from_file (const char *ssid,
3865 + GKeyFile *key_file;
3872 + char *display_template_string;
3873 + CkSession *session;
3874 + GHashTable *display_variables;
3877 + g_debug ("CkSession: New session from file.");
3878 + key_file = g_key_file_new ();
3880 + res = g_key_file_load_from_file (key_file,
3886 + g_warning ("Unable to load sessions from file %s: %s",
3887 + path, error->message);
3888 + g_error_free (error);
3892 + group = g_key_file_get_start_group (key_file);
3893 + if (group == NULL || strcmp (group, "Session Entry") != 0) {
3894 + g_warning ("Not a session file: %s", path);
3895 + g_key_file_free (key_file);
3899 + hidden = g_key_file_get_boolean (key_file, group, "Hidden", NULL);
3902 + g_debug ("CkSession: Session is hidden");
3904 + g_key_file_free (key_file);
3908 + name = g_key_file_get_string (key_file, group, "Name", NULL);
3910 + if (name == NULL) {
3911 + g_warning ("Session file %s doesn't contain a name", path);
3913 + g_key_file_free (key_file);
3917 + type = g_key_file_get_string (key_file, group, "Type", NULL);
3919 + if (type == NULL) {
3920 + g_warning ("Session file %s doesn't contain a type", path);
3922 + g_key_file_free (key_file);
3926 + display_template_string = g_key_file_get_string (key_file, group, "DisplayTemplate", NULL);
3928 + if (display_template_string == NULL) {
3929 + g_warning ("Session file %s doesn't contain a display type", path);
3931 + g_key_file_free (key_file);
3935 + /* Find a group in the key file named after the display type and stuff
3936 + * all its entries into a hash table for later.
3938 + * Those keys are for things like the display number and the vt to
3941 + display_variables = g_hash_table_new_full (g_str_hash, g_str_equal,
3942 + (GDestroyNotify) g_free,
3943 + (GDestroyNotify) g_free);
3944 + type_keys = g_key_file_get_keys (key_file, display_template_string, NULL, NULL);
3946 + if (type_keys != NULL) {
3948 + for (i = 0; type_keys[i] != NULL; i++) {
3950 + string = g_key_file_get_string (key_file, display_template_string, type_keys[i], NULL);
3952 + g_hash_table_insert (display_variables, g_strdup (type_keys[i]), string);
3954 + g_strfreev (type_keys);
3957 + session = ck_session_new (ssid, type, display_template_string, display_variables);
3959 + g_free (display_template_string);
3962 + g_hash_table_unref (display_variables);
3968 ck_session_new (const char *ssid,
3969 - const char *cookie)
3971 + const char *display_template_string,
3972 + GHashTable *display_variables)
3974 + CkDisplayTemplate *display_template;
3978 + g_debug ("CkSession: New Session.");
3980 + display_template = ck_display_template_get_from_name (display_template_string);
3982 + if (display_template == NULL) {
3983 + g_warning ("Unable to load display type %s", display_template_string);
3987 object = g_object_new (CK_TYPE_SESSION,
3990 + "session-type", type,
3991 + "display-type", display_template_string,
3992 + "display-template", display_template,
3993 + "display-variables", display_variables,
3996 res = register_session (CK_SESSION (object));
3998 g_object_unref (object);
3999 @@ -1138,9 +1612,80 @@ ck_session_new (const char *ssid,
4004 +ck_session_set_parameters (CkSession *session,
4005 + const GPtrArray *parameters)
4008 + GObjectClass *class;
4009 + GType object_type;
4011 + object_type = CK_TYPE_SESSION;
4012 + class = g_type_class_ref (object_type);
4013 + for (i = 0; i < parameters->len; i++) {
4015 + GValue val_struct = { 0, };
4016 + GValue value = { 0, };
4019 + GParamSpec *pspec;
4021 + g_value_init (&val_struct, CK_TYPE_PARAMETER_STRUCT);
4022 + g_value_set_static_boxed (&val_struct, g_ptr_array_index (parameters, i));
4024 + res = dbus_g_type_struct_get (&val_struct,
4029 + g_debug ("CkSession: Unable to extract parameter input");
4033 + if (prop_name == NULL) {
4034 + g_debug ("CkSession: Skipping NULL parameter");
4038 + if (strcmp (prop_name, "id") == 0
4039 + || strcmp (prop_name, "cookie") == 0) {
4040 + g_debug ("CkSession: Skipping restricted parameter: %s", prop_name);
4044 + pspec = g_object_class_find_property (class, prop_name);
4046 + g_debug ("CkSession: Skipping unknown parameter: %s", prop_name);
4050 + if (!(pspec->flags & G_PARAM_WRITABLE)) {
4051 + g_debug ("CkSession: property '%s' is not writable", pspec->name);
4055 + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
4056 + res = g_value_transform (prop_val, &value);
4058 + g_debug ("CkSession: unable to transform property value for '%s'", pspec->name);
4062 + g_object_set_property (G_OBJECT (session), prop_name, &value);
4063 + g_value_unset (&value);
4065 + g_free (prop_name);
4066 + if (prop_val != NULL) {
4067 + g_value_unset (prop_val);
4068 + g_free (prop_val);
4072 + g_type_class_unref (class);
4076 ck_session_new_with_parameters (const char *ssid,
4077 - const char *cookie,
4078 const GPtrArray *parameters)
4081 @@ -1152,6 +1697,8 @@ ck_session_new_with_parameters (const ch
4082 GObjectClass *class;
4085 + g_debug ("CkSession: New session with parameters");
4087 object_type = CK_TYPE_SESSION;
4088 class = g_type_class_ref (object_type);
4090 @@ -1169,12 +1716,6 @@ ck_session_new_with_parameters (const ch
4091 g_value_set_string (¶ms[n_params].value, ssid);
4094 - params[n_params].name = g_strdup ("cookie");
4095 - params[n_params].value.g_type = 0;
4096 - g_value_init (¶ms[n_params].value, G_TYPE_STRING);
4097 - g_value_set_string (¶ms[n_params].value, cookie);
4100 if (parameters != NULL) {
4101 for (i = 0; i < parameters->len; i++) {
4103 @@ -1259,7 +1800,7 @@ ck_session_run_programs (CkSession *ses
4107 - char *extra_env[11]; /* be sure to adjust this as needed */
4108 + char *extra_env[12]; /* be sure to adjust this as needed */
4112 @@ -1267,6 +1808,9 @@ ck_session_run_programs (CkSession *ses
4113 if (session->priv->session_type != NULL) {
4114 extra_env[n++] = g_strdup_printf ("CK_SESSION_TYPE=%s", session->priv->session_type);
4116 + if (session->priv->display_type != NULL) {
4117 + extra_env[n++] = g_strdup_printf ("CK_SESSION_DISPLAY_TYPE=%s", session->priv->display_type);
4119 extra_env[n++] = g_strdup_printf ("CK_SESSION_SEAT_ID=%s", session->priv->seat_id);
4120 extra_env[n++] = g_strdup_printf ("CK_SESSION_USER_UID=%d", session->priv->uid);
4121 if (session->priv->display_device != NULL && strlen (session->priv->display_device) > 0) {
4122 @@ -1301,6 +1845,10 @@ ck_session_dump (CkSession *session,
4126 + if (!session->priv->is_open) {
4130 group_name = g_strdup_printf ("Session %s", session->priv->id);
4131 g_key_file_set_integer (key_file, group_name, "uid", session->priv->uid);
4132 g_key_file_set_string (key_file,
4133 @@ -1313,6 +1861,12 @@ ck_session_dump (CkSession *session,
4135 NONULL_STRING (session->priv->session_type));
4137 + if (session->priv->display_type != NULL) {
4138 + g_key_file_set_string (key_file,
4141 + NONULL_STRING (session->priv->display_type));
4143 if (session->priv->login_session_id != NULL && strlen (session->priv->login_session_id) > 0) {
4144 g_key_file_set_string (key_file,
4146 diff --git a/src/ck-session.h b/src/ck-session.h
4147 index b6b565b..a24d0a8 100644
4148 --- a/src/ck-session.h
4149 +++ b/src/ck-session.h
4151 #include <glib-object.h>
4152 #include <dbus/dbus-glib.h>
4154 +#include "ck-display-template.h"
4158 #define CK_TYPE_SESSION (ck_session_get_type ())
4159 @@ -68,10 +70,15 @@ typedef enum
4161 GQuark ck_session_error_quark (void);
4162 GType ck_session_get_type (void);
4163 +CkSession * ck_session_new_from_file (const char *ssid,
4164 + const char *path);
4165 CkSession * ck_session_new (const char *ssid,
4166 - const char *cookie);
4168 + const char *display_type_string,
4169 + GHashTable *display_variables);
4170 CkSession * ck_session_new_with_parameters (const char *ssid,
4171 - const char *cookie,
4172 + const GPtrArray *parameters);
4173 +void ck_session_set_parameters (CkSession *session,
4174 const GPtrArray *parameters);
4176 void ck_session_dump (CkSession *session,
4177 @@ -86,6 +93,15 @@ gboolean ck_session_set_active (CkSession *se
4178 gboolean ck_session_set_is_local (CkSession *session,
4181 +gboolean ck_session_set_is_open (CkSession *session,
4184 +gboolean ck_session_set_ever_open (CkSession *session,
4185 + gboolean ever_open,
4187 +gboolean ck_session_set_under_request (CkSession *session,
4188 + gboolean under_request,
4190 gboolean ck_session_set_id (CkSession *session,
4193 @@ -116,6 +132,11 @@ gboolean ck_session_set_remote_host_name (CkSession *se
4194 gboolean ck_session_set_session_type (CkSession *session,
4197 +gboolean ck_session_set_display_type (CkSession *session,
4200 +GHashTable *ck_session_get_display_variables (CkSession *session);
4201 +CkDisplayTemplate *ck_session_get_display_template (CkSession *session);
4203 /* Exported methods */
4205 @@ -132,6 +153,15 @@ gboolean ck_session_is_active (CkSession *se
4206 gboolean ck_session_is_local (CkSession *session,
4209 +gboolean ck_session_is_open (CkSession *session,
4212 +gboolean ck_session_get_ever_open (CkSession *session,
4215 +gboolean ck_session_get_under_request (CkSession *session,
4216 + gboolean *under_request,
4218 gboolean ck_session_get_unix_user (CkSession *session,
4221 @@ -150,12 +180,18 @@ gboolean ck_session_get_login_session_id (CkSession *se
4222 gboolean ck_session_get_session_type (CkSession *session,
4225 +gboolean ck_session_get_display_type (CkSession *session,
4228 gboolean ck_session_get_remote_host_name (CkSession *session,
4231 gboolean ck_session_get_creation_time (CkSession *session,
4232 char **iso8601_datetime,
4234 +gboolean ck_session_get_remove_on_close (CkSession *session,
4235 + gboolean *remove_on_close,
4238 gboolean ck_session_get_user (CkSession *session,
4240 @@ -171,6 +207,12 @@ gboolean ck_session_get_idle_since_hint (CkSession *se
4241 gboolean ck_session_set_idle_hint (CkSession *session,
4243 DBusGMethodInvocation *context);
4244 +gboolean session_set_remove_on_close (CkSession *session,
4245 + gboolean remove_on_close,
4247 +gboolean ck_session_set_remove_on_close (CkSession *session,
4248 + gboolean remove_on_close,
4249 + DBusGMethodInvocation *context);
4251 /* Privileged actions */
4252 gboolean ck_session_activate (CkSession *session,
4253 diff --git a/src/main.c b/src/main.c
4254 index b8f698f..f685026 100644
4255 diff --git a/src/org.freedesktop.ConsoleKit.Manager.xml b/src/org.freedesktop.ConsoleKit.Manager.xml
4256 index f903b55..34a6d04 100644
4257 --- a/src/org.freedesktop.ConsoleKit.Manager.xml
4258 +++ b/src/org.freedesktop.ConsoleKit.Manager.xml
4259 @@ -160,6 +160,23 @@
4263 + <method name="GetUnmanagedSeats">
4264 + <arg name="seats" direction="out" type="ao">
4266 + <doc:summary>an array of unmanaged Seat IDs</doc:summary>
4271 + <doc:para>This gets a list of the unmanaged <doc:ref type="interface" to="Seat">Seats</doc:ref>
4272 + that are statically configured under /etc/ConsoleKit/seats.d</doc:para>
4273 + <doc:para>Each Seat ID is an D-Bus object path for the object that implements the
4274 + <doc:ref type="interface" to="Seat">Seat</doc:ref> interface.</doc:para>
4275 + </doc:description>
4276 + <doc:seealso><doc:ref type="interface" to="Seat">org.freedesktop.ConsoleKit.Seat</doc:ref></doc:seealso>
4280 <method name="GetSessions">
4281 <arg name="sessions" direction="out" type="ao">
4283 @@ -196,6 +213,22 @@
4288 + <method name="WillNotRespawn">
4289 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4290 + <arg name="ssid" type="o" direction="in">
4292 + <doc:summary>The session id of the session</doc:summary>
4297 + <doc:para>This may be used to set Remove On Close for a Session.
4299 + </doc:description>
4303 <method name="GetSessionForUnixProcess">
4304 <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4305 <arg name="pid" direction="in" type="u">
4306 @@ -310,12 +343,115 @@
4310 + <method name="AddSeat">
4311 + <arg name="type" type="s" direction="in">
4313 + <doc:summary>The type of seat to add</doc:summary>
4316 + <arg name="sid" type="o" direction="out">
4318 + <doc:summary>The Seat ID of the added seat</doc:summary>
4323 + <doc:para>This method is to create a new seat
4325 + </doc:description>
4328 + <method name="AddSeatById">
4329 + <arg name="type" type="s" direction="in">
4331 + <doc:summary>The type of seat to add</doc:summary>
4334 + <arg name="sid" type="o" direction="in">
4336 + <doc:summary>The Seat ID of to be added seat</doc:summary>
4341 + <doc:para>This method is to create a new seat by specify given sid
4343 + </doc:description>
4346 + <method name="RemoveSeat">
4347 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4348 + <arg name="sid" type="o" direction="in">
4350 + <doc:summary>The Seat ID of the seat to remove</doc:summary>
4355 + <doc:para>This method is to remove a seat
4357 + </doc:description>
4360 + <method name="AddSession">
4361 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4362 + <arg name="sid" type="o">
4364 + <doc:summary>The seat to add the session to</doc:summary>
4367 + <arg name="type" type="s">
4369 + <doc:summary>The type of session to run (e.g. "LoginWindow", "Chooser", etc)</doc:summary>
4372 + <arg name="display_type" type="s">
4374 + <doc:summary>The name of the display type to use (defined in displays.d)</doc:summary>
4377 + <arg name="variables" type="a{ss}">
4379 + <doc:summary>Session type specific parameters</doc:summary>
4382 + <arg name="ssid" direction="out" type="o">
4384 + <doc:summary>Session ID</doc:summary>
4389 + <doc:para>Request a new session gets added to seat.</doc:para>
4390 + </doc:description>
4393 + <method name="RemoveSession">
4394 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4395 + <arg name="ssid" type="o" direction="in">
4397 + <doc:summary>The session id of the session to remove</doc:summary>
4402 + <doc:para>This method is to remove a session from a seat
4404 + </doc:description>
4408 <signal name="SeatAdded">
4409 <arg name="sid" type="o">
4411 <doc:summary>The Seat ID for the added seat</doc:summary>
4414 + <arg name="type" type="s">
4416 + <doc:summary>The type of seat added.</doc:summary>
4421 <doc:para>Emitted when a Seat has been added to the system.
4422 diff --git a/src/org.freedesktop.ConsoleKit.Seat.xml b/src/org.freedesktop.ConsoleKit.Seat.xml
4423 index d95990b..1f6c46f 100644
4424 --- a/src/org.freedesktop.ConsoleKit.Seat.xml
4425 +++ b/src/org.freedesktop.ConsoleKit.Seat.xml
4426 @@ -100,6 +100,24 @@ seat at a time.</doc:para>
4430 + <method name="Manage">
4431 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4434 + <doc:para>Attempt to create unmanaged sessions for this seat.</doc:para>
4435 + </doc:description>
4439 + <method name="Unmanage">
4440 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4443 + <doc:para>Stop managing seat.</doc:para>
4444 + </doc:description>
4448 <signal name="ActiveSessionChanged">
4449 <arg name="ssid" type="o">
4451 @@ -160,5 +178,73 @@ seat at a time.</doc:para>
4455 + <signal name="OpenSessionRequest">
4456 + <arg name="ssid" type="o">
4458 + <doc:summary>The session id of the session to add</doc:summary>
4461 + <arg name="session_type" type="s">
4463 + <doc:summary>The type of session to run (e.g. "LoginWindow", "Chooser", etc)</doc:summary>
4466 + <arg name="display_template_name" type="s">
4468 + <doc:summary>The name of display template </doc:summary>
4471 + <arg name="parameters" type="a{ss}">
4473 + <doc:summary>Session type specific parameters</doc:summary>
4476 + <arg name="display_type" type="s">
4478 + <doc:summary>The type of display to use (e.g. "X11", "Command", "XDMCP", etc)</doc:summary>
4481 + <arg name="display_parameters" type="a{ss}">
4483 + <doc:summary>Display type specific parameters</doc:summary>
4488 + <doc:para>Emitted when a new session should get added to the seat.</doc:para>
4489 + </doc:description>
4492 + <signal name="CloseSessionRequest">
4493 + <arg name="ssid" type="o">
4495 + <doc:summary>The session id of the session to remove</doc:summary>
4500 + <doc:para>Emitted when a session with given display number need to be removed.</doc:para>
4501 + </doc:description>
4504 + <signal name="NoRespawn">
4505 + <arg name="ssid" type="o">
4507 + <doc:summary>The session id of the session to not respawn</doc:summary>
4512 + <doc:para>Emitted when ck-seat-tool indicates a session is to be removed.</doc:para>
4513 + </doc:description>
4516 + <signal name="RemoveRequest">
4519 + <doc:para>Emitted when seat needs to get removed.</doc:para>
4520 + </doc:description>
4525 diff --git a/src/org.freedesktop.ConsoleKit.Session.xml b/src/org.freedesktop.ConsoleKit.Session.xml
4526 index b6e1cdb..2652058 100644
4527 --- a/src/org.freedesktop.ConsoleKit.Session.xml
4528 +++ b/src/org.freedesktop.ConsoleKit.Session.xml
4530 <doc:seealso><doc:ref type="property" to="Session:session-type">session-type</doc:ref></doc:seealso>
4533 + <method name="GetDisplayType">
4534 + <arg name="type" direction="out" type="s">
4536 + <doc:summary>Display type</doc:summary>
4541 + <doc:para>Returns the display type of the session.</doc:para>
4542 + </doc:description>
4543 + <doc:seealso><doc:ref type="property" to="Session:display-type">display-type</doc:ref></doc:seealso>
4546 <method name="GetUser">
4547 <arg name="uid" direction="out" type="u">
4549 @@ -174,6 +187,18 @@
4550 <doc:seealso><doc:ref type="property" to="Session:is-local">is-local</doc:ref></doc:seealso>
4553 + <method name="IsOpen">
4554 + <arg name="open" direction="out" type="b">
4556 + <doc:summary>TRUE if the session is open, otherwise FALSE</doc:summary>
4560 + <doc:description><doc:para>Returns whether the session is open</doc:para>
4561 + </doc:description>
4562 + <doc:seealso><doc:ref type="property" to="Session:is-open">is-open</doc:ref></doc:seealso>
4565 <method name="GetCreationTime">
4566 <arg name="iso8601_datetime" type="s" direction="out">
4568 @@ -275,6 +300,21 @@
4572 + <method name="SetRemoveOnClose">
4573 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4574 + <arg name="remove_on_close" type="b" direction="in">
4576 + <doc:summary>boolean value to set the remove-on-close to</doc:summary>
4581 + <doc:para>This may be used by the session to indicate that
4582 + it should be respawn or not when it is closed.
4584 + </doc:description>
4588 <signal name="ActiveChanged">
4589 <arg name="is_active" type="b">
4590 @@ -317,6 +357,19 @@
4594 + <property name="session" type="o" access="readwrite">
4597 + <doc:para>The id of the session.</doc:para>
4599 + The object path of the session. Typically this is set by a session leader during a call to the
4600 + <doc:ref type="method" to="Manager.OpenSessionWithParameters">OpenSessionWithParameters</doc:ref> method, when
4601 + opening a session in response to the <doc:ref type="signal" to="Seat::OpenSessionRequest">OpenSessionRequest</doc:ref>
4604 + </doc:description>
4607 <property name="unix-user" type="u" access="readwrite">
4610 @@ -342,6 +395,16 @@
4614 + <property name="display-type" type="s" access="readwrite">
4617 + <doc:para>The display type of the session.</doc:para>
4618 + <doc:para>Indicate the display template name. All the display template configuration
4619 + files are under /etc/ConsoleKit/displays.d/.
4621 + </doc:description>
4624 <property name="remote-host-name" type="s" access="readwrite">
4627 @@ -396,6 +459,19 @@
4631 + <property name="is-open" type="b" access="readwrite">
4635 + Whether the session is open</doc:para>
4636 + <doc:para>Sessions added from static configuration or in direct response to a call to
4637 + the <doc:ref type="method" to="Manager.AddSession">AddSession</doc:ref> method are initialally
4638 + closed and aren't open until a call to the <doc:ref type="method" to="Manager.OpenSessionWithParameters">OpenSessionWithParameters</doc:ref>
4641 + </doc:description>
4644 <property name="is-local" type="b" access="readwrite">
4647 @@ -408,6 +484,14 @@
4651 + <property name="is-dynamic" type="b" access="readwrite">
4655 + Whether the session is dynamic</doc:para>
4656 + </doc:description>
4659 <property name="idle-hint" type="b" access="readwrite">
4662 @@ -430,6 +514,14 @@
4666 + <property name="remove-on-close" type="b" access="readwrite">
4670 + Whether the session respawn when it is closed</doc:para>
4671 + </doc:description>
4677 diff --git a/src/strverscmp.c b/src/strverscmp.c
4678 new file mode 100644
4679 index 0000000..f077651
4681 +++ b/src/strverscmp.c
4683 +/* Compare strings while treating digits characters numerically.
4684 + Copyright (C) 1997, 2000, 2002, 2004, 2006 Free Software Foundation, Inc.
4685 + This file is part of the GNU C Library.
4686 + Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
4688 + This program is free software; you can redistribute it and/or modify
4689 + it under the terms of the GNU General Public License as published by
4690 + the Free Software Foundation; either version 2, or (at your option)
4691 + any later version.
4693 + This program is distributed in the hope that it will be useful,
4694 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4695 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4696 + GNU General Public License for more details.
4698 + You should have received a copy of the GNU General Public License along
4699 + with this program; if not, write to the Free Software Foundation,
4700 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
4703 +# include <config.h>
4706 +#include <string.h>
4709 +/* states: S_N: normal, S_I: comparing integral part, S_F: comparing
4710 + fractional parts, S_Z: idem but with leading Zeroes only */
4716 +/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
4721 +/* ISDIGIT differs from isdigit, as follows:
4722 + - Its arg may be any int or unsigned int; it need not be an unsigned char
4724 + - It's typically faster.
4725 + POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
4726 + isdigit unless it's important to use the locale's definition
4727 + of `digit' even when the host does not conform to POSIX. */
4728 +#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
4730 +#undef __strverscmp
4734 +# define __strverscmp strverscmp
4737 +/* Compare S1 and S2 as strings holding indices/version numbers,
4738 + returning less than, equal to or greater than zero if S1 is less than,
4739 + equal to or greater than S2 (for more info, see the texinfo doc).
4743 +__strverscmp (const char *s1, const char *s2)
4745 + const unsigned char *p1 = (const unsigned char *) s1;
4746 + const unsigned char *p2 = (const unsigned char *) s2;
4747 + unsigned char c1, c2;
4751 + /* Symbol(s) 0 [1-9] others (padding)
4752 + Transition (10) 0 (01) d (00) x (11) - */
4753 + static const unsigned int next_state[] =
4755 + /* state x d 0 - */
4756 + /* S_N */ S_N, S_I, S_Z, S_N,
4757 + /* S_I */ S_N, S_I, S_I, S_I,
4758 + /* S_F */ S_N, S_F, S_F, S_F,
4759 + /* S_Z */ S_N, S_F, S_Z, S_Z
4762 + static const int result_type[] =
4764 + /* state x/x x/d x/0 x/- d/x d/d d/0 d/-
4765 + 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */
4767 + /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
4768 + CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
4769 + /* S_I */ CMP, -1, -1, CMP, 1, LEN, LEN, CMP,
4770 + 1, LEN, LEN, CMP, CMP, CMP, CMP, CMP,
4771 + /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
4772 + CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
4773 + /* S_Z */ CMP, 1, 1, CMP, -1, CMP, CMP, CMP,
4782 + /* Hint: '0' is a digit too. */
4783 + state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0));
4785 + while ((diff = c1 - c2) == 0 && c1 != '\0')
4787 + state = next_state[state];
4790 + state |= (c1 == '0') + (ISDIGIT (c1) != 0);
4793 + state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))];
4801 + while (ISDIGIT (*p1++))
4802 + if (!ISDIGIT (*p2++))
4805 + return ISDIGIT (*p2) ? -1 : diff;
4812 +weak_alias (__strverscmp, strverscmp)
4814 diff --git a/src/strverscmp.h b/src/strverscmp.h
4815 new file mode 100644
4816 index 0000000..48670c8
4818 +++ b/src/strverscmp.h
4820 +/* Compare strings while treating digits characters numerically.
4821 + Copyright (C) 1997, 2000, 2002, 2004, 2006 Free Software Foundation, Inc.
4822 + This file is part of the GNU C Library.
4823 + Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
4825 + This program is free software; you can redistribute it and/or modify
4826 + it under the terms of the GNU General Public License as published by
4827 + the Free Software Foundation; either version 2, or (at your option)
4828 + any later version.
4830 + This program is distributed in the hope that it will be useful,
4831 + but WITHOUT ANY WARRANTY; without even the implied warranty of
4832 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4833 + GNU General Public License for more details.
4835 + You should have received a copy of the GNU General Public License along
4836 + with this program; if not, write to the Free Software Foundation,
4837 + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
4839 +#ifndef STRVERSCMP_H_
4840 +# define STRVERSCMP_H_
4842 +int strverscmp (const char *, const char *);
4844 +#endif /* not STRVERSCMP_H_ */
4845 diff --git a/tools/Makefile.am b/tools/Makefile.am
4846 index 13c191f..fa16c68 100644
4847 --- a/tools/Makefile.am
4848 +++ b/tools/Makefile.am
4849 @@ -54,6 +54,7 @@ sbin_PROGRAMS = \
4850 ck-log-system-start \
4851 ck-log-system-restart \
4852 ck-log-system-stop \
4856 ck_launch_session_SOURCES = \
4857 @@ -83,6 +84,14 @@ ck_history_LDADD = \
4858 $(top_builddir)/src/libck-event-log.la \
4861 +ck_seat_tool_SOURCES = \
4865 +ck_seat_tool_LDADD = \
4866 + $(CONSOLE_KIT_LIBS) \
4869 ck_log_system_start_SOURCES = \
4870 ck-log-system-start.c \
4872 diff --git a/tools/ck-seat-tool.c b/tools/ck-seat-tool.c
4873 new file mode 100644
4874 index 0000000..0879d0d
4876 +++ b/tools/ck-seat-tool.c
4878 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
4880 + * Copyright (C) 2009 Sun Microsystems, Inc.
4882 + * This program is free software; you can redistribute it and/or
4883 + * modify it under the terms of the GNU General Public License as
4884 + * published by the Free Software Foundation; either version 2 of the
4885 + * License, or (at your option) any later version.
4887 + * This program is distributed in the hope that it will be useful, but
4888 + * WITHOUT ANY WARRANTY; without even the implied warranty of
4889 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4890 + * General Public License for more details.
4892 + * You should have received a copy of the GNU General Public License
4893 + * along with this program; if not, write to the Free Software
4894 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
4895 + * 02111-1307, USA.
4897 + * Authors: Halton Huo <halton.huo@sun.com>
4901 +#include "config.h"
4903 +#include <stdlib.h>
4905 +#include <sys/types.h>
4906 +#include <unistd.h>
4907 +#include <strings.h>
4908 +#include <glib/gi18n.h>
4909 +#include <dbus/dbus-glib.h>
4910 +#include <dbus/dbus-glib-lowlevel.h>
4912 +#define CK_NAME "org.freedesktop.ConsoleKit"
4913 +#define CK_PATH "/org/freedesktop/ConsoleKit"
4914 +#define CK_INTERFACE "org.freedesktop.ConsoleKit"
4915 +#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
4916 +#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
4917 +#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
4918 +#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
4920 +#define CK_DBUS_TYPE_G_STRING_STRING_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING))
4922 +#define IS_STR_SET(x) (x != NULL && x[0] != '\0')
4923 +#define CK_PATH_PREFIX "/org/freedesktop/ConsoleKit/"
4925 +static gboolean add = FALSE;
4926 +static gboolean delete = FALSE;
4927 +static gboolean show_version = FALSE;
4928 +static char *session_type = NULL;
4929 +static char *display_type = NULL;
4930 +static char *seat_id = NULL;
4931 +static char *session_id = NULL;
4932 +static gchar **remaining_args = NULL;
4934 +static const GOptionEntry options [] = {
4935 + { "add", 'a', 0, G_OPTION_ARG_NONE, &add, N_("Add a new session"), NULL},
4936 + { "session-type", '\0', 0, G_OPTION_ARG_STRING, &session_type, N_("Specify session type when adding a session. Default is LoginWindow."), NULL},
4937 + { "display-type", '\0', 0, G_OPTION_ARG_STRING, &display_type, N_("Specify display type under <etc>/ConsoleKit/displays.d/ when adding a session."), NULL},
4938 + { "seat-id", '\0', 0, G_OPTION_ARG_STRING, &seat_id, N_("Specify seat id when adding a session. If not given, create a new seat."), NULL},
4939 + { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &remaining_args, N_("Specify values of variables in display type. For example display=:10"), NULL },
4940 + { "delete", 'd', 0, G_OPTION_ARG_NONE, &delete, N_("Delete a session"), NULL},
4941 + { "session-id", '\0', 0, G_OPTION_ARG_STRING, &session_id, N_("Specify session id when deleting a session"), NULL},
4942 + { "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL },
4947 +add_session (DBusGConnection *connection)
4949 + DBusGProxy *mgr_proxy = NULL;
4950 + DBusGProxy *seat_proxy = NULL;
4951 + GError *error = NULL;
4955 + char *ssid = NULL;
4958 + char *sstype = NULL;
4959 + GHashTable *variables = NULL;
4961 + if (! IS_STR_SET (session_type)) {
4962 + sstype = g_strdup ("LoginWindow");
4964 + sstype = g_strdup (session_type);
4967 + mgr_proxy = dbus_g_proxy_new_for_name (connection,
4970 + CK_MANAGER_INTERFACE);
4971 + if (mgr_proxy == NULL) {
4975 + if (! IS_STR_SET(seat_id)) {
4977 + /* If seat id is not given, create a new seat */
4979 + res = dbus_g_proxy_call (mgr_proxy,
4982 + G_TYPE_STRING, "Default",
4984 + DBUS_TYPE_G_OBJECT_PATH, &sid,
4987 + g_warning ("Unable to add seat: %s", error->message);
4988 + g_error_free (error);
4989 + g_object_unref (mgr_proxy);
4994 + if (!g_str_has_prefix (seat_id, CK_PATH_PREFIX)) {
4995 + sid = g_strdup_printf ("%s%s", CK_PATH_PREFIX, seat_id);
4997 + sid = g_strdup (seat_id);
4999 + /* Check whether seat is existing, if not, try to create it. */
5002 + res = dbus_g_proxy_call (mgr_proxy,
5006 + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
5010 + g_warning ("Unable to get seat list: %s", error->message);
5011 + g_error_free (error);
5012 + g_object_unref (mgr_proxy);
5017 + for (i = 0; i < seats->len; i++) {
5020 + tmp_sid = g_ptr_array_index (seats, i);
5021 + if (g_str_equal (sid, tmp_sid)) {
5032 + res = dbus_g_proxy_call (mgr_proxy,
5035 + G_TYPE_STRING, "Default",
5036 + DBUS_TYPE_G_OBJECT_PATH, sid,
5040 + g_warning ("Unable to add seat: %s", error->message);
5041 + g_error_free (error);
5042 + g_object_unref (mgr_proxy);
5048 + seat_proxy = dbus_g_proxy_new_for_name (connection,
5051 + CK_SEAT_INTERFACE);
5053 + if (seat_proxy == NULL) {
5054 + g_warning ("Failed to talk to seat '%s'", sid);
5055 + g_object_unref (mgr_proxy);
5059 + variables = g_hash_table_new_full (g_str_hash, g_str_equal,
5060 + (GDestroyNotify) g_free,
5061 + (GDestroyNotify) g_free);
5063 + if (remaining_args) {
5064 + for (i = 0; i < G_N_ELEMENTS (remaining_args); i++) {
5067 + /* split var=value */
5068 + arr = g_strsplit (remaining_args [i], "=", 2);
5069 + if (arr[0] && arr[1]) {
5070 + g_hash_table_insert (variables,
5072 + g_strdup (arr[1]));
5079 + res = dbus_g_proxy_call (mgr_proxy,
5082 + DBUS_TYPE_G_OBJECT_PATH, sid,
5083 + G_TYPE_STRING, sstype,
5084 + G_TYPE_STRING, display_type,
5085 + CK_DBUS_TYPE_G_STRING_STRING_HASHTABLE, variables,
5087 + DBUS_TYPE_G_OBJECT_PATH, &ssid,
5091 + g_warning ("Unable to add dynamic session: %s", error->message);
5092 + g_error_free (error);
5094 + dbus_g_proxy_call_no_reply (seat_proxy,
5098 + g_print ("Seat %s with session %s has been added\n", sid, ssid);
5101 + g_object_unref (seat_proxy);
5102 + g_object_unref (mgr_proxy);
5106 +is_session_on_seat (DBusGConnection *connection,
5109 + gboolean *is_last_session)
5112 + DBusGProxy *seat_proxy = NULL;
5113 + GPtrArray *sessions = NULL;
5114 + char *ssid_tmp = NULL;
5116 + gboolean retval = FALSE;
5118 + GError *error = NULL;
5120 + seat_proxy = dbus_g_proxy_new_for_name (connection,
5123 + CK_SEAT_INTERFACE);
5125 + if (seat_proxy == NULL) {
5126 + g_warning ("Failed to talk to seat '%s'", sid);
5131 + res = dbus_g_proxy_call (seat_proxy,
5135 + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
5139 + g_warning ("Failed to get list of sessions for %s: %s", sid, error->message);
5140 + g_error_free (error);
5141 + g_object_unref (seat_proxy);
5145 + for (i = 0; i < sessions->len; i++) {
5147 + ssid_tmp = g_ptr_array_index (sessions, i);
5149 + if (g_str_equal (ssid, ssid_tmp)) {
5154 + g_free (ssid_tmp);
5158 + if (is_last_session != NULL) {
5159 + *is_last_session = sessions->len == 1;
5162 + g_ptr_array_free (sessions, TRUE);
5163 + g_object_unref (seat_proxy);
5169 +find_seat_id_from_session_id (DBusGConnection *connection,
5170 + DBusGProxy *proxy,
5172 + gboolean *is_last_session)
5181 + res = dbus_g_proxy_call (proxy,
5185 + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
5190 + g_warning ("Failed to get list of seats: %s", error->message);
5191 + g_error_free (error);
5195 + for (i = 0; i < seats->len; i++) {
5197 + sid = g_ptr_array_index (seats, i);
5198 + if (is_session_on_seat (connection, sid, ssid, is_last_session)) {
5204 + g_ptr_array_free (seats, TRUE);
5210 +delete_session (DBusGConnection *connection)
5212 + DBusGProxy *proxy;
5215 + gboolean is_last_session;
5217 + if (!g_str_has_prefix (session_id, CK_PATH_PREFIX)) {
5218 + ssid = g_strdup_printf ("%s%s", CK_PATH_PREFIX, session_id);
5220 + ssid = g_strdup (session_id);
5223 + proxy = dbus_g_proxy_new_for_name (connection,
5226 + CK_MANAGER_INTERFACE);
5227 + if (proxy == NULL) {
5231 + sid = find_seat_id_from_session_id (connection, proxy, ssid, &is_last_session);
5233 + dbus_g_proxy_call_no_reply (proxy,
5235 + DBUS_TYPE_G_OBJECT_PATH, ssid,
5239 + dbus_g_proxy_call_no_reply (proxy,
5241 + DBUS_TYPE_G_OBJECT_PATH, ssid,
5245 + if (is_last_session) {
5246 + dbus_g_proxy_call_no_reply (proxy,
5248 + DBUS_TYPE_G_OBJECT_PATH, sid,
5253 + g_object_unref (proxy);
5257 +main (int argc, char *argv[])
5259 + DBusGConnection *connection;
5260 + GOptionContext *ctx;
5261 + GError *error = NULL;
5266 + /* Option parsing */
5267 + ctx = g_option_context_new (_("- Manage dynamic sessions"));
5268 + g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
5269 + res = g_option_context_parse (ctx, &argc, &argv, &error);
5273 + g_warning ("%s", error->message);
5274 + g_error_free (error);
5279 + g_option_context_free (ctx);
5281 + if (show_version) {
5282 + g_print ("%s %s\n", argv[0], VERSION);
5286 + if (add && delete) {
5287 + g_warning ("Can not specify -a and -d at the same time!");
5291 + if (!add && !delete) {
5292 + g_warning ("Must specify -a, -d!");
5296 + if (delete && (! IS_STR_SET (session_id))) {
5297 + g_warning ("You must specify session id for deleting a session. You can get all sessions by ck-list-sessions");
5301 + if (add && (! IS_STR_SET (display_type)) ) {
5302 + g_warning ("You must specify display type for adding a session. You can get all display types under <etc>/ConsoleKit/displays.d/");
5303 + g_warning ("Invalid display type!");
5308 + connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
5309 + if (connection == NULL) {
5310 + g_message ("Failed to connect to the D-Bus daemon: %s", error->message);
5311 + g_error_free (error);
5317 + add_session (connection);
5318 + } else if (delete) {
5319 + delete_session (connection);
5321 + g_warning ("Invaild parameters!");
5327 diff --git a/tools/list-sessions.c b/tools/list-sessions.c
5328 index 3933772..cc69d57 100644
5329 --- a/tools/list-sessions.c
5330 +++ b/tools/list-sessions.c
5332 #define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
5333 #define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
5335 +#define IS_STR_SET(x) (x != NULL && x[0] != '\0')
5337 +typedef struct CkSessionOutput {
5342 +static gboolean do_all = FALSE;
5343 +static gboolean do_version = FALSE;
5344 +static char *do_format = NULL;
5345 +static GOptionEntry entries [] = {
5346 + { "all", 'a', 0, G_OPTION_ARG_NONE, &do_all, N_("List all sessions. If not given, only list open sessions"), NULL },
5347 + { "format", 'f', 0, G_OPTION_ARG_STRING, &do_format, N_("Prints information according to the given format"), NULL },
5348 + { "version", 'V', 0, G_OPTION_ARG_NONE, &do_version, N_("Version of this application"), NULL },
5353 get_uint (DBusGProxy *proxy,
5355 @@ -176,6 +193,7 @@ list_session (DBusGConnection *connection,
5359 + char *display_type;
5361 char *x11_display_device;
5362 char *display_device;
5363 @@ -184,8 +202,11 @@ list_session (DBusGConnection *connection,
5364 char *idle_since_hint;
5369 const char *short_ssid;
5370 + char **format_arr = NULL;
5373 proxy = dbus_g_proxy_new_for_name (connection,
5375 @@ -198,6 +219,7 @@ list_session (DBusGConnection *connection,
5378 session_type = NULL;
5379 + display_type = NULL;
5381 x11_display_device = NULL;
5382 display_device = NULL;
5383 @@ -209,15 +231,21 @@ list_session (DBusGConnection *connection,
5384 get_path (proxy, "GetSeatId", &sid);
5385 get_string (proxy, "GetLoginSessionId", &lsid);
5386 get_string (proxy, "GetSessionType", &session_type);
5387 + get_string (proxy, "GetDisplayType", &display_type);
5388 get_string (proxy, "GetX11Display", &x11_display);
5389 get_string (proxy, "GetX11DisplayDevice", &x11_display_device);
5390 get_string (proxy, "GetDisplayDevice", &display_device);
5391 get_string (proxy, "GetRemoteHostName", &remote_host_name);
5392 + get_boolean (proxy, "IsOpen", &is_open);
5393 get_boolean (proxy, "IsActive", &is_active);
5394 get_boolean (proxy, "IsLocal", &is_local);
5395 get_string (proxy, "GetCreationTime", &creation_time);
5396 get_string (proxy, "GetIdleSinceHint", &idle_since_hint);
5398 + if (!do_all && !is_open) {
5402 realname = get_real_name (uid);
5405 @@ -230,24 +258,49 @@ list_session (DBusGConnection *connection,
5406 short_ssid = ssid + strlen (CK_PATH) + 1;
5409 - printf ("%s:\n\tunix-user = '%d'\n\trealname = '%s'\n\tseat = '%s'\n\tsession-type = '%s'\n\tactive = %s\n\tx11-display = '%s'\n\tx11-display-device = '%s'\n\tdisplay-device = '%s'\n\tremote-host-name = '%s'\n\tis-local = %s\n\ton-since = '%s'\n\tlogin-session-id = '%s'",
5415 - is_active ? "TRUE" : "FALSE",
5417 - x11_display_device,
5420 - is_local ? "TRUE" : "FALSE",
5423 - if (idle_since_hint != NULL && idle_since_hint[0] != '\0') {
5424 - printf ("\n\tidle-since-hint = '%s'", idle_since_hint);
5425 + CkSessionOutput output[] = {
5426 + {"session-id", g_strdup (short_ssid)},
5427 + {"unix-user", g_strdup_printf ("%d", uid)},
5428 + {"realname", g_strdup (realname)},
5429 + {"seat", g_strdup (short_sid)},
5430 + {"session-type", g_strdup (session_type)},
5431 + {"display-type", g_strdup (display_type)},
5432 + {"open", is_open ? "TRUE" : "FALSE"},
5433 + {"active", is_active ? "TRUE" : "FALSE"},
5434 + {"x11-display", g_strdup (x11_display)},
5435 + {"x11-display-device", g_strdup (x11_display_device)},
5436 + {"display-device", g_strdup (display_device)},
5437 + {"remote-host-name", g_strdup (remote_host_name)},
5438 + {"is-local", is_local ? "TRUE" : "FALSE"},
5439 + {"on-since", g_strdup (creation_time)},
5440 + {"login-session-id", g_strdup (lsid)},
5441 + {"idle-since-hint", g_strdup (idle_since_hint)},
5444 + if (IS_STR_SET (do_format)) {
5445 + format_arr = g_strsplit (do_format, ",", -1);
5447 + for (i = 0; format_arr[i] != NULL; ++i) {
5448 + for (j = 0; j < G_N_ELEMENTS (output); j++) {
5449 + if (g_str_equal (format_arr[i], output[j].prop_name)) {
5450 + printf ("'%s'\t", output[j].prop_value);
5456 + g_strfreev (format_arr);
5459 + for (j = 0; j < G_N_ELEMENTS (output); j++) {
5460 + if (g_str_equal (output[j].prop_name, "session-id"))
5461 + printf ("%s:\n", output[j].prop_value);
5463 + printf ("\t%s = '%s'\n",
5464 + output[j].prop_name,
5465 + output[j].prop_value);
5470 g_free (idle_since_hint);
5471 g_free (creation_time);
5472 @@ -256,9 +309,11 @@ list_session (DBusGConnection *connection,
5475 g_free (session_type);
5476 + g_free (display_type);
5477 g_free (x11_display);
5478 g_free (x11_display_device);
5479 g_free (display_device);
5481 g_object_unref (proxy);
5484 @@ -368,11 +423,6 @@ main (int argc,
5485 GOptionContext *context;
5487 GError *error = NULL;
5488 - static gboolean do_version = FALSE;
5489 - static GOptionEntry entries [] = {
5490 - { "version", 'V', 0, G_OPTION_ARG_NONE, &do_version, N_("Version of this application"), NULL },