summaryrefslogtreecommitdiff
path: root/daemon/gdm-session-worker.c
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2015-02-27 07:43:39 -0500
committerRay Strode <rstrode@redhat.com>2015-02-27 10:31:42 -0500
commite699b438e64289c79f690e613399d935d9aac11c (patch)
treedf690ce434c67d07b71554e08fc9fa64ea86e484 /daemon/gdm-session-worker.c
parent5dcbc5ac1e8877787587d916a0bbcc6c4136a7c0 (diff)
downloadgdm-e699b438e64289c79f690e613399d935d9aac11c.tar.gz
worker: force KD_GRAPHICS mode before doing VT switch
If we switch VTs when in KD_TEXT mode there's obvious flicker. This commit addresses that problem by going to KD_GRAPHICS mode before switching VTs. Ideally, we wouldn't switch VTs at all, and instead leave it up to the display servers to manage via logind. At the moment, the display servers don't use logind properly, though, so do this as a stop gap. https://bugzilla.gnome.org/show_bug.cgi?id=745031
Diffstat (limited to 'daemon/gdm-session-worker.c')
-rw-r--r--daemon/gdm-session-worker.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index a5c684c6..470428ba 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -31,6 +31,7 @@
#ifdef WITH_SYSTEMD
#include <sys/ioctl.h>
#include <sys/vt.h>
+#include <sys/kd.h>
#endif
#include <errno.h>
#include <grp.h>
@@ -105,6 +106,9 @@
#define MAX_FILE_SIZE 65536
#define MAX_LOGS 5
+#define RELEASE_DISPLAY_SIGNAL SIGUSR1
+#define ACQUIRE_DISPLAY_SIGNAL SIGUSR2
+
enum {
GDM_SESSION_WORKER_STATE_NONE = 0,
GDM_SESSION_WORKER_STATE_SETUP_COMPLETE,
@@ -959,12 +963,51 @@ gdm_session_worker_stop_auditor (GdmSessionWorker *worker)
#ifdef WITH_SYSTEMD
static void
+on_release_display (int signal)
+{
+ int fd;
+
+ fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
+ ioctl(fd, VT_RELDISP, 1);
+ close(fd);
+}
+
+static void
+on_acquire_display (int signal)
+{
+ int fd;
+
+ fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
+ ioctl(fd, VT_RELDISP, VT_ACKACQ);
+ close(fd);
+}
+
+static void
jump_to_vt (GdmSessionWorker *worker,
int vt_number)
{
int fd;
+ gboolean just_opened_tty = FALSE;
+
+ if (worker->priv->session_tty_fd != -1) {
+ struct vt_mode setmode_request = { 0 };
+
+ fd = worker->priv->session_tty_fd;
+
+ ioctl (fd, KDSETMODE, KD_GRAPHICS);
+
+ setmode_request.mode = VT_PROCESS;
+ setmode_request.relsig = RELEASE_DISPLAY_SIGNAL;
+ setmode_request.acqsig = ACQUIRE_DISPLAY_SIGNAL;
+ ioctl (fd, VT_SETMODE, &setmode_request);
+
+ signal (RELEASE_DISPLAY_SIGNAL, on_release_display);
+ signal (ACQUIRE_DISPLAY_SIGNAL, on_acquire_display);
+ } else {
+ fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
+ just_opened_tty = TRUE;
+ }
- fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
if (ioctl (fd, VT_ACTIVATE, vt_number) < 0) {
g_debug ("GdmSessionWorker: couldn't initiate jump to VT %d: %m",
vt_number);
@@ -972,7 +1015,10 @@ jump_to_vt (GdmSessionWorker *worker,
g_debug ("GdmSessionWorker: couldn't finalize jump to VT %d: %m",
vt_number);
}
- close(fd);
+
+ if (just_opened_tty) {
+ close(fd);
+ }
}
#endif