+void user_elect_display(User *u) {
+ Session *graphical = NULL, *text = NULL, *other = NULL, *s;
+
+ assert(u);
+
+ /* This elects a primary session for each user, which we call
+ * the "display". We try to keep the assignment stable, but we
+ * "upgrade" to better choices. */
+
+ LIST_FOREACH(sessions_by_user, s, u->sessions) {
+
+ if (s->class != SESSION_USER)
+ continue;
+
+ if (s->stopping)
+ continue;
+
+ if (SESSION_TYPE_IS_GRAPHICAL(s->type))
+ graphical = s;
+ else if (s->type == SESSION_TTY)
+ text = s;
+ else
+ other = s;
+ }
+
+ if (graphical &&
+ (!u->display ||
+ u->display->class != SESSION_USER ||
+ u->display->stopping ||
+ !SESSION_TYPE_IS_GRAPHICAL(u->display->type))) {
+ u->display = graphical;
+ return;
+ }
+
+ if (text &&
+ (!u->display ||
+ u->display->class != SESSION_USER ||
+ u->display->stopping ||
+ u->display->type != SESSION_TTY)) {
+ u->display = text;
+ return;
+ }
+
+ if (other &&
+ (!u->display ||
+ u->display->class != SESSION_USER ||
+ u->display->stopping))
+ u->display = other;
+}
+