summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHalton Huo <halton.huo@sun.com>2009-05-10 22:43:06 -0400
committerRay Strode <rstrode@redhat.com>2009-08-03 15:50:56 -0400
commit908cd0d95c6b49f922af9005787dcf1456e452bf (patch)
tree36a841302dcb6378f6e10e0a7192accd3e23fc3f
parent6ad44e30c0e64811b1a6deff4d2aaa0499ab8c78 (diff)
downloadgdm-908cd0d95c6b49f922af9005787dcf1456e452bf.tar.gz
Second pass at display configuration
See http://bugzilla.gnome.org/show_bug.cgi?id=536355
-rw-r--r--configure.ac2
-rw-r--r--daemon/gdm-display.c129
-rw-r--r--daemon/gdm-display.h9
-rw-r--r--daemon/gdm-display.xml9
-rw-r--r--daemon/gdm-local-display-factory.c473
-rw-r--r--daemon/gdm-local-display-factory.h17
-rw-r--r--daemon/gdm-local-display-factory.xml74
-rw-r--r--daemon/gdm-server.c253
8 files changed, 459 insertions, 507 deletions
diff --git a/configure.ac b/configure.ac
index 44705573..a3512e72 100644
--- a/configure.ac
+++ b/configure.ac
@@ -268,7 +268,7 @@ AC_CHECK_TYPE(socklen_t,,
#endif
)
AC_CHECK_HEADERS(sys/sockio.h)
-AC_CHECK_FUNCS([setresuid setenv unsetenv clearenv])
+AC_CHECK_FUNCS([setresuid setenv unsetenv clearenv strrep])
dnl checks needed for Darwin compatibility to linux **environ.
AC_CHECK_HEADERS(crt_externs.h)
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 43702615..45521ad5 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -48,17 +48,6 @@ static guint32 display_serial = 1;
#define DEFAULT_SLAVE_COMMAND LIBEXECDIR "/gdm-simple-slave"
-#if __sun
-#define GDM_PRIO_MIN 0
-#define GDM_PRIO_MAX (NZERO*2)-1
-#define GDM_PRIO_DEFAULT NZERO
-#else
-#include <sys/resource.h>
-#define GDM_PRIO_MIN PRIO_MIN
-#define GDM_PRIO_MAX PRIO_MAX
-#define GDM_PRIO_DEFAULT 0
-#endif
-
struct GdmDisplayPrivate
{
char *id;
@@ -66,9 +55,6 @@ struct GdmDisplayPrivate
char *remote_hostname;
char *x11_command;
- char *x11_arguments;
- char *tty_device;
- int priority;
int x11_display_number;
char *x11_display_name;
int status;
@@ -96,9 +82,6 @@ enum {
PROP_STATUS,
PROP_SEAT_ID,
PROP_X11_COMMAND,
- PROP_X11_ARGUMENTS,
- PROP_TTY_DEVICE,
- PROP_PRIORITY,
PROP_REMOTE_HOSTNAME,
PROP_X11_DISPLAY_NUMBER,
PROP_X11_DISPLAY_NAME,
@@ -782,46 +765,6 @@ gdm_display_get_x11_command (GdmDisplay *display,
}
gboolean
-gdm_display_get_x11_arguments (GdmDisplay *display,
- char **arguments,
- GError **error)
-{
- g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
-
- if (arguments != NULL) {
- *arguments = g_strdup (display->priv->x11_arguments);
- }
-
- return TRUE;
-}
-
-gboolean
-gdm_display_get_tty_device (GdmDisplay *display,
- char **tty_device,
- GError **error)
-{
- g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
-
- if (tty_device != NULL) {
- *tty_device = g_strdup (display->priv->tty_device);
- }
-
- return TRUE;
-}
-
-gboolean
-gdm_display_get_priority (GdmDisplay *display,
- int *priority,
- GError **error)
-{
- g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
-
- *priority = display->priv->priority;
-
- return TRUE;
-}
-
-gboolean
gdm_display_get_x11_display_name (GdmDisplay *display,
char **x11_display,
GError **error)
@@ -894,35 +837,6 @@ _gdm_display_set_x11_command (GdmDisplay *display,
}
static void
-_gdm_display_set_x11_arguments (GdmDisplay *display,
- const char *x11_arguments)
-{
- g_free (display->priv->x11_arguments);
- display->priv->x11_arguments = g_strdup (x11_arguments);
-}
-
-static void
-_gdm_display_set_tty_device (GdmDisplay *display,
- const char *tty_device)
-{
- g_free (display->priv->tty_device);
- display->priv->tty_device = g_strdup (tty_device);
-}
-
-static void
-_gdm_display_set_priority (GdmDisplay *display,
- int priority)
-{
- /* do some bounds checking */
- if (priority < GDM_PRIO_MIN)
- display->priv->priority = GDM_PRIO_MIN;
- else if (priority > GDM_PRIO_MAX)
- display->priv->priority = GDM_PRIO_MAX;
- else
- display->priv->priority = priority;
-}
-
-static void
_gdm_display_set_seat_id (GdmDisplay *display,
const char *seat_id)
{
@@ -1007,15 +921,6 @@ gdm_display_set_property (GObject *object,
case PROP_X11_COMMAND:
_gdm_display_set_x11_command (self, g_value_get_string (value));
break;
- case PROP_X11_ARGUMENTS:
- _gdm_display_set_x11_arguments (self, g_value_get_string (value));
- break;
- case PROP_TTY_DEVICE:
- _gdm_display_set_tty_device (self, g_value_get_string (value));
- break;
- case PROP_PRIORITY:
- _gdm_display_set_priority (self, g_value_get_int (value));
- break;
case PROP_STATUS:
_gdm_display_set_status (self, g_value_get_int (value));
break;
@@ -1069,15 +974,6 @@ gdm_display_get_property (GObject *object,
case PROP_X11_COMMAND:
g_value_set_string (value, self->priv->x11_command);
break;
- case PROP_X11_ARGUMENTS:
- g_value_set_string (value, self->priv->x11_arguments);
- break;
- case PROP_TTY_DEVICE:
- g_value_set_string (value, self->priv->tty_device);
- break;
- case PROP_PRIORITY:
- g_value_set_int (value, self->priv->priority);
- break;
case PROP_STATUS:
g_value_set_int (value, self->priv->status);
break;
@@ -1235,29 +1131,6 @@ gdm_display_class_init (GdmDisplayClass *klass)
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
- PROP_X11_ARGUMENTS,
- g_param_spec_string ("x11-arguments",
- "x11 arguments",
- "x11 arguments",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_TTY_DEVICE,
- g_param_spec_string ("tty-device",
- "tty device",
- "tty device",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
- PROP_PRIORITY,
- g_param_spec_int ("priority",
- "priority",
- "priority",
- GDM_PRIO_MIN,
- GDM_PRIO_MAX,
- GDM_PRIO_DEFAULT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
- g_object_class_install_property (object_class,
PROP_REMOTE_HOSTNAME,
g_param_spec_string ("remote-hostname",
"remote-hostname",
@@ -1369,8 +1242,6 @@ gdm_display_finalize (GObject *object)
g_debug ("GdmDisplay: Finalizing display: %s", display->priv->id);
g_free (display->priv->id);
g_free (display->priv->x11_command);
- g_free (display->priv->x11_arguments);
- g_free (display->priv->tty_device);
g_free (display->priv->seat_id);
g_free (display->priv->remote_hostname);
g_free (display->priv->x11_display_name);
diff --git a/daemon/gdm-display.h b/daemon/gdm-display.h
index 5df9c658..6f240bbb 100644
--- a/daemon/gdm-display.h
+++ b/daemon/gdm-display.h
@@ -105,15 +105,6 @@ gboolean gdm_display_get_id (GdmDisplay *disp
gboolean gdm_display_get_x11_command (GdmDisplay *display,
char **command,
GError **error);
-gboolean gdm_display_get_x11_arguments (GdmDisplay *display,
- char **arguments,
- GError **error);
-gboolean gdm_display_get_tty_device (GdmDisplay *display,
- char **tty_device,
- GError **error);
-gboolean gdm_display_get_priority (GdmDisplay *display,
- int *priority,
- GError **error);
gboolean gdm_display_get_remote_hostname (GdmDisplay *display,
char **hostname,
GError **error);
diff --git a/daemon/gdm-display.xml b/daemon/gdm-display.xml
index a7e1f5a0..894d5c01 100644
--- a/daemon/gdm-display.xml
+++ b/daemon/gdm-display.xml
@@ -7,15 +7,6 @@
<method name="GetX11Command">
<arg name="command" direction="out" type="s"/>
</method>
- <method name="GetX11Arguments">
- <arg name="arguments" direction="out" type="s"/>
- </method>
- <method name="GetTtyDevice">
- <arg name="tty_device" direction="out" type="s"/>
- </method>
- <method name="GetPriority">
- <arg name="priority" direction="out" type="i"/>
- </method>
<method name="GetX11DisplayName">
<arg name="name" direction="out" type="s"/>
</method>
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 53f18fb3..72d2816d 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -40,6 +40,13 @@
#define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate))
+#define CK_NAME "org.freedesktop.ConsoleKit"
+#define CK_PATH "/org/freedesktop/ConsoleKit"
+#define CK_INTERFACE "org.freedesktop.ConsoleKit"
+#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
+
#define CK_SEAT1_PATH "/org/freedesktop/ConsoleKit/Seat1"
#define GDM_DBUS_PATH "/org/gnome/DisplayManager"
@@ -59,8 +66,10 @@
struct GdmLocalDisplayFactoryPrivate
{
DBusGConnection *connection;
- DBusGProxy *proxy;
+ DBusGProxy *proxy_hal;
+ DBusGProxy *proxy_ck;
GHashTable *displays;
+ GSList *lst_proxy;
/* FIXME: this needs to be per seat? */
guint num_failures;
@@ -251,130 +260,6 @@ gdm_local_display_lookup_by_number (GdmLocalDisplayFactory *factory,
Example:
dbus-send --system --dest=org.gnome.DisplayManager \
--type=method_call --print-reply --reply-timeout=2000 \
- /org/gnome/DisplayManager/LocalDisplayFactory \
- org.gnome.DisplayManager.LocalDisplayFactory.CreateDisplay \
- string:"/org/freedesktop/ConsoleKit/Seat1" \
- int32:0 string:"/usr/X11/bin/Xorg" string:"-br -verbose -nolisten tcp" \
- boolean:true int32:0 boolean:true \
- string:"" boolean:false
-*/
-gboolean
-gdm_local_display_factory_create_display (GdmLocalDisplayFactory *factory,
- char *sid,
- gint32 display_number,
- char *xserver_command,
- char *arguments,
- gboolean is_chooser,
- gboolean use_auth,
- gint32 priority,
- char *tty_device,
- gboolean is_dynamic,
- char **id,
- GError **error)
-{
- GdmDisplay *display;
-
- g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
-
- if (display_number == -1)
- display_number = take_next_display_number (factory);
- else {
- /* Make sure number doesn't exist */
- }
-
- if (is_chooser) {
- /* TODO: Start a xdmcp chooser as request */
-
- /* display = gdm_xdmcp_chooser_display_new (display_number); */
- } else {
- if (is_dynamic)
- display = gdm_dynamic_display_new (display_number);
- else
- display = gdm_static_display_new (display_number);
- }
-
- if (display == NULL) {
- g_warning ("Unable to create display: %d", display_number);
- return FALSE;
- }
-
- if (IS_STR_SET (sid))
- g_object_set (display, "seat-id", sid, NULL);
- if (IS_STR_SET (xserver_command))
- g_object_set (display, "x11-command", xserver_command, NULL);
- if (IS_STR_SET (arguments))
- g_object_set (display, "x11-arguments", arguments, NULL);
- g_object_set (display, "use-auth", use_auth, NULL);
- g_object_set (display, "priority", priority, NULL);
- if (IS_STR_SET (tty_device))
- g_object_set (display, "tty-device", tty_device, NULL);
-
- store_display (factory, display_number, display);
-
- /* let store own the ref */
- g_object_unref (display);
-
- if (! gdm_display_manage (display)) {
- gdm_display_unmanage (display);
- return FALSE;
- }
-
- if (! gdm_display_get_id (display, id, NULL)) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- Example:
- dbus-send --system --dest=org.gnome.DisplayManager \
- --type=method_call --print-reply --reply-timeout=2000 \
- /org/gnome/DisplayManager/LocalDisplayFactory \
- org.gnome.DisplayManager.LocalDisplayFactory.RemoveDisplay \
- int32:101
-*/
-gboolean
-gdm_local_display_factory_remove_display (GdmLocalDisplayFactory *factory,
- gint32 display_number,
- GError **error)
-{
- gboolean ret;
- GdmDisplay *display;
-
- g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
-
- ret = FALSE;
-
- /* Make sure number already exist */
- if (! g_hash_table_lookup_extended (factory->priv->displays,
- GINT_TO_POINTER (display_number),
- NULL,
- NULL)) {
- g_debug ("GdmLocalDisplayFactory: display number doesn't exists");
- goto out;
- }
-
- g_debug ("GdmLocalDisplayFactory: Removing dynamic display %d", display_number);
-
- display = gdm_local_display_lookup_by_number (factory, display_number);
-
- if (! gdm_display_unmanage (display)) {
- display = NULL;
- goto out;
- }
-
- store_remove_display (factory, display_number, display);
-
- ret = TRUE;
- out:
- return ret;
-}
-
-/*
- Example:
- dbus-send --system --dest=org.gnome.DisplayManager \
- --type=method_call --print-reply --reply-timeout=2000 \
/org/gnome/DisplayManager/Manager \
org.gnome.DisplayManager.Manager.GetDisplays
*/
@@ -558,31 +443,287 @@ create_display (GdmLocalDisplayFactory *factory)
return display;
}
+#ifndef HAVE_STRREP
+static void
+strrep (char* in, char** out, char* old, char* new)
+{
+ char* temp;
+ char* orig = strdup(in);
+ char* found = strstr(orig, old);
+ if(!found) {
+ *out = malloc(strlen(orig) + 1);
+ strcpy(*out, orig);
+ return;
+ }
+
+ int idx = found - orig;
+
+ *out = realloc(*out, strlen(orig) - strlen(old) + strlen(new) + 1);
+ strncpy(*out, orig, idx);
+ strcpy(*out + idx, new);
+ strcpy(*out + idx + strlen(new), orig + idx + strlen(old));
+
+
+ temp = malloc(idx+strlen(new)+1);
+ strncpy(temp,*out,idx+strlen(new));
+ temp[idx + strlen(new)] = '\0';
+
+ strrep(found + strlen(old), out, old, new);
+ temp = realloc(temp, strlen(temp) + strlen(*out) + 1);
+ strcat(temp,*out);
+ free(*out);
+ *out = temp;
+}
+#endif
+
+static void
+seat_session_to_add (DBusGProxy *seat_proxy,
+ gboolean is_dynamic,
+ const char *xserver_command,
+ GdmLocalDisplayFactory *factory)
+{
+ GdmDisplay *display;
+ gint argc;
+ gchar **argv;
+ GError *error;
+ char *comm = NULL;
+ const char *sid = NULL;
+ gint32 display_number;
+ gboolean is_chooser;
+ gboolean use_auth;
+ int i;
+ gboolean res;
+
+ g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory));
+ g_return_if_fail (IS_STR_SET (xserver_command));
+
+ if (! g_shell_parse_argv (xserver_command, &argc, &argv, &error)) {
+ g_warning ("Could not parse command %s: %s", xserver_command, error->message);
+ g_error_free (error);
+ return;
+ }
+
+ comm = g_strdup (xserver_command);
+ for (i = 0; i < argc; i++) {
+ /* replase $display in case of not specified */
+ if (g_str_equal (argv[i], "$display")) {
+ display_number = take_next_display_number (factory);
+ strrep (comm, &comm, "$display", "");
+ break;
+ }
+
+ /* get display_number in case of specified */
+ if (g_str_has_prefix (argv[i], ":")) {
+ display_number = atoi (argv[i]+1);
+ strrep (comm, &comm, argv[i], "");
+ break;
+ }
+ }
+ g_strfreev (argv);
+
+ is_chooser = FALSE;
+ if (strstr (comm, "-indirect")) {
+ is_chooser = TRUE;
+ }
+
+ use_auth = FALSE;
+ if (strstr (comm, "-auth $auth")) {
+ use_auth = TRUE;
+ strrep (comm, &comm, "-auth $auth", "");
+ }
+
+ if (is_chooser) {
+ /* TODO: Start a xdmcp chooser as request */
+
+ /* display = gdm_xdmcp_chooser_display_new (display_number); */
+ } else {
+ if (is_dynamic)
+ display = gdm_dynamic_display_new (display_number);
+ else
+ display = gdm_static_display_new (display_number);
+ }
+
+ if (display == NULL) {
+ g_warning ("Unable to create display: %d", display_number);
+ g_free (comm);
+ return;
+ }
+
+ sid = dbus_g_proxy_get_path (seat_proxy);
+ if (IS_STR_SET (sid))
+ g_object_set (display, "seat-id", sid, NULL);
+ if (IS_STR_SET (comm))
+ g_object_set (display, "x11-command", comm, NULL);
+ g_free (comm);
+ g_object_set (display, "use-auth", use_auth, NULL);
+
+ store_display (factory, display_number, display);
+
+ g_object_unref (display);
+
+ if (! gdm_display_manage (display)) {
+ gdm_display_unmanage (display);
+ }
+}
+
+static void
+seat_session_to_remove (DBusGProxy *seat_proxy,
+ int display_number,
+ GdmLocalDisplayFactory *factory)
+{
+ GdmDisplay *display;
+
+ g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory));
+
+ /* Make sure number already exist */
+ if (! g_hash_table_lookup_extended (factory->priv->displays,
+ GINT_TO_POINTER (display_number),
+ NULL,
+ NULL)) {
+ g_debug ("GdmLocalDisplayFactory: display number doesn't exists");
+ return;
+ }
+
+ g_debug ("GdmLocalDisplayFactory: Removing dynamic display %d", display_number);
+
+ display = gdm_local_display_lookup_by_number (factory, display_number);
+
+ if (! gdm_display_unmanage (display)) {
+ display = NULL;
+ return;
+ }
+
+ store_remove_display (factory, display_number, display);
+}
+
+static void
+marshal_VOID__BOOLEAN_STRING (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__BOOLEAN_STRING) (gpointer data1,
+ guint arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_VOID__BOOLEAN_STRING callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__BOOLEAN_STRING) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_boolean (param_values + 1),
+ g_marshal_value_peek_string (param_values + 2),
+ data2);
+}
+
+static void
+manage_static_sessions_per_seat (GdmLocalDisplayFactory *factory,
+ const char *sid)
+{
+ DBusGProxy *proxy;
+
+ proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
+ CK_NAME,
+ sid,
+ CK_SEAT_INTERFACE);
+
+ if (proxy == NULL) {
+ g_warning ("Failed to connect to the ConsoleKit seat object");
+ return;
+ }
+
+ dbus_g_object_register_marshaller (marshal_VOID__BOOLEAN_STRING,
+ G_TYPE_NONE,
+ G_TYPE_BOOLEAN,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (proxy,
+ "SessionToAdd",
+ G_TYPE_BOOLEAN,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (proxy,
+ "SessionToRemove",
+ G_TYPE_INT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (proxy,
+ "SessionToAdd",
+ G_CALLBACK (seat_session_to_add),
+ factory,
+ NULL);
+ dbus_g_proxy_connect_signal (proxy,
+ "SessionToRemove",
+ G_CALLBACK (seat_session_to_remove),
+ factory,
+ NULL);
+
+ dbus_g_proxy_call_no_reply (proxy,
+ "ManageSeat",
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ factory->priv->lst_proxy = g_slist_append (factory->priv->lst_proxy, proxy);
+
+}
+
+static void
+seat_added (DBusGProxy *mgr_proxy,
+ const char *sid,
+ GdmLocalDisplayFactory *factory)
+{
+ manage_static_sessions_per_seat (factory, sid);
+}
static gboolean
create_static_displays (GdmLocalDisplayFactory *factory)
{
- DBusGProxy *proxy;
- GError *error = NULL;
+ GError *error;
+ gboolean res;
+ GPtrArray *seats;
+ int i;
- proxy = dbus_g_proxy_new_for_name_owner (factory->priv->connection,
- "org.freedesktop.ConsoleKit",
- "/org/freedesktop/ConsoleKit/Manager",
- "org.freedesktop.ConsoleKit.Manager",
- &error);
+ seats = NULL;
- if (proxy == NULL) {
- g_warning ("Failed to create a new proxy, %s", error->message);
+ error = NULL;
+ res = dbus_g_proxy_call (factory->priv->proxy_ck,
+ "GetUnmanagedSeats",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
+ &seats,
+ G_TYPE_INVALID);
+ if (! res) {
+ g_warning ("Failed to get list of unmanaged seats: %s", error->message);
g_error_free (error);
return FALSE;
}
- dbus_g_proxy_call_no_reply (proxy,
- "CreateStaticSessions",
- G_TYPE_INVALID,
- G_TYPE_INVALID);
+ for (i = 0; i < seats->len; i++) {
+ char *sid;
+
+ sid = g_ptr_array_index (seats, i);
+
+ manage_static_sessions_per_seat (factory, sid);
+
+ g_free (sid);
+ }
- g_object_unref (proxy);
return TRUE;
}
@@ -743,11 +884,11 @@ register_factory (GdmLocalDisplayFactory *factory)
static gboolean
connect_to_hal (GdmLocalDisplayFactory *factory)
{
- factory->priv->proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
- HAL_DBUS_NAME,
- HAL_DBUS_MANAGER_PATH,
- HAL_DBUS_MANAGER_INTERFACE);
- if (factory->priv->proxy == NULL) {
+ factory->priv->proxy_hal = dbus_g_proxy_new_for_name (factory->priv->connection,
+ HAL_DBUS_NAME,
+ HAL_DBUS_MANAGER_PATH,
+ HAL_DBUS_MANAGER_INTERFACE);
+ if (factory->priv->proxy_hal == NULL) {
g_warning ("Couldn't create proxy for HAL Manager");
return FALSE;
}
@@ -758,8 +899,44 @@ connect_to_hal (GdmLocalDisplayFactory *factory)
static void
disconnect_from_hal (GdmLocalDisplayFactory *factory)
{
- if (factory->priv->proxy == NULL) {
- g_object_unref (factory->priv->proxy);
+ if (factory->priv->proxy_hal == NULL) {
+ g_object_unref (factory->priv->proxy_hal);
+ }
+}
+
+static gboolean
+connect_to_ck (GdmLocalDisplayFactory *factory)
+{
+ GdmLocalDisplayFactoryPrivate *priv;
+
+ priv = factory->priv;
+
+ priv->proxy_ck = dbus_g_proxy_new_for_name (priv->connection,
+ CK_NAME,
+ CK_MANAGER_PATH,
+ CK_MANAGER_INTERFACE);
+
+ if (priv->proxy_ck == NULL) {
+ g_warning ("Couldn't create proxy for ConsoleKit Manager");
+ return FALSE;
+ }
+
+ dbus_g_proxy_add_signal (priv->proxy_ck,
+ "SeatAdded",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy_ck,
+ "SeatAdded",
+ G_CALLBACK (seat_added),
+ factory,
+ NULL);
+}
+
+static void
+disconnect_from_ck (GdmLocalDisplayFactory *factory)
+{
+ if (factory->priv->proxy_hal == NULL) {
+ g_object_unref (factory->priv->proxy_hal);
}
}
@@ -781,6 +958,7 @@ gdm_local_display_factory_constructor (GType type,
}
connect_to_hal (factory);
+ connect_to_ck (factory);
return G_OBJECT (factory);
}
@@ -826,7 +1004,10 @@ gdm_local_display_factory_finalize (GObject *object)
g_hash_table_destroy (factory->priv->displays);
+ g_slist_foreach (factory->priv->lst_proxy, g_object_unref, NULL);
+
disconnect_from_hal (factory);
+ disconnect_from_ck (factory);
G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object);
}
diff --git a/daemon/gdm-local-display-factory.h b/daemon/gdm-local-display-factory.h
index 8c43b35d..2abb0530 100644
--- a/daemon/gdm-local-display-factory.h
+++ b/daemon/gdm-local-display-factory.h
@@ -71,23 +71,6 @@ gboolean gdm_local_display_factory_create_product_display (G
char **id,
GError **error);
-gboolean gdm_local_display_factory_create_display (GdmLocalDisplayFactory *factory,
- char *sid,
- gint32 display_number,
- char *xserver_command,
- char *arguments,
- gboolean is_chooser,
- gboolean use_auth,
- gint32 priority,
- char *tty_device,
- gboolean is_dynamic,
- char **id,
- GError **error);
-
-gboolean gdm_local_display_factory_remove_display (GdmLocalDisplayFactory *factory,
- gint32 display_number,
- GError **error);
-
G_END_DECLS
#endif /* __GDM_LOCAL_DISPLAY_FACTORY_H */
diff --git a/daemon/gdm-local-display-factory.xml b/daemon/gdm-local-display-factory.xml
index 0920b856..51f5153b 100644
--- a/daemon/gdm-local-display-factory.xml
+++ b/daemon/gdm-local-display-factory.xml
@@ -1,85 +1,11 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/org/gnome/DisplayManager/LocalDisplayFactory">
<interface name="org.gnome.DisplayManager.LocalDisplayFactory">
- <method name="CreateDisplay">
- <arg name="sid" direction="in" type="s">
- <doc:doc>
- <doc:summary>The seat id. Example: /org/freedesktop/ConsoleKit/Seat1</doc:summary>
- </doc:doc>
- </arg>
- <arg name="display_number" direction="in" type="i">
- <doc:doc>
- <doc:summary>The display number</doc:summary>
- </doc:doc>
- </arg>
- <arg name="xserver_command" direction="in" type="s">
- <doc:doc>
- <doc:summary>The xserver command</doc:summary>
- </doc:doc>
- </arg>
- <arg name="arguments" direction="in" type="s">
- <doc:doc>
- <doc:summary>The arguments of xserver command</doc:summary>
- </doc:doc>
- </arg>
- <arg name="is_chooser" direction="in" type="b">
- <doc:doc>
- <doc:summary>If this value is TRUE, start a XDMCP chooser. If FALSE, start a greeter.</doc:summary>
- </doc:doc>
- </arg>
- <arg name="use_auth" direction="in" type="b">
- <doc:doc>
- <doc:summary>If this value is TRUE, add '-auth $auth_file' argument. The auth_file is generated by GDM before spawning the X server process.</doc:summary>
- </doc:doc>
- </arg>
- <arg name="priority" direction="in" type="i">
- <doc:doc>
- <doc:summary>X server process priority. If value is 0, not change. Values can be any integer value accepted by the setpriority C library function (normally between -20 and 20) with 0 being the default.</doc:summary>
- </doc:doc>
- </arg>
- <arg name="tty_device" direction="in" type="s">
- <doc:doc>
- <doc:summary>Tty device used when create X server process.</doc:summary>
- </doc:doc>
- </arg>
- <arg name="is_dynamic" direction="in" type="b">
- <doc:doc>
- <doc:summary>Whether the session is dynamically created. Only turn this parameter to TRUE when created through ck-dynamic or gdmdynamic</doc:summary>
- </doc:doc>
- </arg>
- <arg name="id" direction="out" type="o">
- <doc:doc>
- <doc:summary>The created display id</doc:summary>
- </doc:doc>
- </arg>
- <doc:doc>
- <doc:description>
- <doc:para>Create display with given parameters
- </doc:para>
- </doc:description>
- </doc:doc>
- </method>
-
- <method name="RemoveDisplay">
- <arg name="display_number" direction="in" type="i">
- <doc:doc>
- <doc:summary>The display number</doc:summary>
- </doc:doc>
- </arg>
- <doc:doc>
- <doc:description>
- <doc:para>Remove display with given display number
- </doc:para>
- </doc:description>
- </doc:doc>
- </method>
-
<method name="CreateProductDisplay">
<arg name="parent_display_id" direction="in" type="o"/>
<arg name="relay_address" direction="in" type="s"/>
<arg name="id" direction="out" type="o"/>
</method>
-
<method name="CreateTransientDisplay">
<arg name="id" direction="out" type="o"/>
</method>
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
index bedf038d..8289a8e7 100644
--- a/daemon/gdm-server.c
+++ b/daemon/gdm-server.c
@@ -67,37 +67,44 @@ extern char **environ;
struct GdmServerPrivate
{
+ char *command;
GPid pid;
- char *user_name;
- char *log_dir;
gboolean disable_tcp;
+ int priority;
+ char *user_name;
+ char *session_args;
- /* cached display values */
+ char *log_dir;
char *display_id;
- char *command;
- char *session_args;
- char *tty_device;
char *display_name;
- char *auth_file;
- int priority;
-
char *display_device;
+ char *auth_file;
gboolean is_parented;
char *parent_display_name;
char *parent_auth_file;
+ char *chosen_hostname;
guint child_watch_id;
};
enum {
PROP_0,
+ PROP_DISPLAY_NAME,
+ PROP_DISPLAY_DEVICE,
+ PROP_AUTH_FILE,
+ PROP_IS_PARENTED,
+ PROP_PARENT_DISPLAY_NAME,
+ PROP_PARENT_AUTH_FILE,
+ PROP_CHOSEN_HOSTNAME,
+ PROP_COMMAND,
+ PROP_PRIORITY,
PROP_USER_NAME,
+ PROP_SESSION_ARGS,
PROP_LOG_DIR,
PROP_DISABLE_TCP,
PROP_DISPLAY_ID,
- PROP_DISPLAY_DEVICE,
};
enum {
@@ -252,48 +259,67 @@ connect_to_parent (GdmServer *server)
static gboolean
gdm_server_resolve_command_line (GdmServer *server,
+ const char *vtarg,
int *argcp,
char ***argvp)
{
- gboolean ret;
- char *command = NULL;
- char *tmp = NULL;
-
- if (server->priv->session_args != NULL) {
- command = g_strdup_printf ("%s %s %s",
- server->priv->command,
- server->priv->display_name,
- server->priv->session_args);
- } else {
- command = g_strdup_printf ("%s %s",
- server->priv->command,
- server->priv->display_name);
+ int argc;
+ char **argv;
+ int len;
+ int i;
+ gboolean gotvtarg = FALSE;
+ gboolean query_in_arglist = FALSE;
+
+ g_shell_parse_argv (server->priv->command, &argc, &argv, NULL);
+
+ for (len = 0; argv != NULL && argv[len] != NULL; len++) {
+ char *arg = argv[len];
+
+ /* HACK! Not to add vt argument to servers that already force
+ * allocation. Mostly for backwards compat only */
+ if (strncmp (arg, "vt", 2) == 0 &&
+ isdigit (arg[2]) &&
+ (arg[3] == '\0' ||
+ (isdigit (arg[3]) && arg[4] == '\0')))
+ gotvtarg = TRUE;
+ if (strcmp (arg, "-query") == 0 ||
+ strcmp (arg, "-indirect") == 0)
+ query_in_arglist = TRUE;
+ }
+
+ argv = g_renew (char *, argv, len + 10);
+ /* shift args down one */
+ for (i = len - 1; i >= 1; i--) {
+ argv[i+1] = argv[i];
}
+ /* server number is the FIRST argument, before any others */
+ argv[1] = g_strdup (server->priv->display_name);
+ len++;
+
if (server->priv->auth_file != NULL) {
- tmp = g_strdup (command);
- g_free (command);
- command = g_strdup_printf ("%s -auth %s ",
- tmp, server->priv->auth_file);
- g_free (tmp);
+ argv[len++] = g_strdup ("-auth");
+ argv[len++] = g_strdup (server->priv->auth_file);
}
-#ifndef __sun
- /* TODO:
- Solaris Xorg does not accept vt argument, remove #ifndef
- when VT part for Xorg goes into Solaris.
- */
- if (server->priv->tty_device != NULL) {
- tmp = g_strdup (command);
- g_free (command);
- command = g_strdup_printf ("%s %s", tmp, server->priv->tty_device);
- g_free (tmp);
+
+ if (server->priv->chosen_hostname) {
+ /* run just one session */
+ argv[len++] = g_strdup ("-terminate");
+ argv[len++] = g_strdup ("-query");
+ argv[len++] = g_strdup (server->priv->chosen_hostname);
+ query_in_arglist = TRUE;
}
-#endif
- ret = g_shell_parse_argv (command, argcp, argvp, NULL);
- g_free (command);
+ if (vtarg != NULL && ! gotvtarg) {
+ argv[len++] = g_strdup (vtarg);
+ }
- return ret;
+ argv[len++] = NULL;
+
+ *argvp = argv;
+ *argcp = len;
+
+ return TRUE;
}
static void
@@ -440,14 +466,7 @@ server_child_setup (GdmServer *server)
sigemptyset (&mask);
sigprocmask (SIG_SETMASK, &mask, NULL);
-#if __sun
-#define GDM_PRIO_DEFAULT NZERO
-#else
-#include <sys/resource.h>
-#define GDM_PRIO_DEFAULT 0
-#endif
-
- if (server->priv->priority != GDM_PRIO_DEFAULT) {
+ if (server->priv->priority != 0) {
if (setpriority (PRIO_PROCESS, 0, server->priv->priority)) {
g_warning (_("%s: Server priority couldn't be set to %d: %s"),
"gdm_server_spawn",
@@ -526,6 +545,30 @@ get_server_environment (GdmServer *server)
}
static void
+server_add_xserver_args (GdmServer *server,
+ int *argc,
+ char ***argv)
+{
+ int count;
+ char **args;
+ int len;
+ int i;
+
+ len = *argc;
+ g_shell_parse_argv (server->priv->session_args, &count, &args, NULL);
+ *argv = g_renew (char *, *argv, len + count + 1);
+
+ for (i=0; i < count;i++) {
+ *argv[len++] = g_strdup (args[i]);
+ }
+
+ *argc += count;
+
+ argv[len] = NULL;
+ g_strfreev (args);
+}
+
+static void
server_child_watch (GPid pid,
int status,
GdmServer *server)
@@ -552,7 +595,8 @@ server_child_watch (GPid pid,
}
static gboolean
-gdm_server_spawn (GdmServer *server)
+gdm_server_spawn (GdmServer *server,
+ const char *vtarg)
{
int argc;
gchar **argv = NULL;
@@ -567,9 +611,14 @@ gdm_server_spawn (GdmServer *server)
argv = NULL;
argc = 0;
gdm_server_resolve_command_line (server,
+ vtarg,
&argc,
&argv);
+ if (server->priv->session_args) {
+ server_add_xserver_args (server, &argc, &argv);
+ }
+
if (argv[0] == NULL) {
g_warning (_("%s: Empty server command for display %s"),
"gdm_server_spawn",
@@ -629,7 +678,7 @@ gdm_server_start (GdmServer *server)
gboolean res;
/* fork X server process */
- res = gdm_server_spawn (server);
+ res = gdm_server_spawn (server, NULL);
return res;
}
@@ -695,6 +744,14 @@ _gdm_server_set_display_id (GdmServer *server,
}
static void
+_gdm_server_set_auth_file (GdmServer *server,
+ const char *auth_file)
+{
+ g_free (server->priv->auth_file);
+ server->priv->auth_file = g_strdup (auth_file);
+}
+
+static void
_gdm_server_set_user_name (GdmServer *server,
const char *name)
{
@@ -723,6 +780,9 @@ gdm_server_set_property (GObject *object,
case PROP_DISPLAY_ID:
_gdm_server_set_display_id (self, g_value_get_string (value));
break;
+ case PROP_AUTH_FILE:
+ _gdm_server_set_auth_file (self, g_value_get_string (value));
+ break;
case PROP_USER_NAME:
_gdm_server_set_user_name (self, g_value_get_string (value));
break;
@@ -753,6 +813,9 @@ gdm_server_get_property (GObject *object,
g_value_take_string (value,
gdm_server_get_display_device (self));
break;
+ case PROP_AUTH_FILE:
+ g_value_set_string (value, self->priv->auth_file);
+ break;
case PROP_USER_NAME:
g_value_set_string (value, self->priv->user_name);
break;
@@ -838,6 +901,14 @@ gdm_server_class_init (GdmServerClass *klass)
NULL,
G_PARAM_READABLE));
g_object_class_install_property (object_class,
+ PROP_AUTH_FILE,
+ g_param_spec_string ("auth-file",
+ "Authorization File",
+ "Path to X authorization file",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
PROP_USER_NAME,
g_param_spec_string ("user-name",
"user name",
@@ -852,13 +923,19 @@ gdm_server_class_init (GdmServerClass *klass)
TRUE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
}
static void
gdm_server_init (GdmServer *server)
{
+
server->priv = GDM_SERVER_GET_PRIVATE (server);
+
+ server->priv->pid = -1;
+ server->priv->command = g_strdup (X_SERVER " -br -verbose");
+ server->priv->log_dir = g_strdup (LOGDIR);
+
+ add_ready_handler (server);
}
static void
@@ -985,72 +1062,6 @@ gdm_server_new (const char *display_id)
error = NULL;
res = dbus_g_proxy_call (proxy,
- "GetX11Arguments",
- &error,
- G_TYPE_INVALID,
- G_TYPE_STRING, &server->priv->session_args,
- G_TYPE_INVALID);
- if (! res) {
- if (error != NULL) {
- g_warning ("Failed to get value: %s", error->message);
- g_error_free (error);
- } else {
- g_warning ("Failed to get value");
- }
-
- exit (1);
- }
-
- /* If session_args is not set, set it NULL */
- if (server->priv->session_args && (strlen (server->priv->session_args ) == 0)) {
- g_free (server->priv->session_args);
- server->priv->session_args = NULL;
- }
-
- error = NULL;
- res = dbus_g_proxy_call (proxy,
- "GetTtyDevice",
- &error,
- G_TYPE_INVALID,
- G_TYPE_STRING, &server->priv->tty_device,
- G_TYPE_INVALID);
- if (! res) {
- if (error != NULL) {
- g_warning ("Failed to get value: %s", error->message);
- g_error_free (error);
- } else {
- g_warning ("Failed to get value");
- }
-
- exit (1);
- }
-
- /* If tty_device is not set, set it NULL */
- if (server->priv->tty_device && (strlen (server->priv->tty_device) == 0)) {
- g_free (server->priv->tty_device);
- server->priv->tty_device = NULL;
- }
-
- error = NULL;
- res = dbus_g_proxy_call (proxy,
- "GetPriority",
- &error,
- G_TYPE_INVALID,
- G_TYPE_INT, &server->priv->priority,
- G_TYPE_INVALID);
- if (! res) {
- if (error != NULL) {
- g_warning ("Failed to get value: %s", error->message);
- g_error_free (error);
- } else {
- g_warning ("Failed to get value");
- }
-
- exit (1);
- }
-
- error = NULL;
- res = dbus_g_proxy_call (proxy,
"GetX11AuthorityFile",
&error,
G_TYPE_INVALID,
@@ -1067,13 +1078,11 @@ gdm_server_new (const char *display_id)
exit (1);
}
- /* If tty_device is not set, set it NULL */
+ /* If auth_file is not set, set it NULL */
if (server->priv->auth_file && (strlen (server->priv->auth_file) == 0)) {
g_free (server->priv->auth_file);
server->priv->auth_file = NULL;
}
- add_ready_handler (server);
-
return server;
}