diff --git a/libck-connector/ck-connector.c b/libck-connector/ck-connector.c index 7f6f87f..fc03e2b 100644 --- a/libck-connector/ck-connector.c +++ b/libck-connector/ck-connector.c @@ -79,6 +79,7 @@ static struct { { "remote-host-name", DBUS_TYPE_STRING }, { "session-type", DBUS_TYPE_STRING }, { "is-local", DBUS_TYPE_BOOLEAN }, + { "is-dynamic", DBUS_TYPE_BOOLEAN }, { "unix-user", DBUS_TYPE_INT32 }, }; diff --git a/src/ck-log-event.c b/src/ck-log-event.c index 7e8ce10..398c570 100644 --- a/src/ck-log-event.c +++ b/src/ck-log-event.c @@ -213,6 +213,7 @@ event_seat_session_added_copy (CkLogSeatSessionAddedEvent *event, event_copy->session_display_device = g_strdup (event->session_display_device); event_copy->session_remote_host_name = g_strdup (event->session_remote_host_name); event_copy->session_is_local = event->session_is_local; + event_copy->session_is_dynamic = event->session_is_dynamic; event_copy->session_unix_user = event->session_unix_user; event_copy->session_creation_time = g_strdup (event->session_creation_time); } @@ -232,6 +233,7 @@ event_seat_session_removed_copy (CkLogSeatSessionRemovedEvent *event, event_copy->session_display_device = g_strdup (event->session_display_device); event_copy->session_remote_host_name = g_strdup (event->session_remote_host_name); event_copy->session_is_local = event->session_is_local; + event_copy->session_is_dynamic = event->session_is_dynamic; event_copy->session_unix_user = event->session_unix_user; event_copy->session_creation_time = g_strdup (event->session_creation_time); } @@ -410,7 +412,7 @@ add_log_for_seat_session_added (GString *str, e = (CkLogSeatSessionAddedEvent *)event; g_string_append_printf (str, - " 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'", + " 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-is-dynamic=%s session-unix-user=%u session-creation-time='%s'", e->seat_id ? e->seat_id : "", e->session_id ? e->session_id : "", e->session_type ? e->session_type : "", @@ -419,6 +421,7 @@ add_log_for_seat_session_added (GString *str, e->session_display_device ? e->session_display_device : "", e->session_remote_host_name ? e->session_remote_host_name : "", e->session_is_local ? "TRUE" : "FALSE", + e->session_is_dynamic ? "TRUE" : "FALSE", e->session_unix_user, e->session_creation_time ? e->session_creation_time : ""); } @@ -431,7 +434,7 @@ add_log_for_seat_session_removed (GString *str, e = (CkLogSeatSessionRemovedEvent *)event; g_string_append_printf (str, - " 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'", + " 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-is-dynamic=%s session-unix-user=%u session-creation-time='%s'", e->seat_id ? e->seat_id : "", e->session_id ? e->session_id : "", e->session_type ? e->session_type : "", @@ -440,6 +443,7 @@ add_log_for_seat_session_removed (GString *str, e->session_display_device ? e->session_display_device : "", e->session_remote_host_name ? e->session_remote_host_name : "", e->session_is_local ? "TRUE" : "FALSE", + e->session_is_dynamic ? "TRUE" : "FALSE", e->session_unix_user, e->session_creation_time ? e->session_creation_time : ""); } @@ -890,7 +894,7 @@ parse_log_for_seat_session_added (const GString *str, } error = NULL; - re = g_regex_new ("seat-id='(?P[a-zA-Z0-9/]+)' session-id='(?P[a-zA-Z0-9/]+)' session-type='(?P[a-zA-Z0-9 ]*)' session-x11-display='(?P[0-9a-zA-Z.:]*)' session-x11-display-device='(?P[^']*)' session-display-device='(?P[^']*)' session-remote-host-name='(?P[^']*)' session-is-local=(?P[a-zA-Z]*) session-unix-user=(?P[0-9]*) session-creation-time='(?P[^']*)'", 0, 0, &error); + re = g_regex_new ("seat-id='(?P[a-zA-Z0-9/]+)' session-id='(?P[a-zA-Z0-9/]+)' session-type='(?P[a-zA-Z0-9 ]*)' session-x11-display='(?P[0-9a-zA-Z.:]*)' session-x11-display-device='(?P[^']*)' session-display-device='(?P[^']*)' session-remote-host-name='(?P[^']*)' session-is-local=(?P[a-zA-Z]*) session-is-dynamic=(?P[a-zA-Z]*) session-unix-user=(?P[0-9]*) session-creation-time='(?P[^']*)'", 0, 0, &error); if (re == NULL) { g_warning (error->message); goto out; @@ -922,6 +926,14 @@ parse_log_for_seat_session_added (const GString *str, } g_free (tmp); + tmp = g_match_info_fetch_named (match_info, "sessionisdynamic"); + if (tmp != NULL && strcmp (tmp, "TRUE") == 0) { + e->session_is_dynamic = TRUE; + } else { + e->session_is_dynamic = FALSE; + } + g_free (tmp); + tmp = g_match_info_fetch_named (match_info, "sessionunixuser"); if (tmp != NULL) { gulong l; @@ -965,7 +977,7 @@ parse_log_for_seat_session_removed (const GString *str, } error = NULL; - re = g_regex_new ("seat-id='(?P[a-zA-Z0-9/]+)' session-id='(?P[a-zA-Z0-9/]+)' session-type='(?P[a-zA-Z0-9 ]*)' session-x11-display='(?P[0-9a-zA-Z.:]*)' session-x11-display-device='(?P[^']*)' session-display-device='(?P[^']*)' session-remote-host-name='(?P[^']*)' session-is-local=(?P[a-zA-Z]*) session-unix-user=(?P[0-9]*) session-creation-time='(?P[^']*)'", 0, 0, &error); + re = g_regex_new ("seat-id='(?P[a-zA-Z0-9/]+)' session-id='(?P[a-zA-Z0-9/]+)' session-type='(?P[a-zA-Z0-9 ]*)' session-x11-display='(?P[0-9a-zA-Z.:]*)' session-x11-display-device='(?P[^']*)' session-display-device='(?P[^']*)' session-remote-host-name='(?P[^']*)' session-is-local=(?P[a-zA-Z]*) session-is-dynamic=(?P[a-zA-Z]*) session-unix-user=(?P[0-9]*) session-creation-time='(?P[^']*)'", 0, 0, &error); if (re == NULL) { g_warning (error->message); goto out; @@ -997,6 +1009,14 @@ parse_log_for_seat_session_removed (const GString *str, } g_free (tmp); + tmp = g_match_info_fetch_named (match_info, "sessionisdynamic"); + if (tmp != NULL && strcmp (tmp, "TRUE") == 0) { + e->session_is_dynamic= TRUE; + } else { + e->session_is_dynamic = FALSE; + } + g_free (tmp); + tmp = g_match_info_fetch_named (match_info, "sessionunixuser"); if (tmp != NULL) { gulong l; diff --git a/src/ck-log-event.h b/src/ck-log-event.h index a54a34e..f95fb37 100644 --- a/src/ck-log-event.h +++ b/src/ck-log-event.h @@ -85,6 +85,7 @@ typedef struct char *session_display_device; char *session_remote_host_name; gboolean session_is_local; + gboolean session_is_dynamic; guint session_unix_user; char *session_creation_time; } CkLogSeatSessionAddedEvent; @@ -99,6 +100,7 @@ typedef struct char *session_display_device; char *session_remote_host_name; gboolean session_is_local; + gboolean session_is_dynamic; guint session_unix_user; char *session_creation_time; } CkLogSeatSessionRemovedEvent; diff --git a/src/ck-manager.c b/src/ck-manager.c index bcb9350..7b85c90 100644 --- a/src/ck-manager.c +++ b/src/ck-manager.c @@ -64,6 +64,10 @@ #define CK_MANAGER_DBUS_PATH CK_DBUS_PATH "/Manager" #define CK_MANAGER_DBUS_NAME "org.freedesktop.ConsoleKit.Manager" +#define GDM_DBUS_NAME "org.gnome.DisplayManager" +#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH "/org/gnome/DisplayManager/LocalDisplayFactory" +#define GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE "org.gnome.DisplayManager.LocalDisplayFactory" + struct CkManagerPrivate { #ifdef HAVE_POLKIT @@ -522,6 +526,7 @@ log_seat_session_added_event (CkManager *manager, "display-device", &event.event.seat_session_added.session_display_device, "remote-host-name", &event.event.seat_session_added.session_remote_host_name, "is-local", &event.event.seat_session_added.session_is_local, + "is-dynamic", &event.event.seat_session_added.session_is_dynamic, "unix-user", &event.event.seat_session_added.session_unix_user, NULL); ck_session_get_creation_time (session, &event.event.seat_session_added.session_creation_time, NULL); @@ -577,6 +582,7 @@ log_seat_session_removed_event (CkManager *manager, "display-device", &event.event.seat_session_removed.session_display_device, "remote-host-name", &event.event.seat_session_removed.session_remote_host_name, "is-local", &event.event.seat_session_removed.session_is_local, + "is-dynamic", &event.event.seat_session_removed.session_is_dynamic, "unix-user", &event.event.seat_session_removed.session_unix_user, NULL); ck_session_get_creation_time (session, &event.event.seat_session_removed.session_creation_time, NULL); @@ -779,6 +785,7 @@ new_polkit_session_from_session (CkManager *manager, uid_t uid; gboolean is_active; gboolean is_local; + gboolean is_dynamic; char *sid; char *ssid; char *remote_host; @@ -792,6 +799,7 @@ new_polkit_session_from_session (CkManager *manager, g_object_get (ck_session, "active", &is_active, "is-local", &is_local, + "is-dynamic", &is_dynamic, "id", &ssid, "unix-user", &uid, "remote-host-name", &remote_host, @@ -2660,6 +2668,147 @@ ck_manager_get_sessions (CkManager *manager, return TRUE; } +/* + Example: + dbus-send --system --dest=org.freedesktop.ConsoleKit \ + --type=method_call --print-reply --reply-timeout=2000 \ + /org/freedesktop/ConsoleKit/Manager \ + org.freedesktop.ConsoleKit.Manager.CreateSession \ + int32:101 string:"/usr/X11/bin/Xvfb" +*/ +gboolean +ck_manager_create_session (CkManager *manager, + gint32 display_number, + char *xserver_command, + char **id, + DBusGMethodInvocation *context) +{ + DBusGProxy *proxy; + gboolean ret = TRUE; + GError *error = NULL; + + g_return_val_if_fail (CK_IS_MANAGER (manager), FALSE); + g_return_val_if_fail (xserver_command != NULL, FALSE); + + proxy = dbus_g_proxy_new_for_name (manager->priv->connection, + GDM_DBUS_NAME, + GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH, + GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE); + if (proxy == NULL) { + g_critical ("error getting %s proxy", + GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE); + return FALSE; + } + + error = NULL; + ret = dbus_g_proxy_call (proxy, + "CreateDynamicDisplay", + &error, + G_TYPE_INT, display_number, + G_TYPE_STRING, xserver_command, + G_TYPE_INVALID, + DBUS_TYPE_G_OBJECT_PATH, id, + G_TYPE_INVALID); + if (!ret) { + if (error != NULL) { + g_critical ("error creating dynamic display(%d=%s): %s", + display_number, + xserver_command, + error->message); + g_error_free (error); + } else { + g_critical ("error creating dynamic display(%d=%s)", + display_number, + xserver_command); + } + } + + g_object_unref (proxy); + + return ret; +} + +/* + Example: + dbus-send --system --dest=org.freedesktop.ConsoleKit \ + --type=method_call --print-reply --reply-timeout=2000 \ + /org/freedesktop/ConsoleKit/Manager \ + org.freedesktop.ConsoleKit.Manager.RemoveSession \ + int32:101 +*/ +gboolean +ck_manager_remove_session (CkManager *manager, + gint32 display_number, + DBusGMethodInvocation *context) +{ + DBusGProxy *proxy; + gboolean ret = TRUE; + + g_return_val_if_fail (CK_IS_MANAGER (manager), FALSE); + + proxy = dbus_g_proxy_new_for_name (manager->priv->connection, + GDM_DBUS_NAME, + GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH, + GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE); + if (proxy == NULL) { + g_critical ("error getting %s proxy", + GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE); + return FALSE; + } + + dbus_g_proxy_call_no_reply (proxy, + "RemoveDynamicDisplay", + G_TYPE_INT, display_number, + G_TYPE_INVALID, + G_TYPE_INVALID); + g_object_unref (proxy); + + return ret; +} + +static void +listify_created_session_displays (char *id, + CkSession *session, + char **session_list) +{ + gboolean is_dynamic; + char *display; + GError *error; + + ck_session_is_dynamic (session, &is_dynamic, NULL); + + if (!is_dynamic) + return; + + ck_session_get_x11_display (session, &display, NULL); + if (*session_list == NULL) { + *session_list = g_strdup (display); + } else { + *session_list = g_strdup_printf ("%s;%s", *session_list, display); + } +} + +/* + Example: + dbus-send --system --dest=org.freedesktop.ConsoleKit \ + --type=method_call --print-reply --reply-timeout=2000 \ + /org/freedesktop/ConsoleKit/Manager \ + org.freedesktop.ConsoleKit.Manager.ListCreatedSessions +*/ +gboolean +ck_manager_list_created_sessions (CkManager *manager, + char **session_list, + DBusGMethodInvocation *context) +{ + gboolean ret = TRUE; + + g_return_val_if_fail (CK_IS_MANAGER (manager), FALSE); + + g_hash_table_foreach (manager->priv->sessions, (GHFunc)listify_created_session_displays, session_list); + + return ret; +} + static void add_seat_for_file (CkManager *manager, const char *filename) diff --git a/src/ck-manager.h b/src/ck-manager.h index 45910b7..afcad15 100644 --- a/src/ck-manager.h +++ b/src/ck-manager.h @@ -122,6 +122,19 @@ gboolean ck_manager_get_system_idle_since_hint (CkManager gboolean ck_manager_open_session_with_parameters (CkManager *manager, const GPtrArray *parameters, DBusGMethodInvocation *context); +/* Dynamic related */ +gboolean ck_manager_create_session (CkManager *manager, + gint32 display_number, + char *xserver_command, + char **id, + DBusGMethodInvocation *context); +gboolean ck_manager_remove_session (CkManager *manager, + gint32 display_number, + DBusGMethodInvocation *context); +gboolean ck_manager_list_created_sessions (CkManager *manager, + char **session_list, + DBusGMethodInvocation *context); + G_END_DECLS diff --git a/src/ck-session.c b/src/ck-session.c index 8ba8791..865cc59 100644 --- a/src/ck-session.c +++ b/src/ck-session.c @@ -67,6 +67,7 @@ struct CkSessionPrivate gboolean active; gboolean is_local; + gboolean is_dynamic; GTimeVal creation_time; @@ -101,6 +102,7 @@ enum { PROP_REMOTE_HOST_NAME, PROP_LOGIN_SESSION_ID, PROP_IS_LOCAL, + PROP_IS_DYNAMIC, PROP_ACTIVE, PROP_IDLE_HINT, }; @@ -421,6 +423,20 @@ ck_session_set_is_local (CkSession *session, } gboolean +ck_session_set_is_dynamic (CkSession *session, + gboolean is_dynamic, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (session->priv->is_dynamic != is_dynamic) { + session->priv->is_dynamic = is_dynamic; + } + + return TRUE; +} + +gboolean ck_session_get_id (CkSession *session, char **id, GError **error) @@ -598,6 +614,20 @@ ck_session_is_local (CkSession *session, } gboolean +ck_session_is_dynamic (CkSession *session, + gboolean *dynamic, + GError **error) +{ + g_return_val_if_fail (CK_IS_SESSION (session), FALSE); + + if (dynamic != NULL) { + *dynamic = session->priv->is_dynamic; + } + + return TRUE; +} + +gboolean ck_session_set_id (CkSession *session, const char *id, GError **error) @@ -743,6 +773,9 @@ ck_session_set_property (GObject *object, case PROP_IS_LOCAL: ck_session_set_is_local (self, g_value_get_boolean (value), NULL); break; + case PROP_IS_DYNAMIC: + ck_session_set_is_dynamic (self, g_value_get_boolean (value), NULL); + break; case PROP_ID: ck_session_set_id (self, g_value_get_string (value), NULL); break; @@ -799,6 +832,9 @@ ck_session_get_property (GObject *object, case PROP_IS_LOCAL: g_value_set_boolean (value, self->priv->is_local); break; + case PROP_IS_DYNAMIC: + g_value_set_boolean (value, self->priv->is_dynamic); + break; case PROP_ID: g_value_set_string (value, self->priv->id); break; @@ -988,6 +1024,13 @@ ck_session_class_init (CkSessionClass *klass) TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (object_class, + PROP_IS_DYNAMIC, + g_param_spec_boolean ("is-dynamic", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, PROP_ID, g_param_spec_string ("id", "id", @@ -1281,6 +1324,7 @@ ck_session_run_programs (CkSession *session, } extra_env[n++] = g_strdup_printf ("CK_SESSION_IS_ACTIVE=%s", session->priv->active ? "true" : "false"); extra_env[n++] = g_strdup_printf ("CK_SESSION_IS_LOCAL=%s", session->priv->is_local ? "true" : "false"); + extra_env[n++] = g_strdup_printf ("CK_SESSION_IS_DYNAMIC=%s", session->priv->is_dynamic ? "true" : "false"); extra_env[n++] = NULL; ck_run_programs (SYSCONFDIR "/ConsoleKit/run-session.d", action, extra_env); @@ -1350,6 +1394,7 @@ ck_session_dump (CkSession *session, NONULL_STRING (session->priv->remote_host_name)); g_key_file_set_boolean (key_file, group_name, "is_active", session->priv->active); g_key_file_set_boolean (key_file, group_name, "is_local", session->priv->is_local); + g_key_file_set_boolean (key_file, group_name, "is_dynamic", session->priv->is_dynamic); s = g_time_val_to_iso8601 (&(session->priv->creation_time)); g_key_file_set_string (key_file, diff --git a/src/ck-session.h b/src/ck-session.h index c9ebd08..c288745 100644 --- a/src/ck-session.h +++ b/src/ck-session.h @@ -83,6 +83,9 @@ gboolean ck_session_set_active (CkSession *se gboolean ck_session_set_is_local (CkSession *session, gboolean is_local, GError **error); +gboolean ck_session_set_is_dynamic (CkSession *session, + gboolean is_dynamic, + GError **error); gboolean ck_session_set_id (CkSession *session, const char *ssid, GError **error); @@ -129,6 +132,9 @@ gboolean ck_session_is_active (CkSession *se gboolean ck_session_is_local (CkSession *session, gboolean *local, GError **error); +gboolean ck_session_is_dynamic (CkSession *session, + gboolean *dynamic, + GError **error); gboolean ck_session_get_unix_user (CkSession *session, guint *uid, GError **error); diff --git a/src/org.freedesktop.ConsoleKit.Manager.xml b/src/org.freedesktop.ConsoleKit.Manager.xml index f405c25..a661f28 100644 --- a/src/org.freedesktop.ConsoleKit.Manager.xml +++ b/src/org.freedesktop.ConsoleKit.Manager.xml @@ -300,6 +300,38 @@ + + + + The display number + + + + + The xserver command + + + + + The created display id + + + + + + + The display number + + + + + + + The created displays + + + + diff --git a/src/org.freedesktop.ConsoleKit.Session.xml b/src/org.freedesktop.ConsoleKit.Session.xml index b6e1cdb..8bbb06f 100644 --- a/src/org.freedesktop.ConsoleKit.Session.xml +++ b/src/org.freedesktop.ConsoleKit.Session.xml @@ -174,6 +174,18 @@ is-local + + + + TRUE if the session is dynamic, otherwise FALSE + + + + Returns whether the session is dynamic + + is-dynamic + + @@ -408,6 +420,14 @@ + + + + + Whether the session is dynamic + + + diff --git a/tools/Makefile.am b/tools/Makefile.am index 13c191f..6522e91 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -48,6 +48,7 @@ bin_PROGRAMS = \ ck-launch-session \ ck-list-sessions \ ck-history \ + ck-dynamic \ $(NULL) sbin_PROGRAMS = \ @@ -83,6 +84,14 @@ ck_history_LDADD = \ $(top_builddir)/src/libck-event-log.la \ $(NULL) +ck_dynamic_SOURCES = \ + ck-dynamic.c \ + $(NULL) + +ck_dynamic_LDADD = \ + $(CONSOLE_KIT_LIBS) \ + $(NULL) + ck_log_system_start_SOURCES = \ ck-log-system-start.c \ $(NULL) diff --git a/tools/ck-dynamic.c b/tools/ck-dynamic.c new file mode 100644 index 0000000..abcff72 --- /dev/null +++ b/tools/ck-dynamic.c @@ -0,0 +1,241 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Sun Microsystems, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Authors: Halton Huo + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CK_DBUS_NAME "org.freedesktop.ConsoleKit" +#define CK_MANAGER_DBUS_PATH "/org/freedesktop/ConsoleKit/Manager" +#define CK_MANAGER_DBUS_NAME "org.freedesktop.ConsoleKit.Manager" + +static gboolean +create_dynamic_session (DBusGConnection *connection, + DBusGProxy *proxy, + const char *key) +{ + gint disp_num; + char *p; + char *xcommand; + char *id = NULL; + GError *error = NULL; + gboolean ret = TRUE; + + if (! g_ascii_isdigit (*key)) { + g_warning ("Invalid display number!"); + return FALSE; + } + disp_num = atoi (key); + + p = strchr (key, '='); + if (p == NULL || *(p + 1) == 0) { + g_warning ("No server string\n"); + return FALSE; + } + xcommand = p + 1; + + ret = dbus_g_proxy_call (proxy, + "CreateSession", + &error, + G_TYPE_INT, disp_num, + G_TYPE_STRING, xcommand, + G_TYPE_INVALID, + G_TYPE_STRING, &id, + G_TYPE_INVALID); + if (!ret) { + if (error) { + g_warning ("Unable to add dynamic display (%d=%s): %s", + disp_num, + xcommand, + error->message); + g_error_free (error); + } else { + g_warning ("Unable to add dynamic display (%d=%s)", + disp_num, + xcommand); + } + } + + g_object_unref (proxy); + g_free (id); + + return ret; +} + +static gboolean +remove_dynamic_session (DBusGConnection *connection, + DBusGProxy *proxy, + const char *key) +{ + gint disp_num; + gboolean ret = TRUE; + + if (!g_ascii_isdigit (*key)) { + g_warning ("Invalid display number!"); + return FALSE; + } + disp_num = atoi (key); + + dbus_g_proxy_call_no_reply (proxy, + "RemoveSession", + G_TYPE_INT, disp_num, + G_TYPE_INVALID, + G_TYPE_INVALID); + g_object_unref (proxy); + + return ret; +} + +static gboolean +list_created_sessions (DBusGConnection *connection, + DBusGProxy *proxy) +{ + char *disp_list = NULL; + GError *error = NULL; + gboolean ret = TRUE; + + ret = dbus_g_proxy_call (proxy, + "ListCreatedSessions", + &error, + G_TYPE_INVALID, + G_TYPE_STRING, &disp_list, + G_TYPE_INVALID); + if (!ret) { + if (error) { + g_warning ("Unable to get dynamic displays: %s", error->message); + g_error_free (error); + } else { + g_warning ("Unable to get dynamic displays"); + } + } else { + if (disp_list && !g_str_equal (disp_list, "")) { + printf ("%s\n", disp_list); + } else { + printf ("No matching display!\n"); + } + } + + g_object_unref (proxy); + g_free (disp_list); + + return ret; +} + +static gboolean +release_all_waiting_sessions (DBusGConnection *connection, + DBusGProxy *proxy) +{ + gboolean ret = TRUE; + + return ret; +} + +int +main (int argc, char *argv[]) +{ + DBusGConnection *connection; + DBusGProxy *proxy; + GOptionContext *ctx; + GError *error = NULL; + char *add_params = NULL; + char *delete_params = NULL; + gboolean list_disps = FALSE; + gboolean release = FALSE; + gboolean verbose = FALSE; + gboolean show_version = FALSE; + gboolean res; + + GOptionEntry options [] = { + { "add", 'a', 0, G_OPTION_ARG_STRING, &add_params, N_("Add a new display"), N_("display") }, + { "delete", 'd', 0, G_OPTION_ARG_STRING, &delete_params, N_("Delete a display"), N_("display") }, + { "list", 'l', 0, G_OPTION_ARG_NONE, &list_disps, N_("List all attached displays"), NULL}, + { "release", 'r', 0, G_OPTION_ARG_NONE, &release, N_("Release (run) all displays waiting in the DISPLAY_CONFIG state"), NULL}, + { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, N_("Verbose mode"), NULL}, + { "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL }, + { NULL } + }; + + g_type_init (); + + /* Option parsing */ + ctx = g_option_context_new ("- Manage dynamic displays"); + g_option_context_add_main_entries (ctx, options, _("Main Options")); + res = g_option_context_parse (ctx, &argc, &argv, &error); + + if (!res) { + if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } + exit (1); + } + + g_option_context_free (ctx); + + if (show_version) { + g_print ("%s %s\n", argv[0], VERSION); + exit (1); + } + + error = NULL; + connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + g_message ("Failed to connect to the D-Bus daemon: %s", error->message); + g_error_free (error); + exit (1); + } + + proxy = dbus_g_proxy_new_for_name_owner (connection, + CK_DBUS_NAME, + CK_MANAGER_DBUS_PATH, + CK_MANAGER_DBUS_NAME, + &error); + if (proxy == NULL) { + g_warning ("Failed to create a new proxy, %s", error->message); + g_error_free (error); + return FALSE; + } + + + if (add_params) { + create_dynamic_session (connection, proxy, add_params); + } else if (delete_params) { + remove_dynamic_session (connection, proxy, delete_params); + } else if (list_disps) { + list_created_sessions (connection, proxy); + } else if (release) { + release_all_waiting_sessions (connection, proxy); + } else { + g_warning ("Invaild parameters!"); + exit (1); + } + + return 0; +} diff --git a/tools/list-sessions.c b/tools/list-sessions.c index 0a026c8..120f583 100644 --- a/tools/list-sessions.c +++ b/tools/list-sessions.c @@ -173,6 +173,7 @@ list_session (DBusGConnection *connection, char *idle_since_hint; gboolean is_active; gboolean is_local; + gboolean is_dynamic; char *short_sid; const char *short_ssid; @@ -204,6 +205,7 @@ list_session (DBusGConnection *connection, get_string (proxy, "GetRemoteHostName", &remote_host_name); get_boolean (proxy, "IsActive", &is_active); get_boolean (proxy, "IsLocal", &is_local); + get_boolean (proxy, "IsDynamic", &is_dynamic); get_string (proxy, "GetCreationTime", &creation_time); get_string (proxy, "GetIdleSinceHint", &idle_since_hint); @@ -219,7 +221,7 @@ list_session (DBusGConnection *connection, short_ssid = ssid + strlen (CK_PATH) + 1; } - 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'", + 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\tis-dynamic = %s\n\ton-since = '%s'\n\tlogin-session-id = '%s'", short_ssid, uid, realname, @@ -231,6 +233,7 @@ list_session (DBusGConnection *connection, display_device, remote_host_name, is_local ? "TRUE" : "FALSE", + is_dynamic ? "TRUE" : "FALSE", creation_time, lsid); if (idle_since_hint != NULL && idle_since_hint[0] != '\0') {