571 lines
21 KiB
Diff
571 lines
21 KiB
Diff
|
From fbdb5fdfc5f4c5569643239cae1d6fe5fac13717 Mon Sep 17 00:00:00 2001
|
||
|
From: Ray Strode <rstrode@redhat.com>
|
||
|
Date: Mon, 12 Dec 2022 10:52:58 -0500
|
||
|
Subject: [PATCH] daemon: Don't error on shutdown
|
||
|
|
||
|
Right now we complain if shutdown happens while the display is
|
||
|
comming up.
|
||
|
|
||
|
This commit detects that case and avoids the error in that case.
|
||
|
---
|
||
|
daemon/gdm-display.c | 28 +++++++++++++++++++++++++++-
|
||
|
daemon/gdm-manager.c | 11 +++++++----
|
||
|
2 files changed, 34 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
|
||
|
index 9438fe72..a93857e9 100644
|
||
|
--- a/daemon/gdm-display.c
|
||
|
+++ b/daemon/gdm-display.c
|
||
|
@@ -66,86 +66,88 @@ typedef struct _GdmDisplayPrivate
|
||
|
char *x11_display_name;
|
||
|
int status;
|
||
|
time_t creation_time;
|
||
|
|
||
|
char *x11_cookie;
|
||
|
gsize x11_cookie_size;
|
||
|
GdmDisplayAccessFile *access_file;
|
||
|
|
||
|
guint finish_idle_id;
|
||
|
|
||
|
xcb_connection_t *xcb_connection;
|
||
|
int xcb_screen_number;
|
||
|
|
||
|
GDBusConnection *connection;
|
||
|
GdmDisplayAccessFile *user_access_file;
|
||
|
|
||
|
GdmDBusDisplay *display_skeleton;
|
||
|
GDBusObjectSkeleton *object_skeleton;
|
||
|
|
||
|
GDBusProxy *accountsservice_proxy;
|
||
|
|
||
|
/* this spawns and controls the greeter session */
|
||
|
GdmLaunchEnvironment *launch_environment;
|
||
|
|
||
|
guint is_local : 1;
|
||
|
guint is_initial : 1;
|
||
|
guint allow_timed_login : 1;
|
||
|
guint have_existing_user_accounts : 1;
|
||
|
guint doing_initial_setup : 1;
|
||
|
guint session_registered : 1;
|
||
|
+ guint shutting_down : 1;
|
||
|
|
||
|
GStrv supported_session_types;
|
||
|
} GdmDisplayPrivate;
|
||
|
|
||
|
enum {
|
||
|
PROP_0,
|
||
|
PROP_ID,
|
||
|
PROP_STATUS,
|
||
|
PROP_SEAT_ID,
|
||
|
PROP_SESSION_ID,
|
||
|
PROP_SESSION_CLASS,
|
||
|
PROP_SESSION_TYPE,
|
||
|
PROP_REMOTE_HOSTNAME,
|
||
|
PROP_X11_DISPLAY_NUMBER,
|
||
|
PROP_X11_DISPLAY_NAME,
|
||
|
PROP_X11_COOKIE,
|
||
|
PROP_X11_AUTHORITY_FILE,
|
||
|
PROP_IS_CONNECTED,
|
||
|
PROP_IS_LOCAL,
|
||
|
PROP_LAUNCH_ENVIRONMENT,
|
||
|
PROP_IS_INITIAL,
|
||
|
PROP_ALLOW_TIMED_LOGIN,
|
||
|
PROP_HAVE_EXISTING_USER_ACCOUNTS,
|
||
|
PROP_DOING_INITIAL_SETUP,
|
||
|
PROP_SESSION_REGISTERED,
|
||
|
PROP_SUPPORTED_SESSION_TYPES,
|
||
|
+ PROP_SHUTTING_DOWN,
|
||
|
};
|
||
|
|
||
|
static void gdm_display_class_init (GdmDisplayClass *klass);
|
||
|
static void gdm_display_init (GdmDisplay *self);
|
||
|
static void gdm_display_finalize (GObject *object);
|
||
|
static void queue_finish (GdmDisplay *self);
|
||
|
static void _gdm_display_set_status (GdmDisplay *self,
|
||
|
int status);
|
||
|
static gboolean wants_initial_setup (GdmDisplay *self);
|
||
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdmDisplay, gdm_display, G_TYPE_OBJECT)
|
||
|
|
||
|
GQuark
|
||
|
gdm_display_error_quark (void)
|
||
|
{
|
||
|
static GQuark ret = 0;
|
||
|
if (ret == 0) {
|
||
|
ret = g_quark_from_static_string ("gdm_display_error");
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
time_t
|
||
|
gdm_display_get_creation_time (GdmDisplay *self)
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
g_return_val_if_fail (GDM_IS_DISPLAY (self), 0);
|
||
|
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
@@ -665,61 +667,61 @@ gdm_display_disconnect (GdmDisplay *self)
|
||
|
}
|
||
|
|
||
|
xcb_flush (priv->xcb_connection);
|
||
|
|
||
|
g_clear_pointer (&priv->xcb_connection, xcb_disconnect);
|
||
|
}
|
||
|
|
||
|
gboolean
|
||
|
gdm_display_unmanage (GdmDisplay *self)
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
|
||
|
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
|
||
|
gdm_display_disconnect (self);
|
||
|
|
||
|
if (priv->user_access_file != NULL) {
|
||
|
gdm_display_access_file_close (priv->user_access_file);
|
||
|
g_object_unref (priv->user_access_file);
|
||
|
priv->user_access_file = NULL;
|
||
|
}
|
||
|
|
||
|
if (priv->access_file != NULL) {
|
||
|
gdm_display_access_file_close (priv->access_file);
|
||
|
g_object_unref (priv->access_file);
|
||
|
priv->access_file = NULL;
|
||
|
}
|
||
|
|
||
|
- if (!priv->session_registered) {
|
||
|
+ if (!priv->session_registered && !priv->shutting_down) {
|
||
|
g_warning ("GdmDisplay: Session never registered, failing");
|
||
|
_gdm_display_set_status (self, GDM_DISPLAY_FAILED);
|
||
|
} else {
|
||
|
_gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
gboolean
|
||
|
gdm_display_get_id (GdmDisplay *self,
|
||
|
char **id,
|
||
|
GError **error)
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
|
||
|
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
if (id != NULL) {
|
||
|
*id = g_strdup (priv->id);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
gboolean
|
||
|
gdm_display_get_x11_display_name (GdmDisplay *self,
|
||
|
char **x11_display,
|
||
|
GError **error)
|
||
|
@@ -851,60 +853,70 @@ _gdm_display_set_x11_cookie (GdmDisplay *self,
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
g_free (priv->x11_cookie);
|
||
|
priv->x11_cookie = g_strdup (x11_cookie);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_gdm_display_set_is_local (GdmDisplay *self,
|
||
|
gboolean is_local)
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
g_debug ("GdmDisplay: local: %s", is_local? "yes" : "no");
|
||
|
priv->is_local = is_local;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_gdm_display_set_session_registered (GdmDisplay *self,
|
||
|
gboolean registered)
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
g_debug ("GdmDisplay: session registered: %s", registered? "yes" : "no");
|
||
|
priv->session_registered = registered;
|
||
|
}
|
||
|
|
||
|
+static void
|
||
|
+_gdm_display_set_shutting_down (GdmDisplay *self,
|
||
|
+ gboolean shutting_down)
|
||
|
+{
|
||
|
+ GdmDisplayPrivate *priv;
|
||
|
+
|
||
|
+ priv = gdm_display_get_instance_private (self);
|
||
|
+ priv->shutting_down = shutting_down;
|
||
|
+}
|
||
|
+
|
||
|
static void
|
||
|
_gdm_display_set_launch_environment (GdmDisplay *self,
|
||
|
GdmLaunchEnvironment *launch_environment)
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
|
||
|
g_clear_object (&priv->launch_environment);
|
||
|
|
||
|
priv->launch_environment = g_object_ref (launch_environment);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_gdm_display_set_is_initial (GdmDisplay *self,
|
||
|
gboolean initial)
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
g_debug ("GdmDisplay: initial: %s", initial? "yes" : "no");
|
||
|
priv->is_initial = initial;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
_gdm_display_set_allow_timed_login (GdmDisplay *self,
|
||
|
gboolean allow_timed_login)
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
@@ -962,60 +974,63 @@ gdm_display_set_property (GObject *object,
|
||
|
case PROP_REMOTE_HOSTNAME:
|
||
|
_gdm_display_set_remote_hostname (self, g_value_get_string (value));
|
||
|
break;
|
||
|
case PROP_X11_DISPLAY_NUMBER:
|
||
|
_gdm_display_set_x11_display_number (self, g_value_get_int (value));
|
||
|
break;
|
||
|
case PROP_X11_DISPLAY_NAME:
|
||
|
_gdm_display_set_x11_display_name (self, g_value_get_string (value));
|
||
|
break;
|
||
|
case PROP_X11_COOKIE:
|
||
|
_gdm_display_set_x11_cookie (self, g_value_get_string (value));
|
||
|
break;
|
||
|
case PROP_IS_LOCAL:
|
||
|
_gdm_display_set_is_local (self, g_value_get_boolean (value));
|
||
|
break;
|
||
|
case PROP_ALLOW_TIMED_LOGIN:
|
||
|
_gdm_display_set_allow_timed_login (self, g_value_get_boolean (value));
|
||
|
break;
|
||
|
case PROP_LAUNCH_ENVIRONMENT:
|
||
|
_gdm_display_set_launch_environment (self, g_value_get_object (value));
|
||
|
break;
|
||
|
case PROP_IS_INITIAL:
|
||
|
_gdm_display_set_is_initial (self, g_value_get_boolean (value));
|
||
|
break;
|
||
|
case PROP_SESSION_REGISTERED:
|
||
|
_gdm_display_set_session_registered (self, g_value_get_boolean (value));
|
||
|
break;
|
||
|
case PROP_SUPPORTED_SESSION_TYPES:
|
||
|
_gdm_display_set_supported_session_types (self, g_value_get_boxed (value));
|
||
|
break;
|
||
|
+ case PROP_SHUTTING_DOWN:
|
||
|
+ _gdm_display_set_shutting_down (self, g_value_get_boolean (value));
|
||
|
+ break;
|
||
|
default:
|
||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gdm_display_get_property (GObject *object,
|
||
|
guint prop_id,
|
||
|
GValue *value,
|
||
|
GParamSpec *pspec)
|
||
|
{
|
||
|
GdmDisplay *self;
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
self = GDM_DISPLAY (object);
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
|
||
|
switch (prop_id) {
|
||
|
case PROP_ID:
|
||
|
g_value_set_string (value, priv->id);
|
||
|
break;
|
||
|
case PROP_STATUS:
|
||
|
g_value_set_int (value, priv->status);
|
||
|
break;
|
||
|
case PROP_SEAT_ID:
|
||
|
g_value_set_string (value, priv->seat_id);
|
||
|
break;
|
||
|
case PROP_SESSION_ID:
|
||
|
g_value_set_string (value, priv->session_id);
|
||
|
@@ -1043,60 +1058,63 @@ gdm_display_get_property (GObject *object,
|
||
|
priv->access_file?
|
||
|
gdm_display_access_file_get_path (priv->access_file) : NULL);
|
||
|
break;
|
||
|
case PROP_IS_LOCAL:
|
||
|
g_value_set_boolean (value, priv->is_local);
|
||
|
break;
|
||
|
case PROP_IS_CONNECTED:
|
||
|
g_value_set_boolean (value, priv->xcb_connection != NULL);
|
||
|
break;
|
||
|
case PROP_LAUNCH_ENVIRONMENT:
|
||
|
g_value_set_object (value, priv->launch_environment);
|
||
|
break;
|
||
|
case PROP_IS_INITIAL:
|
||
|
g_value_set_boolean (value, priv->is_initial);
|
||
|
break;
|
||
|
case PROP_HAVE_EXISTING_USER_ACCOUNTS:
|
||
|
g_value_set_boolean (value, priv->have_existing_user_accounts);
|
||
|
break;
|
||
|
case PROP_DOING_INITIAL_SETUP:
|
||
|
g_value_set_boolean (value, priv->doing_initial_setup);
|
||
|
break;
|
||
|
case PROP_SESSION_REGISTERED:
|
||
|
g_value_set_boolean (value, priv->session_registered);
|
||
|
break;
|
||
|
case PROP_ALLOW_TIMED_LOGIN:
|
||
|
g_value_set_boolean (value, priv->allow_timed_login);
|
||
|
break;
|
||
|
case PROP_SUPPORTED_SESSION_TYPES:
|
||
|
g_value_set_boxed (value, priv->supported_session_types);
|
||
|
break;
|
||
|
+ case PROP_SHUTTING_DOWN:
|
||
|
+ g_value_set_boolean (value, priv->shutting_down);
|
||
|
+ break;
|
||
|
default:
|
||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
handle_get_id (GdmDBusDisplay *skeleton,
|
||
|
GDBusMethodInvocation *invocation,
|
||
|
GdmDisplay *self)
|
||
|
{
|
||
|
char *id;
|
||
|
|
||
|
gdm_display_get_id (self, &id, NULL);
|
||
|
|
||
|
gdm_dbus_display_complete_get_id (skeleton, invocation, id);
|
||
|
|
||
|
g_free (id);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
handle_get_remote_hostname (GdmDBusDisplay *skeleton,
|
||
|
GDBusMethodInvocation *invocation,
|
||
|
GdmDisplay *self)
|
||
|
{
|
||
|
char *hostname;
|
||
|
|
||
|
gdm_display_get_remote_hostname (self, &hostname, NULL);
|
||
|
|
||
|
@@ -1397,60 +1415,68 @@ gdm_display_class_init (GdmDisplayClass *klass)
|
||
|
g_param_spec_boolean ("session-registered",
|
||
|
NULL,
|
||
|
NULL,
|
||
|
FALSE,
|
||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
|
||
|
g_object_class_install_property (object_class,
|
||
|
PROP_LAUNCH_ENVIRONMENT,
|
||
|
g_param_spec_object ("launch-environment",
|
||
|
NULL,
|
||
|
NULL,
|
||
|
GDM_TYPE_LAUNCH_ENVIRONMENT,
|
||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
g_object_class_install_property (object_class,
|
||
|
PROP_STATUS,
|
||
|
g_param_spec_int ("status",
|
||
|
"status",
|
||
|
"status",
|
||
|
-1,
|
||
|
G_MAXINT,
|
||
|
GDM_DISPLAY_UNMANAGED,
|
||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||
|
|
||
|
g_object_class_install_property (object_class,
|
||
|
PROP_SUPPORTED_SESSION_TYPES,
|
||
|
g_param_spec_boxed ("supported-session-types",
|
||
|
"supported session types",
|
||
|
"supported session types",
|
||
|
G_TYPE_STRV,
|
||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||
|
+
|
||
|
+ g_object_class_install_property (object_class,
|
||
|
+ PROP_SHUTTING_DOWN,
|
||
|
+ g_param_spec_boolean ("shutting-down",
|
||
|
+ NULL,
|
||
|
+ NULL,
|
||
|
+ FALSE,
|
||
|
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gdm_display_init (GdmDisplay *self)
|
||
|
{
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
|
||
|
priv->creation_time = time (NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gdm_display_finalize (GObject *object)
|
||
|
{
|
||
|
GdmDisplay *self;
|
||
|
GdmDisplayPrivate *priv;
|
||
|
|
||
|
g_return_if_fail (object != NULL);
|
||
|
g_return_if_fail (GDM_IS_DISPLAY (object));
|
||
|
|
||
|
self = GDM_DISPLAY (object);
|
||
|
priv = gdm_display_get_instance_private (self);
|
||
|
|
||
|
g_return_if_fail (priv != NULL);
|
||
|
|
||
|
g_debug ("GdmDisplay: Finalizing display: %s", priv->id);
|
||
|
g_free (priv->id);
|
||
|
g_free (priv->seat_id);
|
||
|
g_free (priv->session_class);
|
||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
||
|
index c70248f3..05851001 100644
|
||
|
--- a/daemon/gdm-manager.c
|
||
|
+++ b/daemon/gdm-manager.c
|
||
|
@@ -2759,117 +2759,120 @@ gdm_manager_init (GdmManager *manager)
|
||
|
NULL,
|
||
|
(GDestroyNotify)
|
||
|
g_object_unref);
|
||
|
manager->priv->transient_sessions = g_hash_table_new_full (NULL,
|
||
|
NULL,
|
||
|
(GDestroyNotify)
|
||
|
NULL,
|
||
|
(GDestroyNotify)
|
||
|
g_object_unref);
|
||
|
g_signal_connect (G_OBJECT (manager->priv->display_store),
|
||
|
"display-added",
|
||
|
G_CALLBACK (on_display_added),
|
||
|
manager);
|
||
|
|
||
|
g_signal_connect (G_OBJECT (manager->priv->display_store),
|
||
|
"display-removed",
|
||
|
G_CALLBACK (on_display_removed),
|
||
|
manager);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
unexport_display (const char *id,
|
||
|
GdmDisplay *display,
|
||
|
GdmManager *manager)
|
||
|
{
|
||
|
if (!g_dbus_connection_is_closed (manager->priv->connection))
|
||
|
g_dbus_object_manager_server_unexport (manager->priv->object_manager, id);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-finish_display (const char *id,
|
||
|
- GdmDisplay *display,
|
||
|
- GdmManager *manager)
|
||
|
+shut_down_display (const char *id,
|
||
|
+ GdmDisplay *display,
|
||
|
+ GdmManager *manager)
|
||
|
{
|
||
|
gdm_display_stop_greeter_session (display);
|
||
|
+
|
||
|
+ g_object_set (G_OBJECT (display), "shutting-down", TRUE, NULL);
|
||
|
+
|
||
|
if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED)
|
||
|
gdm_display_unmanage (display);
|
||
|
gdm_display_finish (display);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gdm_manager_dispose (GObject *object)
|
||
|
{
|
||
|
GdmManager *manager;
|
||
|
|
||
|
g_return_if_fail (object != NULL);
|
||
|
g_return_if_fail (GDM_IS_MANAGER (object));
|
||
|
|
||
|
manager = GDM_MANAGER (object);
|
||
|
|
||
|
g_return_if_fail (manager->priv != NULL);
|
||
|
|
||
|
gdm_manager_stop (manager);
|
||
|
|
||
|
g_clear_weak_pointer (&manager->priv->automatic_login_display);
|
||
|
|
||
|
#ifdef HAVE_LIBXDMCP
|
||
|
g_clear_object (&manager->priv->xdmcp_factory);
|
||
|
#endif
|
||
|
g_clear_object (&manager->priv->local_factory);
|
||
|
g_clear_pointer (&manager->priv->open_reauthentication_requests,
|
||
|
g_hash_table_unref);
|
||
|
g_clear_pointer (&manager->priv->transient_sessions,
|
||
|
g_hash_table_unref);
|
||
|
|
||
|
g_list_foreach (manager->priv->user_sessions,
|
||
|
(GFunc) gdm_session_close,
|
||
|
NULL);
|
||
|
g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref);
|
||
|
manager->priv->user_sessions = NULL;
|
||
|
|
||
|
g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
|
||
|
G_CALLBACK (on_display_added),
|
||
|
manager);
|
||
|
g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store),
|
||
|
G_CALLBACK (on_display_removed),
|
||
|
manager);
|
||
|
|
||
|
if (!g_dbus_connection_is_closed (manager->priv->connection)) {
|
||
|
gdm_display_store_foreach (manager->priv->display_store,
|
||
|
(GdmDisplayStoreFunc)unexport_display,
|
||
|
manager);
|
||
|
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager));
|
||
|
}
|
||
|
|
||
|
gdm_display_store_foreach (manager->priv->display_store,
|
||
|
- (GdmDisplayStoreFunc) finish_display,
|
||
|
+ (GdmDisplayStoreFunc) shut_down_display,
|
||
|
manager);
|
||
|
|
||
|
gdm_display_store_clear (manager->priv->display_store);
|
||
|
|
||
|
g_dbus_object_manager_server_set_connection (manager->priv->object_manager, NULL);
|
||
|
|
||
|
g_clear_object (&manager->priv->connection);
|
||
|
g_clear_object (&manager->priv->object_manager);
|
||
|
g_clear_object (&manager->priv->display_store);
|
||
|
|
||
|
G_OBJECT_CLASS (gdm_manager_parent_class)->dispose (object);
|
||
|
}
|
||
|
|
||
|
GdmManager *
|
||
|
gdm_manager_new (void)
|
||
|
{
|
||
|
if (manager_object != NULL) {
|
||
|
g_object_ref (manager_object);
|
||
|
} else {
|
||
|
gboolean res;
|
||
|
|
||
|
manager_object = g_object_new (GDM_TYPE_MANAGER, NULL);
|
||
|
g_object_add_weak_pointer (manager_object,
|
||
|
(gpointer *) &manager_object);
|
||
|
res = register_manager (manager_object);
|
||
|
if (! res) {
|
||
|
g_object_unref (manager_object);
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
--
|
||
|
2.37.0.rc1
|
||
|
|