On Fri, Nov 19, 2021 at 02:14:57AM +0100, Dominik Vogt wrote:
> For debugging I need to run another fvwm in xnest, but that
> doesn't support randr.
>
> The attached patch mocks up a global monitor to use if init fails.
> It works at the first glance, but the patch is not very clean.
> Please comment.

Sorry, wrong patch, this is the correct one.

Ciao

Dominik ^_^  ^_^

--

Dominik Vogt
From c821293866fb8c56f00d8cee52b687097e5045a3 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <dominik.v...@gmx.de>
Date: Fri, 19 Nov 2021 02:09:28 +0100
Subject: [PATCH 2/3] Fake a global monitor when RandR is not available.

---
 libs/FScreen.c | 69 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 17 deletions(-)

diff --git a/libs/FScreen.c b/libs/FScreen.c
index 32ee78a7..e00af438 100644
--- a/libs/FScreen.c
+++ b/libs/FScreen.c
@@ -125,6 +125,13 @@ monitor_refresh_global(void)
 		monitor_global = monitor_new();
 		monitor_global->si = screen_info_new();
 		monitor_global->si->name = fxstrdup(GLOBAL_SCREEN_NAME);
+		if (!is_randr_present)
+		{
+			TAILQ_INSERT_TAIL(
+				&screen_info_q, monitor_global->si, entry);
+			TAILQ_INSERT_TAIL(
+				&monitor_q, monitor_global, entry);
+		}
 	}

 	/* At this point, the global screen has been initialised.  Refresh the
@@ -342,8 +349,12 @@ monitor_assign_virtual(struct monitor *ref)
 void
 FScreenSelect(Display *dpy)
 {
-	XRRSelectInput(disp, DefaultRootWindow(disp),
-		RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
+	if (is_randr_present)
+	{
+		XRRSelectInput(
+			disp, DefaultRootWindow(disp),
+			RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
+	}
 }

 void
@@ -352,6 +363,10 @@ monitor_output_change(Display *dpy, XRRScreenChangeNotifyEvent *e)
 	XRRScreenResources	*res;
 	struct monitor		*m = NULL;

+	if (!is_randr_present)
+	{
+		return;
+	}
 	fvwm_debug(__func__, "%s: outputs have changed\n", __func__);

 	if ((res = XRRGetScreenResources(dpy, e->root)) == NULL) {
@@ -511,18 +526,19 @@ void FScreenInit(Display *dpy)
 	if (!XRRQueryExtension(dpy, &randr_event, &err_base) ||
 	    !XRRQueryVersion (dpy, &major, &minor)) {
 		fvwm_debug(__func__, "RandR not present");
-		goto randr_fail;
+		goto no_randr;
 	}

 	if (major == 1 && minor >= 5)
+	{
 		is_randr_present = true;
-
-
-	if (!is_randr_present) {
+	}
+	else
+	{
 		/* Something went wrong. */
 		fvwm_debug(__func__, "Couldn't initialise XRandR: %s\n",
 			   strerror(errno));
-		goto randr_fail;
+		goto no_randr;
 	}

 	fvwm_debug(__func__, "Using RandR %d.%d\n", major, minor);
@@ -533,13 +549,21 @@ void FScreenInit(Display *dpy)
 	if (res == NULL || (res != NULL && res->noutput == 0)) {
 		XRRFreeScreenResources(res);
 		fvwm_debug(__func__, "RandR present, yet no outputs found.");
-		goto randr_fail;
+		is_randr_present = false;
+		goto no_randr;
 	}
 	XRRFreeScreenResources(res);

 	scan_screens(dpy);
+  no_randr:
 	is_tracking_shared = false;

+	if (!is_randr_present)
+	{
+		fprintf(stderr, "Unable to initialise RandR\n");
+		monitor_refresh_global();
+	}
+
 	TAILQ_FOREACH(m, &monitor_q, entry) {
 		m->Desktops = fxcalloc(1, sizeof *m->Desktops);
 		m->Desktops->name = NULL;
@@ -552,10 +576,6 @@ void FScreenInit(Display *dpy)
 	monitor_check_primary();

 	return;
-
-randr_fail:
-	fprintf(stderr, "Unable to initialise RandR\n");
-	exit(101);
 }

 void
@@ -620,6 +640,10 @@ monitor_get_count(void)
 	struct monitor	*m = NULL;
 	int		 c = 0;

+	if (!is_randr_present)
+	{
+		return 1;
+	}
 	TAILQ_FOREACH(m, &monitor_q, entry) {
 		if (m->flags & MONITOR_DISABLED)
 			continue;
@@ -755,7 +779,18 @@ FScreenOfPointerXY(int x, int y)
 Bool FScreenGetScrRect(fscreen_scr_arg *arg, fscreen_scr_t screen,
 			int *x, int *y, int *w, int *h)
 {
-	struct monitor	*m = FindScreen(arg, screen);
+	struct monitor *m;
+
+	if (is_randr_present)
+	{
+		m = FindScreen(arg, screen);
+	}
+	else
+	{
+		/* make sure a monitor exists */
+		monitor_check_primary();
+		m = monitor_global;
+	}
 	if (m == NULL) {
 		fvwm_debug(__func__, "%s: m is NULL\n", __func__);
 		return (True);
@@ -895,10 +930,10 @@ void FScreenGetResistanceRect(
 Bool FScreenIsRectangleOnScreen(fscreen_scr_arg *arg, fscreen_scr_t screen,
 				rectangle *rec)
 {
-	int sx;
-	int sy;
-	int sw;
-	int sh;
+	int sx = 0;
+	int sy = 0;
+	int sw = 0;
+	int sh = 0;

 	FScreenGetScrRect(arg, screen, &sx, &sy, &sw, &sh);

--
2.30.2

Reply via email to