https://github.com/brltty/brltty/pull/264

commit 2810e9fdb14174d045f870a012a576d30d11348d
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Sun Apr 26 00:00:36 2020 +0200

    libbrlapi: Automatically get VT nr from logind
    
    Notably on gnome with Wayland, XDG_VTNR may not be getting defined. We
    can however just directly ask logind which VT our process is running on.

diff --git a/Programs/brlapi_client.c b/Programs/brlapi_client.c
index c669db26f..a49b89b58 100644
--- a/Programs/brlapi_client.c
+++ b/Programs/brlapi_client.c
@@ -92,6 +92,10 @@
 #define MAXIMUM_VIRTUAL_CONSOLE 1
 #endif /* MAXIMUM_VIRTUAL_CONSOLE */
 
+#ifdef HAVE_SD_SESSION_GET_VT
+#include <systemd/sd-login.h>
+#endif /* HAVE_SD_SESSION_GET_VT */
+
 #define BRLAPI_NO_DEPRECATED
 #include "brlapi.h"
 #include "brlapi_protocol.h"
@@ -1602,9 +1606,65 @@ int BRLAPI_STDCALL brlapi__enterTtyModeWithPath(brlapi_handle_t *handle, int *tt
   /* OK, Now we know where we are, so get the effective control of the terminal! */
   *nbTtys = 0;
   ttytreepath = getenv("WINDOWPATH");
-  if (!ttytreepath && getenv("DISPLAY"))
+  if (!ttytreepath && (getenv("DISPLAY") || getenv("WAYLAND_DISPLAY"))) {
     /* Cope with some DMs which are not setting WINDOWPATH (e.g. gdm 3.12) */
     ttytreepath = getenv("XDG_VTNR");
+
+#ifdef HAVE_SD_SESSION_GET_VT
+    if (!ttytreepath) {
+      /* Fallback to asking logind */
+      char *id;
+      unsigned vtnr = 0;
+      int ret;
+
+      ret = sd_pid_get_session(0, &id);
+      if (ret == 0 && id != NULL) {
+	sd_session_get_vt(id, &vtnr);
+	free(id);
+      } else {
+	char **sessions;
+	/* Not even logind knows :/ we are probably logged in from gdm */
+	ret = sd_uid_get_sessions(getuid(), 0, &sessions);
+
+	if (ret > 0) {
+	  int i, chosen = -1;
+
+	  for (i = 0; i < ret; i++) {
+	    char *type;
+
+	    ret = sd_session_get_type(sessions[i], &type);
+	if (ret == 0) {
+	      if (strcmp(type, "tty") != 0 &&
+	          strcmp(type, "unspecified") != 0) {
+		/* x11, wayland or mir, so graphical.
+		 * User normally has only one of them */
+		if (chosen >= 0) {
+		  /* Oops, several sessions? That is not supposed to happen, better
+		   * choose none of them. */
+		  chosen = -1;
+		  break;
+		}
+		chosen = i;
+	      }
+	    }
+	  }
+
+	  if (chosen >= 0) sd_session_get_vt(sessions[i], &vtnr);
+
+	  for (i = 0; i < ret; i++) free(sessions[i]);
+	  free(sessions);
+	}
+      }
+
+      if (vtnr) {
+	  size_t size = sizeof(vtnr)*3 + 1;
+	  ttytreepath=alloca(size);
+	  snprintf(ttytreepath, size, "%u", vtnr);
+	}
+      }
+#endif /* HAVE_SD_SESSION_GET_VT */
+  }
+
   if (ttytreepath)
   for(; *ttytreepath && t-(nbTtys+1)<=BRLAPI_MAXPACKETSIZE/sizeof(uint32_t);
     *t++ = htonl(ttypath), (*nbTtys)++, ttytreepath = ttytreepathstop+1) {
diff --git a/config.h.in b/config.h.in
index eefdbd93f..2ab0837da 100644
--- a/config.h.in
+++ b/config.h.in
@@ -254,6 +254,9 @@ extern "C" {
 /* Define this if the function shl_load is available. */
 #undef HAVE_SHL_LOAD
 
+/* Define this if the function sd_session_get_vt is available in libsystemd. */
+#undef HAVE_SD_SESSION_GET_VT
+
 /* Define this to be a string containing the copyright notice. */
 #undef PACKAGE_COPYRIGHT
 
diff --git a/configure.ac b/configure.ac
index 2588d9f8e..33e995662 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1230,6 +1230,17 @@ in
       ;;
 esac
 
+BRLTTY_HAVE_PACKAGE([systemd], [libsystemd], [
+    brltty_libs_save="${LIBS}"
+    LIBS="${LIBS} ${systemd_libs}"
+    AC_CHECK_FUNC([sd_session_get_vt], [
+      AC_DEFINE([HAVE_SD_SESSION_GET_VT], [1],
+                [Define this if the function sd_session_get_vt is available in libsystemd.])
+      api_libraries="${api_libraries} ${systemd_libs}"
+    ])
+    LIBS="${brltty_libs_save}"
+])
+
 BRLTTY_ARG_PACKAGE([params], [boot parameters], [], [dnl
    linux*)
       params_package="linux"
