Display *
display_new (DisplayServer *display_server)
{
- Display *display = g_object_new (DISPLAY_TYPE, NULL);
+ Display *display;
+ g_return_val_if_fail (display_server != NULL, NULL);
+
+ display = g_object_new (DISPLAY_TYPE, NULL);
display->priv->display_server = g_object_ref (display_server);
return display;
return;
}
- if (!display->priv->display_server)
+ if (display_server_get_is_stopped (display->priv->display_server))
return;
/* Start the session for the authenticated user */
{
g_debug ("Display server stopped");
- g_signal_handlers_disconnect_matched (display->priv->display_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
- g_object_unref (display->priv->display_server);
- display->priv->display_server = NULL;
-
/* Stop this display, it will be restarted by the seat if necessary */
display_stop (display);
}
return TRUE;
}
+gboolean
+display_get_is_ready (Display *display)
+{
+ g_return_val_if_fail (display != NULL, FALSE);
+
+ return display->priv->is_ready;
+}
+
+void
+display_lock (Display *display)
+{
+ g_return_if_fail (display != NULL);
+
+ if (!display->priv->session)
+ return;
+
+ g_debug ("Locking display");
+
+ session_lock (display->priv->session);
+}
+
+void
+display_unlock (Display *display)
+{
+ g_return_if_fail (display != NULL);
+
+ if (!display->priv->session)
+ return;
+
+ g_debug ("Unlocking display");
+
+ session_unlock (display->priv->session);
+}
+
void
display_stop (Display *display)
{
}
/* Stop the display server after that */
- if (display->priv->display_server)
+ if (!display_server_get_is_stopped (display->priv->display_server))
{
display_server_stop (display->priv->display_server);
- if (display->priv->display_server && !display_server_get_is_stopped (display->priv->display_server))
+ if (!display_server_get_is_stopped (display->priv->display_server))
return;
- g_signal_handlers_disconnect_matched (display->priv->display_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
- g_object_unref (display->priv->display_server);
- display->priv->display_server = NULL;
}
display->priv->stopped = TRUE;
}
gboolean
-display_get_is_ready (Display *display)
+display_get_is_stopped (Display *display)
{
g_return_val_if_fail (display != NULL, FALSE);
-
- return display->priv->is_ready;
-}
-
-void
-display_lock (Display *display)
-{
- g_return_if_fail (display != NULL);
-
- if (!display->priv->session)
- return;
-
- g_debug ("Locking display");
-
- session_lock (display->priv->session);
-}
-
-void
-display_unlock (Display *display)
-{
- g_return_if_fail (display != NULL);
-
- if (!display->priv->session)
- return;
-
- g_debug ("Unlocking display");
-
- session_unlock (display->priv->session);
+ return display->priv->stopped;
}
static gboolean
self = DISPLAY (object);
- if (self->priv->display_server)
- {
- g_signal_handlers_disconnect_matched (self->priv->display_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
- g_object_unref (self->priv->display_server);
- }
+ g_signal_handlers_disconnect_matched (self->priv->display_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
+ g_object_unref (self->priv->display_server);
g_free (self->priv->greeter_session);
if (self->priv->greeter)
{
void display_stop (Display *display);
+gboolean display_get_is_stopped (Display *display);
+
G_END_DECLS
#endif /* _DISPLAY_H_ */
return SESSION (session);
}
-static void
-seat_xdmcp_session_display_removed (Seat *seat, Display *display)
-{
- seat_stop (seat);
-}
-
static void
seat_xdmcp_session_init (SeatXDMCPSession *seat)
{
seat_class->create_display_server = seat_xdmcp_session_create_display_server;
seat_class->create_session = seat_xdmcp_session_create_session;
- seat_class->display_removed = seat_xdmcp_session_display_removed;
object_class->finalize = seat_xdmcp_session_finalize;
g_type_class_add_private (klass, sizeof (SeatXDMCPSessionPrivate));
static void
seat_xlocal_set_active_display (Seat *seat, Display *display)
{
- gint number = xserver_local_get_vt (XSERVER_LOCAL (XSERVER (display_get_display_server (display))));
- if (number >= 0)
- vt_set_active (number);
+ gint vt = xserver_local_get_vt (XSERVER_LOCAL (display_get_display_server (display)));
+ if (vt >= 0)
+ vt_set_active (vt);
SEAT_CLASS (seat_xlocal_parent_class)->set_active_display (seat, display);
}
+static Display *
+seat_xlocal_get_active_display (Seat *seat)
+{
+ gint vt;
+ GList *link;
+
+ vt = vt_get_active ();
+ if (vt < 0)
+ return NULL;
+
+ for (link = seat_get_displays (seat); link; link = link->next)
+ {
+ Display *display = link->data;
+ XServerLocal *xserver;
+
+ xserver = XSERVER_LOCAL (display_get_display_server (display));
+ if (xserver_local_get_vt (xserver) == vt)
+ return display;
+ }
+
+ return NULL;
+}
+
static void
seat_xlocal_run_script (Seat *seat, Display *display, Process *script)
{
SEAT_CLASS (seat_xlocal_parent_class)->run_script (seat, display, script);
}
-static void
-seat_xlocal_display_removed (Seat *seat, Display *display)
-{
- if (seat_get_is_stopping (seat))
- return;
-
- /* If this is the only display and it failed to start then stop this seat */
- if (g_list_length (seat_get_displays (seat)) == 0 && !display_get_is_ready (display))
- {
- g_debug ("Stopping X local seat, failed to start a display");
- seat_stop (seat);
- return;
- }
-
- /* Show a new greeter */
- if (display == seat_get_active_display (seat))
- {
- g_debug ("Active display stopped, switching to greeter");
- seat_switch_to_greeter (seat);
- }
-}
-
static void
seat_xlocal_init (SeatXLocal *seat)
{
seat_class->create_display_server = seat_xlocal_create_display_server;
seat_class->create_session = seat_xlocal_create_session;
seat_class->set_active_display = seat_xlocal_set_active_display;
+ seat_class->get_active_display = seat_xlocal_get_active_display;
seat_class->run_script = seat_xlocal_run_script;
- seat_class->display_removed = seat_xlocal_display_removed;
}
SEAT_CLASS (seat_xremote_parent_class)->run_script (seat, display, script);
}
-static void
-seat_xremote_display_removed (Seat *seat, Display *display)
-{
- /* Can't restart the display, so remove this seat */
- seat_stop (seat);
-}
-
static void
seat_xremote_init (SeatXRemote *seat)
{
seat_class->create_display_server = seat_xremote_create_display_server;
seat_class->create_session = seat_xremote_create_session;
seat_class->run_script = seat_xremote_run_script;
- seat_class->display_removed = seat_xremote_display_removed;
}
SEAT_CLASS (seat_xvnc_parent_class)->run_script (seat, display, script);
}
-static void
-seat_xvnc_display_removed (Seat *seat, Display *display)
-{
- seat_stop (seat);
-}
-
static void
seat_xvnc_init (SeatXVNC *seat)
{
seat_class->create_display_server = seat_xvnc_create_display_server;
seat_class->create_session = seat_xvnc_create_session;
seat_class->run_script = seat_xvnc_run_script;
- seat_class->display_removed = seat_xvnc_display_removed;
object_class->finalize = seat_xdmcp_session_finalize;
g_type_class_add_private (klass, sizeof (SeatXVNCPrivate));
/* The displays for this seat */
GList *displays;
- /* The active display */
- Display *active_display;
-
/* TRUE if stopping this seat (waiting for displays to stop) */
gboolean stopping;
seat_get_active_display (Seat *seat)
{
g_return_val_if_fail (seat != NULL, NULL);
- return seat->priv->active_display;
+ return SEAT_GET_CLASS (seat)->get_active_display (seat);
}
gboolean
{
Display *display = link->data;
+ if (display_get_is_stopped (display))
+ continue;
+
/* If already logged in, then switch to that display */
if (g_strcmp0 (display_get_username (display), username) == 0)
{
static void
display_stopped_cb (Display *display, Seat *seat)
{
- seat->priv->displays = g_list_remove (seat->priv->displays, display);
+ gboolean is_active;
+
+ is_active = display == seat_get_active_display (seat);
+
g_signal_handlers_disconnect_matched (display, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
- g_signal_emit (seat, signals[DISPLAY_REMOVED], 0, display);
+ seat->priv->displays = g_list_remove (seat->priv->displays, display);
g_object_unref (display);
+ g_signal_emit (seat, signals[DISPLAY_REMOVED], 0, display);
+
+ /* If no more displays running either start a greeter or stop the seat */
+ if (!seat->priv->stopping)
+ {
+ if (g_list_length (seat->priv->displays) == 0)
+ {
+ /* If failed to start then stop this seat */
+ if (!display_get_is_ready (display))
+ {
+ g_debug ("Stopping seat, failed to start a display");
+ seat_stop (seat);
+ }
+ /* Attempt to start a greeter */
+ else if (!seat->priv->can_switch)
+ {
+ g_debug ("Stopping seat, display stopped");
+ seat_stop (seat);
+ }
+
+ else if (!seat_switch_to_greeter (seat))
+ {
+ g_debug ("Stopping seat, unable to start greeter");
+ seat_stop (seat);
+ }
+ }
+ else if (is_active)
+ {
+ g_debug ("Active display stopped, switching to greeter");
+ if (!seat_switch_to_greeter (seat))
+ {
+ g_debug ("Stopping seat, unable to start greeter");
+ seat_stop (seat);
+ }
+ }
+ }
+
check_stopped (seat);
}
g_signal_emit (seat, signals[DISPLAY_ADDED], 0, display);
/* Switch to this display if currently not looking at anything */
- if (!seat->priv->active_display)
+ if (seat_get_active_display (seat) == NULL)
seat_set_active_display (seat, display);
return display_start (display);
static void
seat_real_set_active_display (Seat *seat, Display *display)
{
- if (display == seat->priv->active_display)
- return;
+ GList *link;
- if (seat->priv->active_display)
+ for (link = seat->priv->displays; link; link = link->next)
{
- /* Stop the existing display if it is a greeter */
- if (!display_get_username (seat->priv->active_display))
+ Display *d = link->data;
+
+ if (d == display)
+ continue;
+
+ /* Stop any greeters and lock any other sessions */
+ if (!display_get_username (d))
{
- g_debug ("Stopping greeter display being switched from");
- display_stop (seat->priv->active_display);
+ g_debug ("Stopping background greeter");
+ display_stop (d);
}
- /* Otherwise lock it */
else
- {
- display_lock (seat->priv->active_display);
- }
- g_object_unref (seat->priv->active_display);
- }
- seat->priv->active_display = g_object_ref (display);
+ display_lock (d);
+ }
+}
+
+static Display *
+seat_real_get_active_display (Seat *seat)
+{
+ return NULL;
}
static void
g_hash_table_unref (self->priv->properties);
g_free (self->priv->guest_username);
g_list_free_full (self->priv->displays, g_object_unref);
- if (self->priv->active_display)
- g_object_unref (self->priv->active_display);
G_OBJECT_CLASS (seat_parent_class)->finalize (object);
}
klass->setup = seat_real_setup;
klass->start = seat_real_start;
klass->set_active_display = seat_real_set_active_display;
+ klass->get_active_display = seat_real_get_active_display;
klass->run_script = seat_real_run_script;
klass->stop = seat_real_stop;
DisplayServer *(*create_display_server) (Seat *seat);
Session *(*create_session) (Seat *seat, Display *display);
void (*set_active_display)(Seat *seat, Display *display);
+ Display *(*get_active_display)(Seat *seat);
void (*run_script)(Seat *seat, Display *display, Process *script);
void (*stop)(Seat *seat);
/* VT to run on */
gint vt;
+ /* TRUE if holding a reference to the VT */
+ gboolean have_vt_ref;
+
/* TRUE if replacing Plymouth */
gboolean replacing_plymouth;
};
if (self->priv->vt < 0)
self->priv->vt = vt_get_unused ();
if (self->priv->vt >= 0)
+ {
vt_ref (self->priv->vt);
+ self->priv->have_vt_ref = TRUE;
+ }
return self;
}
{
g_debug ("X server stopped");
- g_object_unref (server->priv->xserver_process);
- server->priv->xserver_process = NULL;
-
xserver_local_release_display_number (xserver_get_display_number (XSERVER (server)));
if (xserver_get_authority (XSERVER (server)) && server->priv->authority_file)
server->priv->authority_file = NULL;
}
- if (server->priv->vt >= 0)
+ if (server->priv->have_vt_ref)
{
vt_unref (server->priv->vt);
- server->priv->vt = -1;
- }
+ server->priv->have_vt_ref = FALSE;
+ }
if (server->priv->replacing_plymouth && plymouth_get_is_running ())
{
g_free (self->priv->xdmcp_key);
if (self->priv->authority_file)
g_object_unref (self->priv->authority_file);
- if (self->priv->vt >= 0)
+ if (self->priv->have_vt_ref)
vt_unref (self->priv->vt);
G_OBJECT_CLASS (xserver_local_parent_class)->finalize (object);