From 908cd0d95c6b49f922af9005787dcf1456e452bf Mon Sep 17 00:00:00 2001 From: Halton Huo Date: Sun, 10 May 2009 22:43:06 -0400 Subject: Second pass at display configuration See http://bugzilla.gnome.org/show_bug.cgi?id=536355 --- configure.ac | 2 +- daemon/gdm-display.c | 129 ---------- daemon/gdm-display.h | 9 - daemon/gdm-display.xml | 9 - daemon/gdm-local-display-factory.c | 473 ++++++++++++++++++++++++----------- daemon/gdm-local-display-factory.h | 17 -- daemon/gdm-local-display-factory.xml | 74 ------ daemon/gdm-server.c | 253 ++++++++++--------- 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 -#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, @@ -781,46 +764,6 @@ gdm_display_get_x11_command (GdmDisplay *display, return TRUE; } -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, @@ -893,35 +836,6 @@ _gdm_display_set_x11_command (GdmDisplay *display, display->priv->x11_command = g_strdup (x11_command); } -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; @@ -1234,29 +1130,6 @@ gdm_display_class_init (GdmDisplayClass *klass) "x11 command", 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", @@ -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 @@ - - - - - - - - - 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; @@ -247,130 +256,6 @@ gdm_local_display_lookup_by_number (GdmLocalDisplayFactory *factory, return display; } -/* - 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 \ @@ -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 @@ - - - - The seat id. Example: /org/freedesktop/ConsoleKit/Seat1 - - - - - The display number - - - - - The xserver command - - - - - The arguments of xserver command - - - - - If this value is TRUE, start a XDMCP chooser. If FALSE, start a greeter. - - - - - If this value is TRUE, add '-auth $auth_file' argument. The auth_file is generated by GDM before spawning the X server process. - - - - - 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. - - - - - Tty device used when create X server process. - - - - - Whether the session is dynamically created. Only turn this parameter to TRUE when created through ck-dynamic or gdmdynamic - - - - - The created display id - - - - - Create display with given parameters - - - - - - - - - The display number - - - - - Remove display with given display number - - - - - - 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 -#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", @@ -525,6 +544,30 @@ get_server_environment (GdmServer *server) return env; } +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, @@ -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; } @@ -694,6 +743,14 @@ _gdm_server_set_display_id (GdmServer *server, server->priv->display_id = g_strdup (id); } +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; @@ -837,6 +900,14 @@ gdm_server_class_init (GdmServerClass *klass) "Path to terminal display is running on", 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", @@ -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 @@ -983,72 +1060,6 @@ gdm_server_new (const char *display_id) server->priv->command = g_strdup (X_SERVER); } - 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", @@ -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; } -- cgit v1.2.1