shared-macros.mk: simplify java settings
[oi-userland.git] / components / library / ConsoleKit / patches / 01-ck-dynamic.patch
blob8f69c987de719d1dfed4cde32b461b72cd074355
1 diff --git a/configure.ac b/configure.ac
2 index 117d788..2ff6020 100644
3 --- a/configure.ac
4 +++ b/configure.ac
5 @@ -203,6 +203,18 @@ AM_CONDITIONAL(CK_COMPILE_SOLARIS, test x$CK_BACKEND = xsolaris, [Compiling for
6 AC_SUBST(CK_BACKEND)
8 dnl ---------------------------------------------------------------------------
9 +dnl Check for X11 DIR
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"`
16 +fi
17 +test "x$X11_DIR" = x && X11_DIR=$bindir
18 +AC_SUBST([X11_DIR])
20 +dnl ---------------------------------------------------------------------------
21 dnl Check for PAM
22 dnl ---------------------------------------------------------------------------
24 @@ -303,6 +315,14 @@ if test "x$enable_inotify" = "xyes" ; then
27 dnl ---------------------------------------------------------------------------
28 +dnl check for strverscmp
29 +dnl ---------------------------------------------------------------------------
30 +have_strverscmp=no
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 ---------------------------------------------------------------------------
36 dnl check for RBAC
37 dnl ---------------------------------------------------------------------------
39 @@ -401,6 +421,8 @@ tools/linux/Makefile
40 tools/freebsd/Makefile
41 tools/solaris/Makefile
42 data/Makefile
43 +data/displays.d/Makefile
44 +data/sessions.d/Makefile
45 doc/Makefile
46 doc/dbus/ConsoleKit.xml
47 doc/dbus/Makefile
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
52 @@ -1,5 +1,26 @@
53 [Seat Entry]
54 Version=1.0
55 Name=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]_"
58 +ID=StaticSeat1
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.
63 Hidden=false
64 -Devices=
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:
71 +# Pointer=
72 +# Monitor=
73 +# VideoCard=
74 +# Monitor=
75 +# UsbHub=
76 +Devices=
78 +# List of sessions to start on the seat, separated by ';'
79 +# Each session is defined in sessions.d/
80 +Sessions=Local;
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
85 @@ -44,6 +44,9 @@
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"
95 @@ -69,6 +72,18 @@
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"
114 @@ -88,6 +103,9 @@
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"
124 @@ -103,6 +121,9 @@
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"
134 @@ -127,6 +148,12 @@
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"/>
159 </policy>
161 </busconfig>
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
166 @@ -1,5 +1,10 @@
167 NULL =
169 +SUBDIRS = \
170 + displays.d \
171 + sessions.d \
172 + $(NULL)
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
178 new file mode 100644
179 index 0000000..754d2bf
180 --- /dev/null
181 +++ b/data/displays.d/Headless.display.in
182 @@ -0,0 +1,5 @@
183 +[Display]
184 +Type=X11
186 +[X11]
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
189 new file mode 100644
190 index 0000000..b845a7b
191 --- /dev/null
192 +++ b/data/displays.d/Local.display.in
193 @@ -0,0 +1,5 @@
194 +[Display]
195 +Type=X11
197 +[X11]
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
200 new file mode 100644
201 index 0000000..6ad336b
202 --- /dev/null
203 +++ b/data/displays.d/LocalVNC.display.in
204 @@ -0,0 +1,5 @@
205 +[Display]
206 +Type=X11
208 +[X11]
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
211 new file mode 100644
212 index 0000000..1fab1d2
213 --- /dev/null
214 +++ b/data/displays.d/Makefile.am
215 @@ -0,0 +1,29 @@
216 +NULL =
218 +displaydir = $(sysconfdir)/ConsoleKit/displays.d
219 +display_in_files = \
220 + Local.display.in \
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)|" $< > $@
236 +EXTRA_DIST = \
237 + $(display_in_files) \
238 + $(NULL)
240 +MAINTAINERCLEANFILES = \
241 + *~ \
242 + Makefile.in
244 +CLEANFILES = $(display_DATA)
245 diff --git a/data/displays.d/RemoteMachine.display.in b/data/displays.d/RemoteMachine.display.in
246 new file mode 100644
247 index 0000000..7c69451
248 --- /dev/null
249 +++ b/data/displays.d/RemoteMachine.display.in
250 @@ -0,0 +1,5 @@
251 +[Display]
252 +Type=X11
254 +[X11]
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
257 new file mode 100644
258 index 0000000..d376af9
259 --- /dev/null
260 +++ b/data/sessions.d/Headless.session
261 @@ -0,0 +1,8 @@
262 +[Session Entry]
263 +Name=Headless
264 +Type=LoginWindow
265 +Description=Login Window running on headless display
266 +DisplayTemplate=Headless
268 +[Headless]
269 +display=:32
270 diff --git a/data/sessions.d/Local.session b/data/sessions.d/Local.session
271 new file mode 100644
272 index 0000000..9d3b975
273 --- /dev/null
274 +++ b/data/sessions.d/Local.session
275 @@ -0,0 +1,9 @@
276 +[Session Entry]
277 +Name=Local
278 +Type=LoginWindow
279 +Description=Local Login Screen
280 +DisplayTemplate=Local
282 +[Local]
283 +display=:0
284 +vt=vt1
285 diff --git a/data/sessions.d/LocalVNC.session b/data/sessions.d/LocalVNC.session
286 new file mode 100644
287 index 0000000..c05802f
288 --- /dev/null
289 +++ b/data/sessions.d/LocalVNC.session
290 @@ -0,0 +1,8 @@
291 +[Session Entry]
292 +Name=LocalVNC
293 +Type=LoginWindow
294 +Description=Connect to local VNC server running on same machine
295 +DisplayTemplate=LocalVNC
297 +[LocalVNC]
298 +display=:64
299 diff --git a/data/sessions.d/Makefile.am b/data/sessions.d/Makefile.am
300 new file mode 100644
301 index 0000000..f17ffdc
302 --- /dev/null
303 +++ b/data/sessions.d/Makefile.am
304 @@ -0,0 +1,16 @@
305 +NULL =
307 +sessiondir = $(sysconfdir)/ConsoleKit/sessions.d
308 +session_DATA = \
309 + Headless.session \
310 + Local.session \
311 + LocalVNC.session \
312 + Remote.session
314 +EXTRA_DIST = \
315 + $(session_DATA) \
316 + $(NULL)
318 +MAINTAINERCLEANFILES = \
319 + *~ \
320 + Makefile.in
321 diff --git a/data/sessions.d/Remote.session b/data/sessions.d/Remote.session
322 new file mode 100644
323 index 0000000..e88f975
324 --- /dev/null
325 +++ b/data/sessions.d/Remote.session
326 @@ -0,0 +1,9 @@
327 +[Session Entry]
328 +Name=Remote Chooser
329 +Type=Remote
330 +Description=Connect to chooser on nearby remote machine
331 +DisplayTemplate=RemoteMachine
333 +[RemoteMachine]
334 +display=:96
335 +vt=vt10
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.
341 </para>
342 </sect1>
344 + <sect1>
345 + <title>Seat manager</title>
346 + <para>
347 +The seat manager is the process responsible for starting and stopping sessions on a seat.
348 + </para>
349 + </sect1>
351 </chapter>
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 = \
373 ck-file-monitor.h \
374 ck-job.h \
375 ck-job.c \
376 + ck-display-template.h \
377 + ck-display-template.c \
378 ck-seat.h \
379 ck-seat.c \
380 ck-session-leader.h \
381 @@ -122,6 +124,13 @@ console_kit_daemon_SOURCES = \
382 $(BUILT_SOURCES) \
383 $(NULL)
385 +if USE_SELF_STRVERSCMP
386 +console_kit_daemon_SOURCES += \
387 + strverscmp.c \
388 + strverscmp.h \
389 + $(NULL)
390 +endif
392 if ENABLE_INOTIFY
393 FILE_MONITOR_BACKEND = ck-file-monitor-inotify.c
394 else
395 diff --git a/src/ck-display-template.c b/src/ck-display-template.c
396 new file mode 100644
397 index 0000000..9206103
398 --- /dev/null
399 +++ b/src/ck-display-template.c
400 @@ -0,0 +1,341 @@
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.
405 + * Red Hat, 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.
421 + */
423 +#include "config.h"
425 +#include <string.h>
426 +#include <glib.h>
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
437 + char *name;
438 + char *type;
439 + GHashTable *parameters;
442 +enum {
443 + PROP_0,
444 + PROP_NAME,
445 + PROP_TYPE,
446 + PROP_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)
458 +static void
459 +_ck_display_template_set_name (CkDisplayTemplate *display,
460 + const char *name)
462 + g_free (display->priv->name);
463 + display->priv->name = g_strdup (name);
466 +static void
467 +_ck_display_template_set_type_string (CkDisplayTemplate *display,
468 + const char *type)
470 + g_free (display->priv->type);
471 + display->priv->type = g_strdup (type);
474 +static void
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);
486 + } else {
487 + display->priv->parameters = g_hash_table_ref (parameters);
491 +static void
492 +ck_display_template_set_property (GObject *object,
493 + guint prop_id,
494 + const GValue *value,
495 + GParamSpec *pspec)
497 + CkDisplayTemplate *self;
499 + self = CK_DISPLAY_TEMPLATE (object);
501 + switch (prop_id) {
502 + case PROP_NAME:
503 + _ck_display_template_set_name (self, g_value_get_string (value));
504 + break;
505 + case PROP_TYPE:
506 + _ck_display_template_set_type_string (self, g_value_get_string (value));
507 + break;
508 + case PROP_PARAMETERS:
509 + _ck_display_template_set_parameters (self, g_value_get_boxed (value));
510 + break;
511 + default:
512 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
513 + break;
517 +static void
518 +ck_display_template_get_property (GObject *object,
519 + guint prop_id,
520 + GValue *value,
521 + GParamSpec *pspec)
523 + CkDisplayTemplate *self;
525 + self = CK_DISPLAY_TEMPLATE (object);
527 + switch (prop_id) {
528 + case PROP_NAME:
529 + g_value_set_string (value, self->priv->name);
530 + break;
531 + case PROP_TYPE:
532 + g_value_set_string (value, self->priv->type);
533 + break;
534 + case PROP_PARAMETERS:
535 + g_value_set_boxed (value, self->priv->parameters);
536 + break;
537 + default:
538 + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
539 + break;
543 +static void
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,
553 + PROP_NAME,
554 + g_param_spec_string ("name",
555 + "display type name",
556 + "display type name",
557 + NULL,
558 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
559 + g_object_class_install_property (object_class,
560 + PROP_TYPE,
561 + g_param_spec_string ("type",
562 + "type",
563 + "Type",
564 + NULL,
565 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
566 + g_object_class_install_property (object_class,
567 + PROP_PARAMETERS,
568 + g_param_spec_boxed ("parameters",
569 + "Parameters",
570 + "Parameters",
571 + G_TYPE_HASH_TABLE,
572 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
573 + g_type_class_add_private (klass, sizeof (CkDisplayTemplatePrivate));
576 +static void
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);
588 +static void
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);
607 +static gboolean
608 +ck_display_template_load (CkDisplayTemplate *display)
610 + GKeyFile *key_file;
611 + const char *name;
612 + char *group;
613 + char *filename;
614 + gboolean hidden;
615 + char *type;
616 + gboolean res;
617 + GError *error;
618 + char **type_keys;
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 ();
629 + error = NULL;
630 + res = g_key_file_load_from_file (key_file,
631 + filename,
632 + G_KEY_FILE_NONE,
633 + &error);
634 + if (! res) {
635 + g_warning ("Unable to load display from file %s: %s", filename, error->message);
636 + g_error_free (error);
637 + return FALSE;
639 + g_free (filename);
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);
645 + g_free (group);
646 + g_key_file_free (key_file);
647 + return FALSE;
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");
656 + g_free (group);
657 + g_key_file_free (key_file);
658 + return FALSE;
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) {
670 + int i;
671 + for (i = 0; type_keys[i] != NULL; i++) {
672 + char *string;
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);
683 + g_free (group);
684 + g_key_file_free (key_file);
685 + return TRUE;
688 +CkDisplayTemplate *
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) {
702 + GObject *object;
704 + object = g_object_new (CK_TYPE_DISPLAY_TEMPLATE,
705 + "name", name,
706 + NULL);
708 + if (!ck_display_template_load (CK_DISPLAY_TEMPLATE (object))) {
709 + g_object_unref (object);
710 + return NULL;
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;
734 +GHashTable *
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
743 new file mode 100644
744 index 0000000..fa74e67
745 --- /dev/null
746 +++ b/src/ck-display-template.h
747 @@ -0,0 +1,57 @@
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.
767 + */
769 +#ifndef __CK_DISPLAY_TEMPLATE_H
770 +#define __CK_DISPLAY_TEMPLATE_H
772 +#include <glib-object.h>
774 +G_BEGIN_DECLS
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;
785 +typedef struct
787 + GObject parent;
788 + CkDisplayTemplatePrivate *priv;
789 +} CkDisplayTemplate;
791 +typedef struct
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);
802 +G_END_DECLS
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
872 error = NULL;
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);
875 if (re == NULL) {
876 g_warning ("%s", error->message);
877 goto out;
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
889 error = NULL;
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);
892 if (re == NULL) {
893 g_warning ("%s", error->message);
894 goto out;
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
909 char *seat_id;
910 int seat_kind;
911 + char *seat_type;
912 } CkLogSeatAddedEvent;
914 typedef struct
915 @@ -81,11 +82,13 @@ typedef struct
916 char *seat_id;
917 char *session_id;
918 char *session_type;
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
930 char *seat_id;
931 char *session_id;
932 char *session_type;
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
945 @@ -45,9 +45,14 @@
946 #include <secdb.h>
947 #endif
949 +#ifndef HAVE_STRVERSCMP
950 +#include "strverscmp.h"
951 +#endif
953 #include "ck-manager.h"
954 #include "ck-manager-glue.h"
955 #include "ck-seat.h"
956 +#include "ck-display-template.h"
957 #include "ck-session-leader.h"
958 #include "ck-session.h"
959 #include "ck-marshal.h"
960 @@ -57,12 +62,19 @@
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", \
965 + G_TYPE_STRING, \
966 + G_TYPE_VALUE, \
967 + G_TYPE_INVALID))
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
979 #ifdef HAVE_POLKIT
980 @@ -391,6 +403,7 @@ log_seat_added_event (CkManager *manage
981 GError *error;
982 char *sid;
983 CkSeatKind seat_kind;
984 + char *seat_type;
986 memset (&event, 0, sizeof (CkLogEvent));
988 @@ -400,9 +413,11 @@ log_seat_added_event (CkManager *manage
989 sid = NULL;
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;
998 error = NULL;
999 res = ck_event_logger_queue_event (manager->priv->logger, &event, &error);
1000 @@ -412,6 +427,7 @@ log_seat_added_event (CkManager *manage
1003 g_free (sid);
1004 + g_free (seat_type);
1007 static void
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;
1026 GError *error;
1028 + g_debug ("CkManager: Ready.");
1030 error = NULL;
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");
1038 ret = FALSE;
1039 goto out;
1041 @@ -982,6 +1003,7 @@ session_is_real_user (CkSession *session
1042 *userp = g_strdup (username);
1045 + g_debug ("CkManager: Session is real user");
1046 ret = TRUE;
1048 out:
1049 @@ -1242,6 +1264,7 @@ on_seat_active_session_changed_full (CkS
1051 char *ssid = NULL;
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 *
1059 char *ssid = NULL;
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
1067 char *ssid = NULL;
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,
1075 CkManager *manager)
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,
1083 CkManager *manager)
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
1092 static CkSeat *
1093 -add_new_seat (CkManager *manager,
1094 - CkSeatKind kind)
1095 +add_new_seat (CkManager *manager,
1096 + const char *give_sid,
1097 + CkSeatKind kind,
1098 + const char *type)
1100 char *sid;
1101 CkSeat *seat;
1103 - sid = generate_seat_id (manager);
1104 + if (IS_STR_SET (give_sid)) {
1105 + sid = g_strdup (give_sid);
1106 + } else {
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,
1127 sid = NULL;
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,
1134 sid,
1135 @@ -1420,64 +1457,22 @@ remove_seat (CkManager *manager,
1136 g_free (sid);
1139 -#define IS_STR_SET(x) (x != NULL && x[0] != '\0')
1141 static CkSeat *
1142 find_seat_for_session (CkManager *manager,
1143 CkSession *session)
1145 CkSeat *seat;
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;
1157 - seat = NULL;
1158 - display_device = NULL;
1159 - x11_display_device = NULL;
1160 - x11_display = NULL;
1161 - remote_host_name = NULL;
1162 - is_local = FALSE;
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;
1184 + char *sid = NULL;
1186 + ck_session_get_seat_id (session, &sid, NULL);
1188 - if (is_static_x11 || is_static_text) {
1189 - char *sid;
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);
1193 - g_free (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);
1202 + g_free (sid);
1203 return seat;
1206 @@ -1612,36 +1607,52 @@ open_session_for_leader (CkManager
1207 CkSession *session;
1208 CkSeat *seat;
1209 const char *ssid;
1210 + char *sid;
1211 const char *cookie;
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,
1218 - cookie,
1219 - parameters);
1220 + session = g_hash_table_lookup (manager->priv->sessions, ssid);
1222 if (session == NULL) {
1223 - GError *error;
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,
1232 + parameters);
1234 + if (session == NULL) {
1235 + GError *error;
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);
1243 - return;
1244 + return;
1247 + g_hash_table_insert (manager->priv->sessions,
1248 + g_strdup (ssid),
1249 + g_object_ref (session));
1251 + } else {
1252 + g_debug ("CkManager: Using found session.");
1253 + ck_session_set_parameters (session, parameters);
1256 - g_hash_table_insert (manager->priv->sessions,
1257 - g_strdup (ssid),
1258 - g_object_ref (session));
1259 + ck_session_set_cookie (session, cookie, NULL);
1260 + ck_session_set_is_open (session, TRUE, NULL);
1262 /* Add to seat */
1263 seat = find_seat_for_session (manager, session);
1264 if (seat == NULL) {
1265 + sid = NULL;
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");
1270 + g_free (sid);
1273 ck_seat_add_session (seat, session, NULL);
1274 @@ -1863,6 +1874,7 @@ generate_session_for_leader (CkManager
1276 gboolean res;
1278 + g_debug ("CkManager: Generate session for leader.");
1279 res = ck_session_leader_collect_parameters (leader,
1280 context,
1281 (CkSessionLeaderDoneFunc)collect_parameters_cb,
1282 @@ -1877,11 +1889,57 @@ generate_session_for_leader (CkManager
1286 +static char *
1287 +check_parameters_for_ssid (const GPtrArray *parameters)
1289 + int i;
1291 + if (parameters == NULL) {
1292 + return NULL;
1295 + for (i = 0; i < parameters->len; i++) {
1296 + GValue val_struct = { 0, };
1297 + char *prop_name;
1298 + gboolean res;
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,
1304 + 0, &prop_name,
1305 + G_MAXUINT);
1306 + if (! res) {
1307 + g_debug ("CkManager: Unable to read parameter name");
1308 + continue;
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);
1318 + if (! res) {
1319 + g_debug ("CkManager: Unable to read parameter value");
1320 + continue;
1323 + session_val = g_value_get_boxed (&prop_val);
1325 + return g_value_dup_string (session_val);
1329 + return NULL;
1332 static gboolean
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)
1342 pid_t pid;
1343 uid_t uid;
1344 @@ -1889,6 +1947,7 @@ create_session_for_sender (CkManager
1345 char *cookie;
1346 char *ssid;
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
1366 + */
1367 + g_debug ("CkManager: Managing existing session ssid: %s", ssid);
1368 + } else {
1369 + ssid = generate_session_id (manager);
1370 + session = NULL;
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
1377 gboolean ret;
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);
1382 g_free (sender);
1384 return ret;
1385 @@ -2163,7 +2234,7 @@ ck_manager_open_session_with_parameters
1386 gboolean ret;
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);
1391 g_free (sender);
1393 return ret;
1394 @@ -2180,10 +2251,12 @@ remove_session_for_cookie (CkManager *m
1395 char *sid;
1396 gboolean res;
1397 gboolean ret;
1398 + gboolean should_remove_session;
1400 ret = FALSE;
1401 orig_ssid = NULL;
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
1408 goto out;
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 */
1430 - sid = NULL;
1431 - ck_session_get_seat_id (orig_session, &sid, NULL);
1432 - if (sid != NULL) {
1433 - CkSeat *seat;
1434 - seat = g_hash_table_lookup (manager->priv->seats, sid);
1435 - if (seat != NULL) {
1436 - CkSeatKind kind;
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");
1450 + sid = NULL;
1451 + ck_session_get_seat_id (orig_session, &sid, NULL);
1452 + if (sid != NULL) {
1453 + CkSeat *seat;
1454 + seat = g_hash_table_lookup (manager->priv->seats, sid);
1455 + if (seat != NULL) {
1456 + CkSeatKind kind;
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);
1466 - g_free (sid);
1467 + g_free (sid);
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
1483 ret = TRUE;
1484 out:
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);
1496 return ret;
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
1508 guint n_removed;
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 ();
1518 #endif
1520 + g_debug ("CkManager: Registering manager");
1522 error = NULL;
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),
1527 NULL,
1528 NULL,
1529 - g_cclosure_marshal_VOID__BOXED,
1530 + ck_marshal_VOID__STRING_STRING,
1531 G_TYPE_NONE,
1532 - 1, DBUS_TYPE_G_OBJECT_PATH);
1533 + 2,
1534 + G_TYPE_STRING,
1535 + G_TYPE_STRING);
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
1542 static void
1543 +listify_unmanaged_seat_ids (char *id,
1544 + CkSeat *seat,
1545 + GPtrArray **array)
1547 + if (ck_seat_is_managed (seat)) {
1548 + return;
1551 + g_ptr_array_add (*array, g_strdup (id));
1556 + Example:
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
1562 +gboolean
1563 +ck_manager_get_unmanaged_seats (CkManager *manager,
1564 + GPtrArray **seats,
1565 + GError **error)
1567 + g_return_val_if_fail (CK_IS_MANAGER (manager), FALSE);
1569 + if (seats == NULL) {
1570 + return FALSE;
1573 + *seats = g_ptr_array_new ();
1574 + g_hash_table_foreach (manager->priv->seats, (GHFunc)listify_unmanaged_seat_ids, seats);
1576 + return TRUE;
1579 +static void
1580 listify_session_ids (char *id,
1581 CkSession *session,
1582 GPtrArray **array)
1583 @@ -2604,16 +2736,321 @@ ck_manager_get_sessions (CkManager *man
1584 return TRUE;
1588 + Example:
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
1594 +gboolean
1595 +ck_manager_add_seat (CkManager *manager,
1596 + const char *type,
1597 + char **sid,
1598 + GError **error)
1600 + CkSeat *seat;
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)) {
1608 + return FALSE;
1611 + return TRUE;
1615 + Example:
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 \
1622 +gboolean
1623 +ck_manager_add_seat_by_id (CkManager *manager,
1624 + const char *type,
1625 + const char *sid,
1626 + GError **error)
1628 + CkSeat *seat;
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);
1638 + Example:
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
1645 +gboolean
1646 +ck_manager_remove_seat (CkManager *manager,
1647 + const char *sid,
1648 + DBusGMethodInvocation *context)
1650 + CkSeat *seat = NULL;
1651 + CkSeatKind kind;
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) {
1659 + GError *error;
1661 + error = g_error_new (CK_SEAT_ERROR,
1662 + CK_SEAT_ERROR_GENERAL,
1663 + _("Seat '%s' doesn't exist"),
1664 + sid);
1666 + dbus_g_method_return_error (context, error);
1667 + g_error_free (error);
1669 + return FALSE;
1672 + ck_seat_get_kind (seat, &kind, NULL);
1674 + if (kind == CK_SEAT_KIND_STATIC) {
1675 + GError *error;
1677 + error = g_error_new (CK_SEAT_ERROR,
1678 + CK_SEAT_ERROR_GENERAL,
1679 + _("Seat '%s' is static and can't be removed"),
1680 + sid);
1682 + dbus_g_method_return_error (context, error);
1683 + g_error_free (error);
1685 + return FALSE;
1688 + if (ck_seat_is_managed (seat)) {
1689 + ck_seat_request_removal (seat);
1690 + } else {
1691 + remove_seat (manager, seat);
1694 + return TRUE;
1698 + Example:
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"
1707 +gboolean
1708 +ck_manager_add_session (CkManager *manager,
1709 + const char *sid,
1710 + const char *type,
1711 + const char *display_type,
1712 + GHashTable *variables,
1713 + DBusGMethodInvocation *context)
1715 + CkSeat *seat;
1716 + CkSession *session;
1717 + char *ssid;
1719 + g_debug ("CkManager: Add session");
1720 + seat = g_hash_table_lookup (manager->priv->seats, sid);
1722 + if (seat == NULL) {
1723 + GError *error;
1725 + error = g_error_new (CK_SEAT_ERROR,
1726 + CK_SEAT_ERROR_GENERAL,
1727 + _("Seat '%s' doesn't exist"),
1728 + sid);
1730 + dbus_g_method_return_error (context, error);
1731 + g_error_free (error);
1733 + return FALSE;
1736 + ssid = generate_session_id (manager);
1738 + session = ck_session_new (ssid, type, display_type, variables);
1740 + if (session == NULL) {
1741 + GError *error;
1743 + error = g_error_new (CK_SEAT_ERROR,
1744 + CK_SEAT_ERROR_GENERAL,
1745 + _("Session could not be added to seat '%s'"),
1746 + sid);
1748 + dbus_g_method_return_error (context, error);
1749 + g_error_free (error);
1751 + return FALSE;
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);
1757 + } else {
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,
1764 + ssid,
1765 + session);
1767 + dbus_g_method_return (context, ssid);
1768 + return TRUE;
1772 + Example:
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
1779 +gboolean
1780 +ck_manager_remove_session (CkManager *manager,
1781 + const char *ssid,
1782 + DBusGMethodInvocation *context)
1784 + CkSession *session;
1785 + CkSeat *seat;
1786 + GError *error;
1787 + char *sid;
1788 + gboolean is_open;
1790 + g_debug ("CkManager: Remove session.");
1791 + session = g_hash_table_lookup (manager->priv->sessions, ssid);
1793 + if (session == NULL) {
1794 + GError *error;
1796 + error = g_error_new (CK_SEAT_ERROR,
1797 + CK_SEAT_ERROR_GENERAL,
1798 + _("Session '%s' doesn't exist"),
1799 + ssid);
1801 + dbus_g_method_return_error (context, error);
1802 + g_error_free (error);
1804 + return FALSE;
1807 + ck_session_get_seat_id (session, &sid, NULL);
1808 + seat = g_hash_table_lookup (manager->priv->seats, sid);
1809 + g_free (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);
1814 + return TRUE;
1817 + error = NULL;
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
1823 + */
1824 + if (ck_seat_is_managed (seat) && is_open) {
1825 + ck_seat_request_close_session (seat, session, NULL);
1826 + dbus_g_method_return (context);
1828 + return TRUE;
1831 + if (!ck_seat_remove_session (seat, session, &error)) {
1832 + if (error == NULL) {
1833 + return TRUE;
1836 + dbus_g_method_return_error (context, error);
1837 + g_error_free (error);
1838 + return FALSE;
1841 + g_hash_table_remove (manager->priv->sessions, ssid);
1842 + dbus_g_method_return (context);
1843 + return TRUE;
1846 +static void
1847 +add_sessions_from_seat (CkManager *manager,
1848 + CkSeat *seat)
1850 + GPtrArray *sessions;
1851 + int i;
1853 + g_debug ("CkManager: Add session from seat.");
1854 + ck_seat_get_sessions (seat, &sessions, NULL);
1856 + for (i = 0; i < sessions->len; i++) {
1857 + char *ssid;
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,
1864 + ssid,
1865 + session);
1868 + g_ptr_array_free (sessions, TRUE);
1871 static void
1872 add_seat_for_file (CkManager *manager,
1873 const char *filename)
1875 char *sid;
1876 + char *orig_sid;
1877 CkSeat *seat;
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 */
1886 + g_free (sid);
1887 + g_free (orig_sid);
1888 + manager->priv->seat_serial--;
1889 + return;
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) {
1901 + return;
1904 if (seat == NULL) {
1905 return;
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)
1916 GDir *d;
1917 GError *error;
1918 const char *file;
1919 + GQueue seat_queue;
1921 error = NULL;
1922 d = g_dir_open (CK_SEAT_DIR,
1923 @@ -2658,17 +3096,26 @@ load_seats_from_dir (CkManager *manager)
1924 return FALSE;
1927 + g_queue_init (&seat_queue);
1928 while ((file = g_dir_read_name (d)) != NULL) {
1929 if (g_str_has_suffix (file, ".seat")) {
1930 char *path;
1931 path = g_build_filename (CK_SEAT_DIR, file, NULL);
1932 - add_seat_for_file (manager, path);
1933 - g_free (path);
1934 + g_queue_push_tail (&seat_queue, path);
1938 g_dir_close (d);
1940 + g_queue_sort (&seat_queue, (GCompareDataFunc) strverscmp, NULL);
1942 + while (!g_queue_is_empty (&seat_queue)) {
1943 + char *path;
1945 + path = g_queue_pop_head (&seat_queue);
1946 + add_seat_for_file (manager, path);
1947 + g_free (path);
1950 return TRUE;
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);
1961 static void
1962 @@ -2750,7 +3195,48 @@ ck_manager_new (void)
1963 g_object_unref (manager_object);
1964 return NULL;
1967 + create_seats (CK_MANAGER (manager_object));
1970 return CK_MANAGER (manager_object);
1973 +gboolean
1974 +ck_manager_will_not_respawn (CkManager *manager,
1975 + const char *ssid,
1976 + DBusGMethodInvocation *context)
1978 + GError *error;
1979 + CkSeat *seat;
1980 + CkSession *session;
1981 + char *sid;
1983 + g_debug ("CkManager: Will not respawn: '%s'.", ssid);
1984 + session = g_hash_table_lookup (manager->priv->sessions, ssid);
1986 + if (session == NULL) {
1987 + GError *error;
1989 + error = g_error_new (CK_SEAT_ERROR,
1990 + CK_SEAT_ERROR_GENERAL,
1991 + _("Session '%s' doesn't exist"),
1992 + ssid);
1994 + dbus_g_method_return_error (context, error);
1995 + g_error_free (error);
1997 + return FALSE;
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);
2003 + g_free (sid);
2005 + ck_seat_no_respawn (seat, session, &error);
2007 + dbus_g_method_return (context);
2008 + return TRUE;
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,
2019 - const char *sid);
2020 + const char *sid,
2021 + const char *type);
2022 void (* seat_removed) (CkManager *manager,
2023 const char *sid);
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,
2027 GPtrArray **seats,
2028 GError **error);
2029 +gboolean ck_manager_get_unmanaged_seats (CkManager *manager,
2030 + GPtrArray **seats,
2031 + GError **error);
2032 gboolean ck_manager_close_session (CkManager *manager,
2033 const char *cookie,
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,
2040 + const char *type,
2041 + char **sid,
2042 + GError **error);
2043 +gboolean ck_manager_add_seat_by_id (CkManager *manager,
2044 + const char *type,
2045 + const char *sid,
2046 + GError **error);
2047 +gboolean ck_manager_remove_seat (CkManager *manager,
2048 + const char *sid,
2049 + DBusGMethodInvocation *context);
2051 +gboolean ck_manager_add_session (CkManager *manager,
2052 + const char *sid,
2053 + const char *type,
2054 + const char *display_type,
2055 + GHashTable *parameters,
2056 + DBusGMethodInvocation *context);
2057 +gboolean ck_manager_remove_session (CkManager *manager,
2058 + const char *ssid,
2059 + DBusGMethodInvocation *context);
2060 +gboolean ck_manager_will_not_respawn (CkManager *manager,
2061 + const char *cookie,
2062 + DBusGMethodInvocation *context);
2064 G_END_DECLS
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
2071 @@ -1,3 +1,6 @@
2072 VOID:UINT,STRING
2073 BOOLEAN:POINTER
2074 VOID:OBJECT,OBJECT
2075 +VOID:STRING,STRING
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
2080 --- a/src/ck-seat.c
2081 +++ b/src/ck-seat.c
2082 @@ -39,21 +39,30 @@
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
2107 char *id;
2108 CkSeatKind kind;
2109 + char *type;
2110 GHashTable *sessions;
2111 GPtrArray *devices;
2113 @@ -62,6 +71,8 @@ struct CkSeatPrivate
2114 CkVtMonitor *vt_monitor;
2116 DBusGConnection *connection;
2118 + DBusGProxy *manager_proxy;
2121 enum {
2122 @@ -73,6 +84,10 @@ enum {
2123 SESSION_REMOVED_FULL,
2124 DEVICE_ADDED,
2125 DEVICE_REMOVED,
2126 + REMOVE_REQUEST,
2127 + OPEN_SESSION_REQUEST,
2128 + CLOSE_SESSION_REQUEST,
2129 + NO_RESPAWN,
2130 LAST_SIGNAL
2133 @@ -80,6 +95,7 @@ enum {
2134 PROP_0,
2135 PROP_ID,
2136 PROP_KIND,
2137 + PROP_TYPE
2140 static guint signals [LAST_SIGNAL] = { 0, };
2141 @@ -286,6 +302,7 @@ ck_seat_activate_session (CkSeat
2143 CkSession *session;
2144 gboolean ret;
2145 + gboolean is_open;
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);
2155 + if (!is_open) {
2156 + ret = ck_seat_request_open_session (seat, session, NULL);
2157 + dbus_g_method_return (context, NULL);
2158 + } else {
2159 + ret = _seat_activate_session (seat, session, context);
2162 return ret;
2165 static gboolean
2166 +on_substitution_match (const GMatchInfo *match_info,
2167 + GString *result,
2168 + GHashTable *substitution_variables)
2170 + char *match;
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);
2180 + } else {
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);
2187 + g_free (match);
2189 + return FALSE;
2192 +static char *
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,
2201 + value,
2202 + -1, 0, 0,
2203 + (GRegexEvalCallback)
2204 + on_substitution_match,
2205 + substitution_variables,
2206 + NULL);
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),
2236 + expanded_string);
2239 + return evaluated_parameters;
2242 +static void
2243 +request_session (gpointer key,
2244 + gpointer value,
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);
2256 +static void
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,
2265 + DBUS_TYPE_ARRAY,
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,
2270 + &array_iter);
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,
2279 + NULL,
2280 + &dict_iter);
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);
2289 +static void
2290 +emit_session_open_request (CkSeat *seat,
2291 + const char *ssid,
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))
2303 + return;
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);
2326 +gboolean
2327 +ck_seat_request_open_session (CkSeat *seat,
2328 + CkSession *session,
2329 + GError **error)
2331 + char *ssid;
2332 + char *type;
2333 + CkDisplayTemplate *display_template;
2334 + GHashTable *display_variables;
2335 + GHashTable *display_parameters;
2336 + GHashTable *evaluated_parameters;
2337 + gboolean is_open;
2338 + gboolean ever_open;
2339 + gboolean under_request;
2341 + ck_session_is_open (session, &is_open, NULL);
2343 + if (is_open) {
2344 + return TRUE;
2347 + ck_session_get_under_request (session, &under_request, NULL);
2348 + if (under_request) {
2349 + return TRUE;
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) {
2359 + return TRUE;
2362 + ck_session_get_session_type (session, &type, NULL);
2364 + if (type == NULL) {
2365 + g_object_unref (display_template);
2366 + return TRUE;
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) {
2374 + g_free (type);
2375 + g_object_unref (display_template);
2376 + g_hash_table_unref (display_variables);
2377 + return TRUE;
2380 + if (!ever_open) {
2381 + evaluated_parameters = get_evaluated_parameter_map (display_parameters, display_variables);
2382 + } else {
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);
2396 + g_free (ssid);
2397 + g_free (type);
2398 + g_hash_table_unref (evaluated_parameters);
2399 + g_hash_table_unref (display_variables);
2400 + g_object_unref (display_template);
2402 + return TRUE;
2405 +static void
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),
2412 + seat);
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?)
2420 + */
2423 +gboolean
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) {
2433 + GError *error;
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);
2450 + return FALSE;
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.
2458 + */
2459 + seat->priv->manager_proxy = dbus_g_proxy_new_for_name (seat->priv->connection,
2461 + sender_name,
2462 + seat->priv->id,
2463 + "org.freedesktop.ConsoleKit.SeatManager");
2464 + g_free (sender_name);
2466 + g_signal_connect_swapped (seat->priv->manager_proxy,
2467 + "destroy",
2468 + G_CALLBACK (on_seat_manager_disappeared),
2469 + seat);
2471 + g_hash_table_foreach (seat->priv->sessions, request_session, seat);
2473 + dbus_g_method_return (context);
2474 + return TRUE;
2477 +gboolean
2478 +ck_seat_unmanage (CkSeat *seat,
2479 + DBusGMethodInvocation *context)
2481 + GError *error;
2482 + const char *existing_manager_name;
2483 + char *sender_name;
2485 + g_debug ("CkSeat: Seat unmanage.");
2486 + if (seat->priv->manager_proxy == NULL) {
2487 + GError *error;
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);
2495 + return FALSE;
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,
2507 + sender_name);
2509 + dbus_g_method_return_error (context, error);
2510 + g_error_free (error);
2512 + return FALSE;
2515 + on_seat_manager_disappeared (seat);
2517 + dbus_g_method_return (context);
2518 + return TRUE;
2521 +void
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",
2534 + "RemoveRequest");
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);
2545 +static gboolean
2546 match_session_display_device (const char *key,
2547 CkSession *session,
2548 const char *display_device)
2549 @@ -313,6 +716,8 @@ match_session_display_device (const char
2550 device = NULL;
2551 ret = FALSE;
2553 + g_debug ("CkSeat: Session display device.");
2555 if (session == NULL) {
2556 goto out;
2558 @@ -485,6 +890,8 @@ change_active_session (CkSeat *seat,
2559 char *ssid;
2560 CkSession *old_session;
2562 + g_debug ("CkSeat: Change active session.");
2564 if (seat->priv->active_session == session) {
2565 return;
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,
2582 static void
2583 +find_possible_session_to_activate (CkSeat *seat)
2585 + GHashTableIter iter;
2586 + gpointer key, value;
2587 + gboolean is_open;
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);
2597 + if (is_open) {
2598 + login_session = NULL;
2599 + change_active_session (seat, value);
2600 + break;
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);
2618 +static void
2619 update_active_vt (CkSeat *seat,
2620 guint num)
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);
2630 + } else {
2631 + change_active_session (seat, session);
2634 g_free (device);
2636 @@ -546,12 +997,20 @@ maybe_update_active_session (CkSeat *sea
2638 guint num;
2640 - if (seat->priv->kind != CK_SEAT_KIND_STATIC) {
2641 - return;
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,
2650 + &num, NULL)) {
2651 + update_active_vt (seat, num);
2653 + break;
2654 + case CK_SEAT_KIND_DYNAMIC:
2655 + find_possible_session_to_activate (seat);
2656 + break;
2657 + default:
2658 + break;
2662 @@ -560,6 +1019,7 @@ session_activate (CkSession
2663 DBusGMethodInvocation *context,
2664 CkSeat *seat)
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 *
2671 ssid = NULL;
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,
2678 ssid,
2679 @@ -627,18 +1089,118 @@ ck_seat_remove_session (CkSeat *
2680 return ret;
2683 +static void
2684 +emit_session_close_request (CkSeat *seat,
2685 + const char *ssid)
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);
2709 +gboolean
2710 +ck_seat_request_close_session (CkSeat *seat,
2711 + CkSession *session,
2712 + GError **error)
2714 + char *ssid;
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);
2725 + g_free (ssid);
2727 + return FALSE;
2730 +gboolean
2731 +ck_seat_no_respawn (CkSeat *seat,
2732 + CkSession *session,
2733 + GError **error)
2735 + DBusMessage *message;
2736 + DBusConnection *connection;
2737 + DBusMessageIter iter;
2738 + char *ssid;
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",
2749 + "NoRespawn");
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);
2762 + g_free (ssid);
2764 + return FALSE;
2767 gboolean
2768 ck_seat_add_session (CkSeat *seat,
2769 CkSession *session,
2770 GError **error)
2772 char *ssid;
2773 + GHashTableIter iter;
2774 + gpointer key, value;
2775 + gboolean found;
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));
2783 + found = FALSE;
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)) {
2787 + found = TRUE;
2788 + break;
2792 + if (! found)
2793 + g_hash_table_insert (seat->priv->sessions, g_strdup (ssid), g_object_ref (session));
2794 + else
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);
2807 g_free (ssid);
2809 return TRUE;
2810 @@ -741,6 +1307,20 @@ ck_seat_get_kind (CkSeat *seat,
2813 gboolean
2814 +ck_seat_get_type_string (CkSeat *seat,
2815 + char **type,
2816 + GError **error)
2818 + g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
2820 + if (type != NULL) {
2821 + *type = g_strdup (seat->priv->type);
2824 + return TRUE;
2827 +gboolean
2828 ck_seat_get_id (CkSeat *seat,
2829 char **id,
2830 GError **error)
2831 @@ -772,6 +1352,7 @@ ck_seat_register (CkSeat *seat)
2832 g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
2834 error = NULL;
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,
2842 static void
2843 +_ck_seat_set_type_string (CkSeat *seat,
2844 + const char *type)
2846 + g_free (seat->priv->type);
2847 + seat->priv->type = g_strdup (type);
2850 +static void
2851 ck_seat_set_property (GObject *object,
2852 guint prop_id,
2853 const GValue *value,
2854 @@ -875,6 +1464,9 @@ ck_seat_set_property (GObject
2855 case PROP_KIND:
2856 _ck_seat_set_kind (self, g_value_get_enum (value));
2857 break;
2858 + case PROP_TYPE:
2859 + _ck_seat_set_type_string (self, g_value_get_string (value));
2860 + break;
2861 default:
2862 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2863 break;
2864 @@ -896,7 +1488,10 @@ ck_seat_get_property (GObject *object
2865 g_value_set_string (value, self->priv->id);
2866 break;
2867 case PROP_KIND:
2868 - g_value_set_string (value, self->priv->id);
2869 + g_value_set_enum (value, self->priv->kind);
2870 + break;
2871 + case PROP_TYPE:
2872 + g_value_set_string (value, self->priv->type);
2873 break;
2874 default:
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,
2878 G_TYPE_NONE,
2879 1, CK_TYPE_DEVICE);
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),
2884 + NULL,
2885 + NULL,
2886 + g_cclosure_marshal_VOID__VOID,
2887 + G_TYPE_NONE, 0);
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),
2892 + NULL,
2893 + NULL,
2894 + ck_marshal_VOID__STRING_STRING_STRING_POINTER_STRING_POINTER,
2895 + G_TYPE_NONE,
2896 + 6,
2897 + DBUS_TYPE_G_OBJECT_PATH,
2898 + G_TYPE_STRING,
2899 + G_TYPE_STRING,
2900 + CK_DBUS_TYPE_G_STRING_STRING_HASHTABLE,
2901 + G_TYPE_STRING,
2902 + CK_DBUS_TYPE_G_STRING_STRING_HASHTABLE,
2903 + G_TYPE_INVALID);
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),
2908 + NULL,
2909 + NULL,
2910 + g_cclosure_marshal_VOID__VOID,
2911 + G_TYPE_NONE,
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),
2917 + NULL,
2918 + NULL,
2919 + g_cclosure_marshal_VOID__VOID,
2920 + G_TYPE_NONE, 0);
2921 +/* HERE */
2923 g_object_class_install_property (object_class,
2924 PROP_ID,
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,
2930 + PROP_TYPE,
2931 + g_param_spec_string ("type",
2932 + "type",
2933 + "type",
2934 + NULL,
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)
2940 g_free,
2941 (GDestroyNotify) g_object_unref);
2942 seat->priv->devices = g_ptr_array_new ();
2943 + seat->priv->manager_proxy = NULL;
2946 static void
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);
2956 CkSeat *
2957 ck_seat_new (const char *sid,
2958 - CkSeatKind kind)
2959 + CkSeatKind kind,
2960 + const char *type)
2962 GObject *object;
2964 object = g_object_new (CK_TYPE_SEAT,
2965 "id", sid,
2966 "kind", kind,
2967 + "type", type,
2968 NULL);
2970 return CK_SEAT (object);
2973 CkSeat *
2974 -ck_seat_new_with_devices (const char *sid,
2975 - CkSeatKind kind,
2976 - GPtrArray *devices)
2977 +ck_seat_new_with_devices_and_sessions (const char *sid,
2978 + CkSeatKind kind,
2979 + GPtrArray *devices,
2980 + GPtrArray *sessions)
2982 GObject *object;
2983 int i;
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);
2998 +static char *
2999 +generate_static_session_id (const char *sid,
3000 + const char *session_name)
3002 + const char *seat_name;
3003 + char *ssid;
3005 + seat_name = strrchr (sid, '/');
3007 + if (seat_name == NULL) {
3008 + g_warning ("Seat id '%s' lacks a /", sid);
3009 + seat_name = sid;
3010 + } else {
3011 + seat_name++;
3014 + ssid = g_strdup_printf ("%s/Session%s%s",
3015 + CK_DBUS_PATH, seat_name,
3016 + session_name);
3018 + return ssid;
3021 CkSeat *
3022 -ck_seat_new_from_file (const char *sid,
3023 +ck_seat_new_from_file (char **sid,
3024 const char *path)
3026 - GKeyFile *key_file;
3027 - gboolean res;
3028 - GError *error;
3029 - char *group;
3030 - CkSeat *seat;
3031 - gboolean hidden;
3032 - GPtrArray *devices;
3033 - char **device_list;
3034 - gsize ndevices;
3035 - gsize i;
3036 + GKeyFile *key_file;
3037 + gboolean res;
3038 + GError *error;
3039 + char *group;
3040 + CkSeat *seat;
3041 + char *read_sid;
3042 + gboolean hidden;
3043 + GPtrArray *sessions;
3044 + char **session_list;
3045 + gsize nsessions;
3046 + GPtrArray *devices;
3047 + char **device_list;
3048 + gsize ndevices;
3049 + gsize i;
3051 seat = NULL;
3053 + g_debug ("CkSeat: New seat from file.");
3055 key_file = g_key_file_new ();
3056 error = NULL;
3057 res = g_key_file_load_from_file (key_file,
3058 @@ -1146,9 +1830,52 @@ ck_seat_new_from_file (const char *sid,
3059 goto out;
3062 + read_sid = g_key_file_get_string (key_file, group, "ID", NULL);
3063 + if (IS_STR_SET (read_sid)) {
3064 + g_free (*sid);
3065 + *sid = g_strdup_printf ("%s/%s", CK_DBUS_PATH, read_sid);
3066 + } else {
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++) {
3075 + char *path;
3076 + char *file;
3077 + char *ssid;
3078 + CkSession *session;
3080 + file = g_strconcat (session_list[i], ".session", NULL);
3081 + path = g_build_filename (CK_SESSION_DIR, file, NULL);
3082 + g_free (file);
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
3087 + */
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);
3094 + g_free (path);
3095 + continue;
3097 + g_free (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,
3113 g_strfreev (split);
3115 g_strfreev (device_list);
3116 - g_free (group);
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);
3122 + g_free (group);
3124 out:
3126 g_key_file_free (key_file);
3127 @@ -1356,10 +2084,15 @@ ck_seat_dump (CkSeat *seat,
3129 error = NULL;
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",
3132 - seat->priv->id,
3133 - error->message);
3134 - g_error_free (error);
3135 + if (error) {
3136 + g_warning ("Cannot get session id for active session on seat %s: %s",
3137 + seat->priv->id,
3138 + error->message);
3139 + g_error_free (error);
3140 + } else {
3141 + g_warning ("Cannot get session id for active session on seat %s",
3142 + seat->priv->id);
3144 } else {
3145 g_key_file_set_string (key_file,
3146 group_name,
3147 @@ -1371,3 +2104,24 @@ ck_seat_dump (CkSeat *seat,
3149 g_free (group_name);
3152 +gboolean
3153 +ck_seat_is_managed (CkSeat *seat)
3155 + return seat->priv->manager_proxy != NULL;
3158 +CkSession *
3159 +ck_seat_get_session (CkSeat *seat,
3160 + const char *ssid)
3162 + CkSession *session;
3164 + session = g_hash_table_lookup (seat->priv->sessions, ssid);
3166 + if (session == NULL) {
3167 + return 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
3174 --- a/src/ck-seat.h
3175 +++ b/src/ck-seat.h
3176 @@ -47,6 +47,18 @@ typedef struct
3178 GObjectClass parent_class;
3180 + void (* remove_request) (CkSeat *seat);
3181 + void (* open_session_request) (CkSeat *seat,
3182 + const char *ssid,
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,
3193 const char *ssid);
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);
3204 } CkSeatClass;
3206 typedef enum
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,
3211 - CkSeatKind kind);
3212 -CkSeat * ck_seat_new_from_file (const char *sid,
3213 - const char *path);
3214 -CkSeat * ck_seat_new_with_devices (const char *sid,
3215 CkSeatKind kind,
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,
3221 + CkSeatKind kind,
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,
3229 CkSeatKind *kind,
3230 GError **error);
3231 +gboolean ck_seat_get_type_string (CkSeat *seat,
3232 + char **type,
3233 + GError **error);
3234 gboolean ck_seat_add_session (CkSeat *seat,
3235 CkSession *session,
3236 GError **error);
3237 gboolean ck_seat_remove_session (CkSeat *seat,
3238 CkSession *session,
3239 GError **error);
3240 +gboolean ck_seat_request_open_session (CkSeat *seat,
3241 + CkSession *session,
3242 + GError **error);
3243 +gboolean ck_seat_request_close_session (CkSeat *seat,
3244 + CkSession *session,
3245 + GError **error);
3246 gboolean ck_seat_add_device (CkSeat *seat,
3247 GValueArray *device,
3248 GError **error);
3249 gboolean ck_seat_remove_device (CkSeat *seat,
3250 GValueArray *device,
3251 GError **error);
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,
3261 const char *ssid,
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,
3270 + GError **error);
3272 G_END_DECLS
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
3290 @@ -40,6 +40,7 @@
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
3299 char *seat_id;
3301 char *session_type;
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;
3308 guint uid;
3310 + CkDisplayTemplate *display_template;
3311 + GHashTable *display_variables;
3313 gboolean active;
3314 gboolean is_local;
3315 + gboolean is_open;
3316 + gboolean ever_open;
3317 + gboolean under_request;
3318 + GMutex *mutex_under_request;
3320 GTimeVal creation_time;
3322 @@ -74,6 +83,8 @@ struct CkSessionPrivate
3323 gboolean idle_hint;
3324 GTimeVal idle_since_hint;
3326 + gboolean remove_on_close;
3328 DBusGConnection *connection;
3329 DBusGProxy *bus_proxy;
3331 @@ -91,17 +102,24 @@ enum {
3332 PROP_0,
3333 PROP_ID,
3334 PROP_COOKIE,
3335 + PROP_SEAT_ID,
3336 PROP_USER,
3337 PROP_UNIX_USER,
3338 PROP_X11_DISPLAY,
3339 PROP_X11_DISPLAY_DEVICE,
3340 PROP_DISPLAY_DEVICE,
3341 PROP_SESSION_TYPE,
3342 + PROP_DISPLAY_TYPE,
3343 + PROP_DISPLAY_TEMPLATE,
3344 + PROP_DISPLAY_VARIABLES,
3345 PROP_REMOTE_HOST_NAME,
3346 PROP_LOGIN_SESSION_ID,
3347 PROP_IS_LOCAL,
3348 + PROP_IS_OPEN,
3349 + PROP_EVER_OPEN,
3350 PROP_ACTIVE,
3351 PROP_IDLE_HINT,
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.");
3363 error = NULL;
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)
3367 DBUS_PATH_DBUS,
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);
3376 + return FALSE;
3379 dbus_g_connection_register_g_object (session->priv->connection, session->priv->id, G_OBJECT (session));
3381 return TRUE;
3382 @@ -301,6 +330,40 @@ ck_session_set_idle_hint (CkSession
3385 gboolean
3386 +session_set_remove_on_close (CkSession *session,
3387 + gboolean remove_on_close,
3388 + GError **error)
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.");
3398 + else
3399 + g_debug ("CkSession: Setting remove on close to false.");
3401 + return TRUE;
3405 + Example:
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
3411 +gboolean
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);
3419 +gboolean
3420 ck_session_get_idle_hint (CkSession *session,
3421 gboolean *idle_hint,
3422 GError **error)
3423 @@ -366,6 +429,7 @@ ck_session_activate (CkSession
3425 gboolean res;
3427 + g_debug ("CkSession: Session activate.");
3428 g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3430 res = 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
3443 gboolean
3444 +ck_session_set_is_open (CkSession *session,
3445 + gboolean is_open,
3446 + GError **error)
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;
3455 + return TRUE;
3458 +gboolean
3459 +ck_session_set_ever_open (CkSession *session,
3460 + gboolean ever_open,
3461 + GError **error)
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;
3469 + return TRUE;
3472 +static gboolean
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);
3481 + return FALSE;
3484 +gboolean
3485 +ck_session_set_under_request (CkSession *session,
3486 + gboolean under_request,
3487 + GError **error)
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;
3494 + } else {
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);
3502 + return TRUE;
3505 +gboolean
3506 ck_session_get_id (CkSession *session,
3507 char **id,
3508 GError **error)
3509 @@ -554,6 +682,20 @@ ck_session_get_creation_time (CkSession
3512 gboolean
3513 +ck_session_get_remove_on_close (CkSession *session,
3514 + gboolean *remove_on_close,
3515 + GError **error)
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;
3523 + return TRUE;
3526 +gboolean
3527 ck_session_get_session_type (CkSession *session,
3528 char **type,
3529 GError **error)
3530 @@ -568,6 +710,20 @@ ck_session_get_session_type (CkSession
3533 gboolean
3534 +ck_session_get_display_type (CkSession *session,
3535 + char **type,
3536 + GError **error)
3538 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3540 + if (type != NULL) {
3541 + *type = g_strdup (session->priv->display_type);
3544 + return TRUE;
3547 +gboolean
3548 ck_session_is_active (CkSession *session,
3549 gboolean *active,
3550 GError **error)
3551 @@ -596,6 +752,50 @@ ck_session_is_local (CkSession *ses
3554 gboolean
3555 +ck_session_is_open (CkSession *session,
3556 + gboolean *open,
3557 + GError **error)
3559 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3561 + if (open != NULL) {
3562 + *open = session->priv->is_open;
3565 + return TRUE;
3568 +gboolean
3569 +ck_session_get_ever_open (CkSession *session,
3570 + gboolean *open,
3571 + GError **error)
3573 + g_return_val_if_fail (CK_IS_SESSION (session), FALSE);
3575 + if (open != NULL) {
3576 + *open = session->priv->ever_open;
3579 + return TRUE;
3582 +gboolean
3583 +ck_session_get_under_request (CkSession *session,
3584 + gboolean *under_request,
3585 + GError **error)
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);
3595 + return TRUE;
3598 +gboolean
3599 ck_session_set_id (CkSession *session,
3600 const char *id,
3601 GError **error)
3602 @@ -608,6 +808,21 @@ ck_session_set_id (CkSession *sessi
3603 return TRUE;
3606 +static void
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);
3616 + } else {
3617 + session->priv->display_variables = NULL;
3621 gboolean
3622 ck_session_set_cookie (CkSession *session,
3623 const char *cookie,
3624 @@ -724,6 +939,54 @@ ck_session_set_session_type (CkSession
3625 return TRUE;
3628 +gboolean
3629 +ck_session_set_display_type (CkSession *session,
3630 + const char *type,
3631 + GError **error)
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);
3638 + return TRUE;
3641 +static gboolean
3642 +ck_session_set_display_template (CkSession *session,
3643 + CkDisplayTemplate *display_template,
3644 + GError **error)
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);
3655 + } else {
3656 + session->priv->display_template = NULL;
3659 + return TRUE;
3662 +GHashTable *
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);
3676 static void
3677 ck_session_set_property (GObject *object,
3678 guint prop_id,
3679 @@ -741,15 +1004,33 @@ ck_session_set_property (GObject
3680 case PROP_IS_LOCAL:
3681 ck_session_set_is_local (self, g_value_get_boolean (value), NULL);
3682 break;
3683 + case PROP_IS_OPEN:
3684 + ck_session_set_is_open (self, g_value_get_boolean (value), NULL);
3685 + break;
3686 + case PROP_EVER_OPEN:
3687 + ck_session_set_ever_open (self, g_value_get_boolean (value), NULL);
3688 + break;
3689 case PROP_ID:
3690 ck_session_set_id (self, g_value_get_string (value), NULL);
3691 break;
3692 case PROP_COOKIE:
3693 ck_session_set_cookie (self, g_value_get_string (value), NULL);
3694 break;
3695 + case PROP_SEAT_ID:
3696 + ck_session_set_seat_id (self, g_value_get_string (value), NULL);
3697 + break;
3698 case PROP_SESSION_TYPE:
3699 ck_session_set_session_type (self, g_value_get_string (value), NULL);
3700 break;
3701 + case PROP_DISPLAY_TYPE:
3702 + ck_session_set_display_type (self, g_value_get_string (value), NULL);
3703 + break;
3704 + case PROP_DISPLAY_TEMPLATE:
3705 + ck_session_set_display_template (self, g_value_get_object (value), NULL);
3706 + break;
3707 + case PROP_DISPLAY_VARIABLES:
3708 + ck_session_set_display_variables (self, g_value_get_boxed (value));
3709 + break;
3710 case PROP_X11_DISPLAY:
3711 ck_session_set_x11_display (self, g_value_get_string (value), NULL);
3712 break;
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));
3716 break;
3717 + case PROP_REMOVE_ON_CLOSE:
3718 + session_set_remove_on_close (self, g_value_get_boolean (value), NULL);
3719 + break;
3720 default:
3721 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3722 break;
3723 @@ -797,15 +1081,33 @@ ck_session_get_property (GObject *obj
3724 case PROP_IS_LOCAL:
3725 g_value_set_boolean (value, self->priv->is_local);
3726 break;
3727 + case PROP_IS_OPEN:
3728 + g_value_set_boolean (value, self->priv->is_open);
3729 + break;
3730 + case PROP_EVER_OPEN:
3731 + g_value_set_boolean (value, self->priv->ever_open);
3732 + break;
3733 case PROP_ID:
3734 g_value_set_string (value, self->priv->id);
3735 break;
3736 case PROP_COOKIE:
3737 g_value_set_string (value, self->priv->cookie);
3738 break;
3739 + case PROP_SEAT_ID:
3740 + g_value_set_string (value, self->priv->seat_id);
3741 + break;
3742 case PROP_SESSION_TYPE:
3743 g_value_set_string (value, self->priv->session_type);
3744 break;
3745 + case PROP_DISPLAY_TYPE:
3746 + g_value_set_string (value, self->priv->display_type);
3747 + break;
3748 + case PROP_DISPLAY_TEMPLATE:
3749 + g_value_set_object (value, self->priv->display_template);
3750 + break;
3751 + case PROP_DISPLAY_VARIABLES:
3752 + g_value_set_boxed (value, self->priv->display_variables);
3753 + break;
3754 case PROP_X11_DISPLAY:
3755 g_value_set_string (value, self->priv->x11_display);
3756 break;
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);
3760 break;
3761 + case PROP_REMOVE_ON_CLOSE:
3762 + g_value_set_boolean (value, self->priv->remove_on_close);
3763 + break;
3764 default:
3765 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3766 break;
3767 @@ -881,6 +1186,8 @@ session_add_activity_watch (CkSession *s
3768 static void
3769 session_remove_activity_watch (CkSession *session)
3771 + g_debug ("CkSession: Remove activity watch.");
3773 if (session->priv->idle_monitor == NULL) {
3774 return;
3776 @@ -999,6 +1306,13 @@ ck_session_class_init (CkSessionClass *k
3777 "cookie",
3778 NULL,
3779 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
3780 + g_object_class_install_property (object_class,
3781 + PROP_SEAT_ID,
3782 + g_param_spec_string ("seat-id",
3783 + "seat id",
3784 + "seat id",
3785 + NULL,
3786 + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
3788 g_object_class_install_property (object_class,
3789 PROP_SESSION_TYPE,
3790 @@ -1008,6 +1322,27 @@ ck_session_class_init (CkSessionClass *k
3791 NULL,
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",
3796 + "session-type",
3797 + "session type",
3798 + NULL,
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",
3817 "login-session-id",
3818 @@ -1070,6 +1405,14 @@ ck_session_class_init (CkSessionClass *k
3819 FALSE,
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",
3825 + NULL,
3826 + NULL,
3827 + FALSE,
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,
3838 + g_str_equal,
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 ();
3849 static void
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)
3861 CkSession *
3862 +ck_session_new_from_file (const char *ssid,
3863 + const char *path)
3865 + GKeyFile *key_file;
3866 + gboolean res;
3867 + GError *error;
3868 + char *group;
3869 + char *name;
3870 + gboolean hidden;
3871 + char *type;
3872 + char *display_template_string;
3873 + CkSession *session;
3874 + GHashTable *display_variables;
3875 + char **type_keys;
3877 + g_debug ("CkSession: New session from file.");
3878 + key_file = g_key_file_new ();
3879 + error = NULL;
3880 + res = g_key_file_load_from_file (key_file,
3881 + path,
3882 + G_KEY_FILE_NONE,
3883 + &error);
3885 + if (! res) {
3886 + g_warning ("Unable to load sessions from file %s: %s",
3887 + path, error->message);
3888 + g_error_free (error);
3889 + return NULL;
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);
3896 + return NULL;
3899 + hidden = g_key_file_get_boolean (key_file, group, "Hidden", NULL);
3901 + if (hidden) {
3902 + g_debug ("CkSession: Session is hidden");
3903 + g_free (group);
3904 + g_key_file_free (key_file);
3905 + return NULL;
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);
3912 + g_free (group);
3913 + g_key_file_free (key_file);
3914 + return NULL;
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);
3921 + g_free (group);
3922 + g_key_file_free (key_file);
3923 + return NULL;
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);
3930 + g_free (group);
3931 + g_key_file_free (key_file);
3932 + return NULL;
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
3939 + * run X with.
3940 + */
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) {
3947 + int i;
3948 + for (i = 0; type_keys[i] != NULL; i++) {
3949 + char *string;
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);
3960 + g_free (group);
3961 + g_free (type);
3962 + g_hash_table_unref (display_variables);
3964 + return session;
3967 +CkSession *
3968 ck_session_new (const char *ssid,
3969 - const char *cookie)
3970 + const char *type,
3971 + const char *display_template_string,
3972 + GHashTable *display_variables)
3974 + CkDisplayTemplate *display_template;
3975 GObject *object;
3976 gboolean res;
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);
3984 + return NULL;
3987 object = g_object_new (CK_TYPE_SESSION,
3988 "id", ssid,
3989 - "cookie", cookie,
3990 + "session-type", type,
3991 + "display-type", display_template_string,
3992 + "display-template", display_template,
3993 + "display-variables", display_variables,
3994 NULL);
3996 res = register_session (CK_SESSION (object));
3997 if (! res) {
3998 g_object_unref (object);
3999 @@ -1138,9 +1612,80 @@ ck_session_new (const char *ssid,
4000 G_TYPE_VALUE, \
4001 G_TYPE_INVALID))
4003 +void
4004 +ck_session_set_parameters (CkSession *session,
4005 + const GPtrArray *parameters)
4007 + int i;
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++) {
4014 + gboolean res;
4015 + GValue val_struct = { 0, };
4016 + GValue value = { 0, };
4017 + char *prop_name;
4018 + GValue *prop_val;
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,
4025 + 0, &prop_name,
4026 + 1, &prop_val,
4027 + G_MAXUINT);
4028 + if (! res) {
4029 + g_debug ("CkSession: Unable to extract parameter input");
4030 + goto cont;
4033 + if (prop_name == NULL) {
4034 + g_debug ("CkSession: Skipping NULL parameter");
4035 + goto cont;
4038 + if (strcmp (prop_name, "id") == 0
4039 + || strcmp (prop_name, "cookie") == 0) {
4040 + g_debug ("CkSession: Skipping restricted parameter: %s", prop_name);
4041 + goto cont;
4044 + pspec = g_object_class_find_property (class, prop_name);
4045 + if (! pspec) {
4046 + g_debug ("CkSession: Skipping unknown parameter: %s", prop_name);
4047 + goto cont;
4050 + if (!(pspec->flags & G_PARAM_WRITABLE)) {
4051 + g_debug ("CkSession: property '%s' is not writable", pspec->name);
4052 + goto cont;
4055 + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
4056 + res = g_value_transform (prop_val, &value);
4057 + if (! res) {
4058 + g_debug ("CkSession: unable to transform property value for '%s'", pspec->name);
4059 + goto cont;
4062 + g_object_set_property (G_OBJECT (session), prop_name, &value);
4063 + g_value_unset (&value);
4064 + cont:
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);
4075 CkSession *
4076 ck_session_new_with_parameters (const char *ssid,
4077 - const char *cookie,
4078 const GPtrArray *parameters)
4080 GObject *object;
4081 @@ -1152,6 +1697,8 @@ ck_session_new_with_parameters (const ch
4082 GObjectClass *class;
4083 GType object_type;
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 (&params[n_params].value, ssid);
4092 n_params++;
4094 - params[n_params].name = g_strdup ("cookie");
4095 - params[n_params].value.g_type = 0;
4096 - g_value_init (&params[n_params].value, G_TYPE_STRING);
4097 - g_value_set_string (&params[n_params].value, cookie);
4098 - n_params++;
4100 if (parameters != NULL) {
4101 for (i = 0; i < parameters->len; i++) {
4102 gboolean res;
4103 @@ -1259,7 +1800,7 @@ ck_session_run_programs (CkSession *ses
4104 const char *action)
4106 int n;
4107 - char *extra_env[11]; /* be sure to adjust this as needed */
4108 + char *extra_env[12]; /* be sure to adjust this as needed */
4110 n = 0;
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,
4123 char *s;
4124 char *group_name;
4126 + if (!session->priv->is_open) {
4127 + return;
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,
4134 "type",
4135 NONULL_STRING (session->priv->session_type));
4137 + if (session->priv->display_type != NULL) {
4138 + g_key_file_set_string (key_file,
4139 + group_name,
4140 + "display_type",
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,
4145 group_name,
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
4150 @@ -25,6 +25,8 @@
4151 #include <glib-object.h>
4152 #include <dbus/dbus-glib.h>
4154 +#include "ck-display-template.h"
4156 G_BEGIN_DECLS
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);
4167 + const char *type,
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,
4179 gboolean is_local,
4180 GError **error);
4181 +gboolean ck_session_set_is_open (CkSession *session,
4182 + gboolean is_open,
4183 + GError **error);
4184 +gboolean ck_session_set_ever_open (CkSession *session,
4185 + gboolean ever_open,
4186 + GError **error);
4187 +gboolean ck_session_set_under_request (CkSession *session,
4188 + gboolean under_request,
4189 + GError **error);
4190 gboolean ck_session_set_id (CkSession *session,
4191 const char *ssid,
4192 GError **error);
4193 @@ -116,6 +132,11 @@ gboolean ck_session_set_remote_host_name (CkSession *se
4194 gboolean ck_session_set_session_type (CkSession *session,
4195 const char *type,
4196 GError **error);
4197 +gboolean ck_session_set_display_type (CkSession *session,
4198 + const char *type,
4199 + GError **error);
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,
4207 gboolean *local,
4208 GError **error);
4209 +gboolean ck_session_is_open (CkSession *session,
4210 + gboolean *open,
4211 + GError **error);
4212 +gboolean ck_session_get_ever_open (CkSession *session,
4213 + gboolean *open,
4214 + GError **error);
4215 +gboolean ck_session_get_under_request (CkSession *session,
4216 + gboolean *under_request,
4217 + GError **error);
4218 gboolean ck_session_get_unix_user (CkSession *session,
4219 guint *uid,
4220 GError **error);
4221 @@ -150,12 +180,18 @@ gboolean ck_session_get_login_session_id (CkSession *se
4222 gboolean ck_session_get_session_type (CkSession *session,
4223 char **type,
4224 GError **error);
4225 +gboolean ck_session_get_display_type (CkSession *session,
4226 + char **type,
4227 + GError **error);
4228 gboolean ck_session_get_remote_host_name (CkSession *session,
4229 char **host_name,
4230 GError **error);
4231 gboolean ck_session_get_creation_time (CkSession *session,
4232 char **iso8601_datetime,
4233 GError **error);
4234 +gboolean ck_session_get_remove_on_close (CkSession *session,
4235 + gboolean *remove_on_close,
4236 + GError **error);
4237 /*deprecated*/
4238 gboolean ck_session_get_user (CkSession *session,
4239 guint *uid,
4240 @@ -171,6 +207,12 @@ gboolean ck_session_get_idle_since_hint (CkSession *se
4241 gboolean ck_session_set_idle_hint (CkSession *session,
4242 gboolean idle_hint,
4243 DBusGMethodInvocation *context);
4244 +gboolean session_set_remove_on_close (CkSession *session,
4245 + gboolean remove_on_close,
4246 + GError **error);
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 @@
4260 </doc:doc>
4261 </method>
4263 + <method name="GetUnmanagedSeats">
4264 + <arg name="seats" direction="out" type="ao">
4265 + <doc:doc>
4266 + <doc:summary>an array of unmanaged Seat IDs</doc:summary>
4267 + </doc:doc>
4268 + </arg>
4269 + <doc:doc>
4270 + <doc:description>
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>
4277 + </doc:doc>
4278 + </method>
4280 <method name="GetSessions">
4281 <arg name="sessions" direction="out" type="ao">
4282 <doc:doc>
4283 @@ -196,6 +213,22 @@
4284 </doc:description>
4285 </doc:doc>
4286 </method>
4288 + <method name="WillNotRespawn">
4289 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4290 + <arg name="ssid" type="o" direction="in">
4291 + <doc:doc>
4292 + <doc:summary>The session id of the session</doc:summary>
4293 + </doc:doc>
4294 + </arg>
4295 + <doc:doc>
4296 + <doc:description>
4297 + <doc:para>This may be used to set Remove On Close for a Session.
4298 + </doc:para>
4299 + </doc:description>
4300 + </doc:doc>
4301 + </method>
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 @@
4307 </doc:doc>
4308 </method>
4310 + <method name="AddSeat">
4311 + <arg name="type" type="s" direction="in">
4312 + <doc:doc>
4313 + <doc:summary>The type of seat to add</doc:summary>
4314 + </doc:doc>
4315 + </arg>
4316 + <arg name="sid" type="o" direction="out">
4317 + <doc:doc>
4318 + <doc:summary>The Seat ID of the added seat</doc:summary>
4319 + </doc:doc>
4320 + </arg>
4321 + <doc:doc>
4322 + <doc:description>
4323 + <doc:para>This method is to create a new seat
4324 + </doc:para>
4325 + </doc:description>
4326 + </doc:doc>
4327 + </method>
4328 + <method name="AddSeatById">
4329 + <arg name="type" type="s" direction="in">
4330 + <doc:doc>
4331 + <doc:summary>The type of seat to add</doc:summary>
4332 + </doc:doc>
4333 + </arg>
4334 + <arg name="sid" type="o" direction="in">
4335 + <doc:doc>
4336 + <doc:summary>The Seat ID of to be added seat</doc:summary>
4337 + </doc:doc>
4338 + </arg>
4339 + <doc:doc>
4340 + <doc:description>
4341 + <doc:para>This method is to create a new seat by specify given sid
4342 + </doc:para>
4343 + </doc:description>
4344 + </doc:doc>
4345 + </method>
4346 + <method name="RemoveSeat">
4347 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4348 + <arg name="sid" type="o" direction="in">
4349 + <doc:doc>
4350 + <doc:summary>The Seat ID of the seat to remove</doc:summary>
4351 + </doc:doc>
4352 + </arg>
4353 + <doc:doc>
4354 + <doc:description>
4355 + <doc:para>This method is to remove a seat
4356 + </doc:para>
4357 + </doc:description>
4358 + </doc:doc>
4359 + </method>
4360 + <method name="AddSession">
4361 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4362 + <arg name="sid" type="o">
4363 + <doc:doc>
4364 + <doc:summary>The seat to add the session to</doc:summary>
4365 + </doc:doc>
4366 + </arg>
4367 + <arg name="type" type="s">
4368 + <doc:doc>
4369 + <doc:summary>The type of session to run (e.g. "LoginWindow", "Chooser", etc)</doc:summary>
4370 + </doc:doc>
4371 + </arg>
4372 + <arg name="display_type" type="s">
4373 + <doc:doc>
4374 + <doc:summary>The name of the display type to use (defined in displays.d)</doc:summary>
4375 + </doc:doc>
4376 + </arg>
4377 + <arg name="variables" type="a{ss}">
4378 + <doc:doc>
4379 + <doc:summary>Session type specific parameters</doc:summary>
4380 + </doc:doc>
4381 + </arg>
4382 + <arg name="ssid" direction="out" type="o">
4383 + <doc:doc>
4384 + <doc:summary>Session ID</doc:summary>
4385 + </doc:doc>
4386 + </arg>
4387 + <doc:doc>
4388 + <doc:description>
4389 + <doc:para>Request a new session gets added to seat.</doc:para>
4390 + </doc:description>
4391 + </doc:doc>
4392 + </method>
4393 + <method name="RemoveSession">
4394 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4395 + <arg name="ssid" type="o" direction="in">
4396 + <doc:doc>
4397 + <doc:summary>The session id of the session to remove</doc:summary>
4398 + </doc:doc>
4399 + </arg>
4400 + <doc:doc>
4401 + <doc:description>
4402 + <doc:para>This method is to remove a session from a seat
4403 + </doc:para>
4404 + </doc:description>
4405 + </doc:doc>
4406 + </method>
4408 <signal name="SeatAdded">
4409 <arg name="sid" type="o">
4410 <doc:doc>
4411 <doc:summary>The Seat ID for the added seat</doc:summary>
4412 </doc:doc>
4413 </arg>
4414 + <arg name="type" type="s">
4415 + <doc:doc>
4416 + <doc:summary>The type of seat added.</doc:summary>
4417 + </doc:doc>
4418 + </arg>
4419 <doc:doc>
4420 <doc:description>
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>
4427 </doc:doc>
4428 </method>
4430 + <method name="Manage">
4431 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4432 + <doc:doc>
4433 + <doc:description>
4434 + <doc:para>Attempt to create unmanaged sessions for this seat.</doc:para>
4435 + </doc:description>
4436 + </doc:doc>
4437 + </method>
4439 + <method name="Unmanage">
4440 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4441 + <doc:doc>
4442 + <doc:description>
4443 + <doc:para>Stop managing seat.</doc:para>
4444 + </doc:description>
4445 + </doc:doc>
4446 + </method>
4448 <signal name="ActiveSessionChanged">
4449 <arg name="ssid" type="o">
4450 <doc:doc>
4451 @@ -160,5 +178,73 @@ seat at a time.</doc:para>
4452 </doc:description>
4453 </doc:doc>
4454 </signal>
4455 + <signal name="OpenSessionRequest">
4456 + <arg name="ssid" type="o">
4457 + <doc:doc>
4458 + <doc:summary>The session id of the session to add</doc:summary>
4459 + </doc:doc>
4460 + </arg>
4461 + <arg name="session_type" type="s">
4462 + <doc:doc>
4463 + <doc:summary>The type of session to run (e.g. "LoginWindow", "Chooser", etc)</doc:summary>
4464 + </doc:doc>
4465 + </arg>
4466 + <arg name="display_template_name" type="s">
4467 + <doc:doc>
4468 + <doc:summary>The name of display template </doc:summary>
4469 + </doc:doc>
4470 + </arg>
4471 + <arg name="parameters" type="a{ss}">
4472 + <doc:doc>
4473 + <doc:summary>Session type specific parameters</doc:summary>
4474 + </doc:doc>
4475 + </arg>
4476 + <arg name="display_type" type="s">
4477 + <doc:doc>
4478 + <doc:summary>The type of display to use (e.g. "X11", "Command", "XDMCP", etc)</doc:summary>
4479 + </doc:doc>
4480 + </arg>
4481 + <arg name="display_parameters" type="a{ss}">
4482 + <doc:doc>
4483 + <doc:summary>Display type specific parameters</doc:summary>
4484 + </doc:doc>
4485 + </arg>
4486 + <doc:doc>
4487 + <doc:description>
4488 + <doc:para>Emitted when a new session should get added to the seat.</doc:para>
4489 + </doc:description>
4490 + </doc:doc>
4491 + </signal>
4492 + <signal name="CloseSessionRequest">
4493 + <arg name="ssid" type="o">
4494 + <doc:doc>
4495 + <doc:summary>The session id of the session to remove</doc:summary>
4496 + </doc:doc>
4497 + </arg>
4498 + <doc:doc>
4499 + <doc:description>
4500 + <doc:para>Emitted when a session with given display number need to be removed.</doc:para>
4501 + </doc:description>
4502 + </doc:doc>
4503 + </signal>
4504 + <signal name="NoRespawn">
4505 + <arg name="ssid" type="o">
4506 + <doc:doc>
4507 + <doc:summary>The session id of the session to not respawn</doc:summary>
4508 + </doc:doc>
4509 + </arg>
4510 + <doc:doc>
4511 + <doc:description>
4512 + <doc:para>Emitted when ck-seat-tool indicates a session is to be removed.</doc:para>
4513 + </doc:description>
4514 + </doc:doc>
4515 + </signal>
4516 + <signal name="RemoveRequest">
4517 + <doc:doc>
4518 + <doc:description>
4519 + <doc:para>Emitted when seat needs to get removed.</doc:para>
4520 + </doc:description>
4521 + </doc:doc>
4522 + </signal>
4523 </interface>
4524 </node>
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
4529 @@ -52,6 +52,19 @@
4530 <doc:seealso><doc:ref type="property" to="Session:session-type">session-type</doc:ref></doc:seealso>
4531 </doc:doc>
4532 </method>
4533 + <method name="GetDisplayType">
4534 + <arg name="type" direction="out" type="s">
4535 + <doc:doc>
4536 + <doc:summary>Display type</doc:summary>
4537 + </doc:doc>
4538 + </arg>
4539 + <doc:doc>
4540 + <doc:description>
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>
4544 + </doc:doc>
4545 + </method>
4546 <method name="GetUser">
4547 <arg name="uid" direction="out" type="u">
4548 <doc:doc>
4549 @@ -174,6 +187,18 @@
4550 <doc:seealso><doc:ref type="property" to="Session:is-local">is-local</doc:ref></doc:seealso>
4551 </doc:doc>
4552 </method>
4553 + <method name="IsOpen">
4554 + <arg name="open" direction="out" type="b">
4555 + <doc:doc>
4556 + <doc:summary>TRUE if the session is open, otherwise FALSE</doc:summary>
4557 + </doc:doc>
4558 + </arg>
4559 + <doc:doc>
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>
4563 + </doc:doc>
4564 + </method>
4565 <method name="GetCreationTime">
4566 <arg name="iso8601_datetime" type="s" direction="out">
4567 <doc:doc>
4568 @@ -275,6 +300,21 @@
4569 </doc:description>
4570 </doc:doc>
4571 </method>
4572 + <method name="SetRemoveOnClose">
4573 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
4574 + <arg name="remove_on_close" type="b" direction="in">
4575 + <doc:doc>
4576 + <doc:summary>boolean value to set the remove-on-close to</doc:summary>
4577 + </doc:doc>
4578 + </arg>
4579 + <doc:doc>
4580 + <doc:description>
4581 + <doc:para>This may be used by the session to indicate that
4582 + it should be respawn or not when it is closed.
4583 + </doc:para>
4584 + </doc:description>
4585 + </doc:doc>
4586 + </method>
4588 <signal name="ActiveChanged">
4589 <arg name="is_active" type="b">
4590 @@ -317,6 +357,19 @@
4591 </doc:doc>
4592 </signal>
4594 + <property name="session" type="o" access="readwrite">
4595 + <doc:doc>
4596 + <doc:description>
4597 + <doc:para>The id of the session.</doc:para>
4598 + <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>
4602 + signal.
4603 + </doc:para>
4604 + </doc:description>
4605 + </doc:doc>
4606 + </property>
4607 <property name="unix-user" type="u" access="readwrite">
4608 <doc:doc>
4609 <doc:description>
4610 @@ -342,6 +395,16 @@
4611 </doc:description>
4612 </doc:doc>
4613 </property>
4614 + <property name="display-type" type="s" access="readwrite">
4615 + <doc:doc>
4616 + <doc:description>
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/.
4620 + </doc:para>
4621 + </doc:description>
4622 + </doc:doc>
4623 + </property>
4624 <property name="remote-host-name" type="s" access="readwrite">
4625 <doc:doc>
4626 <doc:description>
4627 @@ -396,6 +459,19 @@
4628 </doc:description>
4629 </doc:doc>
4630 </property>
4631 + <property name="is-open" type="b" access="readwrite">
4632 + <doc:doc>
4633 + <doc:description>
4634 + <doc:para>
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>
4639 + method.
4640 + </doc:para>
4641 + </doc:description>
4642 + </doc:doc>
4643 + </property>
4644 <property name="is-local" type="b" access="readwrite">
4645 <doc:doc>
4646 <doc:description>
4647 @@ -408,6 +484,14 @@
4648 </doc:description>
4649 </doc:doc>
4650 </property>
4651 + <property name="is-dynamic" type="b" access="readwrite">
4652 + <doc:doc>
4653 + <doc:description>
4654 + <doc:para>
4655 + Whether the session is dynamic</doc:para>
4656 + </doc:description>
4657 + </doc:doc>
4658 + </property>
4659 <property name="idle-hint" type="b" access="readwrite">
4660 <doc:doc>
4661 <doc:description>
4662 @@ -430,6 +514,14 @@
4663 </doc:description>
4664 </doc:doc>
4665 </property>
4666 + <property name="remove-on-close" type="b" access="readwrite">
4667 + <doc:doc>
4668 + <doc:description>
4669 + <doc:para>
4670 + Whether the session respawn when it is closed</doc:para>
4671 + </doc:description>
4672 + </doc:doc>
4673 + </property>
4675 </interface>
4676 </node>
4677 diff --git a/src/strverscmp.c b/src/strverscmp.c
4678 new file mode 100644
4679 index 0000000..f077651
4680 --- /dev/null
4681 +++ b/src/strverscmp.c
4682 @@ -0,0 +1,131 @@
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. */
4702 +#if !_LIBC
4703 +# include <config.h>
4704 +#endif
4706 +#include <string.h>
4707 +#include <ctype.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 */
4711 +#define S_N 0x0
4712 +#define S_I 0x4
4713 +#define S_F 0x8
4714 +#define S_Z 0xC
4716 +/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
4717 +#define CMP 2
4718 +#define LEN 3
4721 +/* ISDIGIT differs from isdigit, as follows:
4722 + - Its arg may be any int or unsigned int; it need not be an unsigned char
4723 + or EOF.
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
4731 +#undef strverscmp
4733 +#ifndef weak_alias
4734 +# define __strverscmp strverscmp
4735 +#endif
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).
4742 +int
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;
4748 + int state;
4749 + int diff;
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
4760 + };
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,
4774 + -1, CMP, CMP, CMP
4775 + };
4777 + if (p1 == p2)
4778 + return 0;
4780 + c1 = *p1++;
4781 + c2 = *p2++;
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];
4788 + c1 = *p1++;
4789 + c2 = *p2++;
4790 + state |= (c1 == '0') + (ISDIGIT (c1) != 0);
4793 + state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))];
4795 + switch (state)
4797 + case CMP:
4798 + return diff;
4800 + case LEN:
4801 + while (ISDIGIT (*p1++))
4802 + if (!ISDIGIT (*p2++))
4803 + return 1;
4805 + return ISDIGIT (*p2) ? -1 : diff;
4807 + default:
4808 + return state;
4811 +#ifdef weak_alias
4812 +weak_alias (__strverscmp, strverscmp)
4813 +#endif
4814 diff --git a/src/strverscmp.h b/src/strverscmp.h
4815 new file mode 100644
4816 index 0000000..48670c8
4817 --- /dev/null
4818 +++ b/src/strverscmp.h
4819 @@ -0,0 +1,25 @@
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 \
4853 + ck-seat-tool \
4854 $(NULL)
4856 ck_launch_session_SOURCES = \
4857 @@ -83,6 +84,14 @@ ck_history_LDADD = \
4858 $(top_builddir)/src/libck-event-log.la \
4859 $(NULL)
4861 +ck_seat_tool_SOURCES = \
4862 + ck-seat-tool.c \
4863 + $(NULL)
4865 +ck_seat_tool_LDADD = \
4866 + $(CONSOLE_KIT_LIBS) \
4867 + $(NULL)
4869 ck_log_system_start_SOURCES = \
4870 ck-log-system-start.c \
4871 $(NULL)
4872 diff --git a/tools/ck-seat-tool.c b/tools/ck-seat-tool.c
4873 new file mode 100644
4874 index 0000000..0879d0d
4875 --- /dev/null
4876 +++ b/tools/ck-seat-tool.c
4877 @@ -0,0 +1,449 @@
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>
4899 + */
4901 +#include "config.h"
4903 +#include <stdlib.h>
4904 +#include <stdio.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 },
4943 + { NULL }
4946 +static void
4947 +add_session (DBusGConnection *connection)
4949 + DBusGProxy *mgr_proxy = NULL;
4950 + DBusGProxy *seat_proxy = NULL;
4951 + GError *error = NULL;
4952 + gboolean res;
4953 + char *sid = NULL;
4954 + GPtrArray *seats;
4955 + char *ssid = NULL;
4956 + int i;
4957 + gboolean found;
4958 + char *sstype = NULL;
4959 + GHashTable *variables = NULL;
4961 + if (! IS_STR_SET (session_type)) {
4962 + sstype = g_strdup ("LoginWindow");
4963 + } else {
4964 + sstype = g_strdup (session_type);
4967 + mgr_proxy = dbus_g_proxy_new_for_name (connection,
4968 + CK_NAME,
4969 + CK_MANAGER_PATH,
4970 + CK_MANAGER_INTERFACE);
4971 + if (mgr_proxy == NULL) {
4972 + return;
4975 + if (! IS_STR_SET(seat_id)) {
4977 + /* If seat id is not given, create a new seat */
4978 + error = NULL;
4979 + res = dbus_g_proxy_call (mgr_proxy,
4980 + "AddSeat",
4981 + &error,
4982 + G_TYPE_STRING, "Default",
4983 + G_TYPE_INVALID,
4984 + DBUS_TYPE_G_OBJECT_PATH, &sid,
4985 + G_TYPE_INVALID);
4986 + if (!res) {
4987 + g_warning ("Unable to add seat: %s", error->message);
4988 + g_error_free (error);
4989 + g_object_unref (mgr_proxy);
4990 + return;
4993 + } else {
4994 + if (!g_str_has_prefix (seat_id, CK_PATH_PREFIX)) {
4995 + sid = g_strdup_printf ("%s%s", CK_PATH_PREFIX, seat_id);
4996 + } else {
4997 + sid = g_strdup (seat_id);
4999 + /* Check whether seat is existing, if not, try to create it. */
5001 + error = NULL;
5002 + res = dbus_g_proxy_call (mgr_proxy,
5003 + "GetSeats",
5004 + &error,
5005 + G_TYPE_INVALID,
5006 + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
5007 + &seats,
5008 + G_TYPE_INVALID);
5009 + if (!res) {
5010 + g_warning ("Unable to get seat list: %s", error->message);
5011 + g_error_free (error);
5012 + g_object_unref (mgr_proxy);
5013 + return;
5016 + found = FALSE;
5017 + for (i = 0; i < seats->len; i++) {
5018 + char *tmp_sid;
5020 + tmp_sid = g_ptr_array_index (seats, i);
5021 + if (g_str_equal (sid, tmp_sid)) {
5022 + found = TRUE;
5023 + g_free (tmp_sid);
5024 + break;
5027 + g_free (tmp_sid);
5030 + if (! found) {
5031 + error = NULL;
5032 + res = dbus_g_proxy_call (mgr_proxy,
5033 + "AddSeatById",
5034 + &error,
5035 + G_TYPE_STRING, "Default",
5036 + DBUS_TYPE_G_OBJECT_PATH, sid,
5037 + G_TYPE_INVALID,
5038 + G_TYPE_INVALID);
5039 + if (!res) {
5040 + g_warning ("Unable to add seat: %s", error->message);
5041 + g_error_free (error);
5042 + g_object_unref (mgr_proxy);
5043 + return;
5048 + seat_proxy = dbus_g_proxy_new_for_name (connection,
5049 + CK_NAME,
5050 + sid,
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);
5056 + return;
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++) {
5065 + char **arr;
5067 + /* split var=value */
5068 + arr = g_strsplit (remaining_args [i], "=", 2);
5069 + if (arr[0] && arr[1]) {
5070 + g_hash_table_insert (variables,
5071 + g_strdup(arr[0]),
5072 + g_strdup (arr[1]));
5074 + g_strfreev (arr);
5078 + error = NULL;
5079 + res = dbus_g_proxy_call (mgr_proxy,
5080 + "AddSession",
5081 + &error,
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,
5086 + G_TYPE_INVALID,
5087 + DBUS_TYPE_G_OBJECT_PATH, &ssid,
5088 + G_TYPE_INVALID);
5090 + if (!res) {
5091 + g_warning ("Unable to add dynamic session: %s", error->message);
5092 + g_error_free (error);
5093 + } else {
5094 + dbus_g_proxy_call_no_reply (seat_proxy,
5095 + "Manage",
5096 + G_TYPE_INVALID,
5097 + G_TYPE_INVALID);
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);
5105 +static gboolean
5106 +is_session_on_seat (DBusGConnection *connection,
5107 + const char *sid,
5108 + const char *ssid,
5109 + gboolean *is_last_session)
5112 + DBusGProxy *seat_proxy = NULL;
5113 + GPtrArray *sessions = NULL;
5114 + char *ssid_tmp = NULL;
5115 + gboolean res;
5116 + gboolean retval = FALSE;
5117 + int i;
5118 + GError *error = NULL;
5120 + seat_proxy = dbus_g_proxy_new_for_name (connection,
5121 + CK_NAME,
5122 + sid,
5123 + CK_SEAT_INTERFACE);
5125 + if (seat_proxy == NULL) {
5126 + g_warning ("Failed to talk to seat '%s'", sid);
5127 + return FALSE;
5130 + error = NULL;
5131 + res = dbus_g_proxy_call (seat_proxy,
5132 + "GetSessions",
5133 + &error,
5134 + G_TYPE_INVALID,
5135 + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
5136 + &sessions,
5137 + G_TYPE_INVALID);
5138 + if (! res) {
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);
5142 + return FALSE;
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)) {
5150 + retval = TRUE;
5151 + break;
5154 + g_free (ssid_tmp);
5155 + ssid_tmp = NULL;
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);
5165 + return retval;
5168 +static char *
5169 +find_seat_id_from_session_id (DBusGConnection *connection,
5170 + DBusGProxy *proxy,
5171 + const char *ssid,
5172 + gboolean *is_last_session)
5174 + GError *error;
5175 + GPtrArray *seats;
5176 + int i;
5177 + char *sid;
5178 + gboolean res;
5180 + error = NULL;
5181 + res = dbus_g_proxy_call (proxy,
5182 + "GetSeats",
5183 + &error,
5184 + G_TYPE_INVALID,
5185 + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
5186 + &seats,
5187 + G_TYPE_INVALID);
5189 + if (! res) {
5190 + g_warning ("Failed to get list of seats: %s", error->message);
5191 + g_error_free (error);
5192 + return NULL;
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)) {
5199 + break;
5202 + g_free (sid);
5204 + g_ptr_array_free (seats, TRUE);
5206 + return sid;
5209 +static void
5210 +delete_session (DBusGConnection *connection)
5212 + DBusGProxy *proxy;
5213 + char *ssid;
5214 + char *sid;
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);
5219 + } else {
5220 + ssid = g_strdup (session_id);
5223 + proxy = dbus_g_proxy_new_for_name (connection,
5224 + CK_NAME,
5225 + CK_MANAGER_PATH,
5226 + CK_MANAGER_INTERFACE);
5227 + if (proxy == NULL) {
5228 + return;
5231 + sid = find_seat_id_from_session_id (connection, proxy, ssid, &is_last_session);
5233 + dbus_g_proxy_call_no_reply (proxy,
5234 + "WillNotRespawn",
5235 + DBUS_TYPE_G_OBJECT_PATH, ssid,
5236 + G_TYPE_INVALID,
5237 + G_TYPE_INVALID);
5239 + dbus_g_proxy_call_no_reply (proxy,
5240 + "RemoveSession",
5241 + DBUS_TYPE_G_OBJECT_PATH, ssid,
5242 + G_TYPE_INVALID,
5243 + G_TYPE_INVALID);
5245 + if (is_last_session) {
5246 + dbus_g_proxy_call_no_reply (proxy,
5247 + "RemoveSeat",
5248 + DBUS_TYPE_G_OBJECT_PATH, sid,
5249 + G_TYPE_INVALID,
5250 + G_TYPE_INVALID);
5253 + g_object_unref (proxy);
5256 +int
5257 +main (int argc, char *argv[])
5259 + DBusGConnection *connection;
5260 + GOptionContext *ctx;
5261 + GError *error = NULL;
5262 + gboolean res;
5264 + g_type_init ();
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);
5271 + if (!res) {
5272 + if (error) {
5273 + g_warning ("%s", error->message);
5274 + g_error_free (error);
5276 + exit (1);
5279 + g_option_context_free (ctx);
5281 + if (show_version) {
5282 + g_print ("%s %s\n", argv[0], VERSION);
5283 + exit (0);
5286 + if (add && delete) {
5287 + g_warning ("Can not specify -a and -d at the same time!");
5288 + exit (1);
5291 + if (!add && !delete) {
5292 + g_warning ("Must specify -a, -d!");
5293 + exit (1);
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");
5298 + exit (1);
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!");
5304 + exit (1);
5307 + error = NULL;
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);
5312 + exit (1);
5316 + if (add) {
5317 + add_session (connection);
5318 + } else if (delete) {
5319 + delete_session (connection);
5320 + } else {
5321 + g_warning ("Invaild parameters!");
5322 + exit (1);
5325 + return 0;
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
5331 @@ -46,6 +46,23 @@
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 {
5338 + char *prop_name;
5339 + char *prop_value;
5340 +} 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 },
5349 + { NULL }
5352 static gboolean
5353 get_uint (DBusGProxy *proxy,
5354 const char *method,
5355 @@ -176,6 +193,7 @@ list_session (DBusGConnection *connection,
5356 char *sid;
5357 char *lsid;
5358 char *session_type;
5359 + char *display_type;
5360 char *x11_display;
5361 char *x11_display_device;
5362 char *display_device;
5363 @@ -184,8 +202,11 @@ list_session (DBusGConnection *connection,
5364 char *idle_since_hint;
5365 gboolean is_active;
5366 gboolean is_local;
5367 + gboolean is_open;
5368 char *short_sid;
5369 const char *short_ssid;
5370 + char **format_arr = NULL;
5371 + int i, j;
5373 proxy = dbus_g_proxy_new_for_name (connection,
5374 CK_NAME,
5375 @@ -198,6 +219,7 @@ list_session (DBusGConnection *connection,
5376 sid = NULL;
5377 lsid = NULL;
5378 session_type = NULL;
5379 + display_type = NULL;
5380 x11_display = 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) {
5399 + return;
5402 realname = get_real_name (uid);
5404 short_sid = sid;
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'",
5410 - short_ssid,
5411 - uid,
5412 - realname,
5413 - short_sid,
5414 - session_type,
5415 - is_active ? "TRUE" : "FALSE",
5416 - x11_display,
5417 - x11_display_device,
5418 - display_device,
5419 - remote_host_name,
5420 - is_local ? "TRUE" : "FALSE",
5421 - creation_time,
5422 - lsid);
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)},
5442 + };
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);
5451 + break;
5455 + printf ("\n");
5456 + g_strfreev (format_arr);
5458 + } else {
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);
5462 + else
5463 + printf ("\t%s = '%s'\n",
5464 + output[j].prop_name,
5465 + output[j].prop_value);
5468 - printf ("\n");
5470 g_free (idle_since_hint);
5471 g_free (creation_time);
5472 @@ -256,9 +309,11 @@ list_session (DBusGConnection *connection,
5473 g_free (sid);
5474 g_free (lsid);
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;
5486 gboolean retval;
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 },
5491 - { NULL }
5492 - };
5494 g_type_init ();