On Sat, Sep 13, 2014 at 10:32:42PM +0100, Dominik Vogt wrote:
> It's perfectly allright if the *User* specifies these strings, but
> it would greatly simplify the internal logic if the strings could
> be translated to numbers in FScreen.

Hmm.  Maybe see the patch below?  It won't (yet) alleviate the need to
change your configuration file, but it does provide:

$[screennum.NAME]

Where NAME is some monitor name defined by XRandR.  This would in theory
allow for use of monitor names translated to number, or a direct number
once I resurrect the code to support that (think in terms of extended
geometry string specifiers:  XxY+A-B@somescreen).

I've no idea if this is a good way to go or not.  See comments in-line
as for the massive assumption I'm making, but Works For Me (tm).

diff --git a/libs/FScreen.c b/libs/FScreen.c
index 0ed5bcb..acceb29 100644
--- a/libs/FScreen.c
+++ b/libs/FScreen.c
@@ -50,6 +50,24 @@ static int no_of_screens;
 static struct monitor  *FindScreenOfXY(int x, int y);
 static struct monitor  *monitor_new(void);
 static void             init_monitor_contents(void);
+static void             monitor_print_debug(struct monitor *);
+
+static void monitor_print_debug(struct monitor *m)
+{
+       if (m == NULL)
+               return;
+
+       fprintf(stderr, "XRandR:  Added monitor:\n"
+               "  name: %s\n"
+               "  num:  %d\n"
+               "  x:    %d\n"
+               "  y:    %d\n"
+               "  w:    %d\n"
+               "  h:    %d\n\n",
+               m->name, m->number,
+               m->coord.x, m->coord.y,
+               m->coord.w, m->coord.h);
+}
 
 static void GetMouseXY(XEvent *eventp, int *x, int *y)
 {
@@ -131,6 +149,7 @@ void FScreenInit(Display *dpy)
        int                      i;
        int                      err_base = 0, event = 0;
        int                      is_randr_present = 0;
+       int                      monitor_number = 0;
 
        disp = dpy;
 
@@ -150,6 +169,7 @@ void FScreenInit(Display *dpy)
        TAILQ_INIT(&monitor_q);
 
        m = monitor_new();
+       m->number = monitor_number;
        m->coord.x = 0;
        m->coord.y = 0;
        m->coord.w = DisplayWidth(disp, DefaultScreen(disp));
@@ -157,15 +177,42 @@ void FScreenInit(Display *dpy)
        m->name = mvwm_strdup("global");
        TAILQ_INSERT_HEAD(&monitor_q, m, entry);
 
+       monitor_print_debug(m);
+
        if (!is_randr_present)
                goto done;
 
        /* XRandR is present, so query the screens we have. */
+       /* TA:  2014-09-13:  FIXME FIXME FIXME:
+        *
+        * How do we handle this crude ordering with monitors being
+        * added/removed?
+        */
        res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy));
        if (res != NULL) {
                crtc = NULL;
                no_of_screens = res->noutput;
-               for (i = 0; i < res->noutput; i++) {
+               /* TA:  2014-09-13:  XXX: The XRandR API is completely geared
+                * towards using outputs referred to by string (names) as
+                * found in either one's xorg.conf or via EDID.
+                *
+                * Unfortunately, Xinerama didn't have this, and hence
+                * maintained a screen ordering instead; outputs were numbered,
+                * in fvwm's case: 1 -> n, where "0" was reserved for the
+                * "global" screen (entire root window combined across all
+                * outputs).
+                *
+                * XRandR doesn't seem to offer any means of querying outputs
+                * based on logical ordering (such as whether they're
+                * left/right/up/down of one another respectively), despite
+                * being allowed to configure display outputs to have position
+                * information.
+                *
+                * So for now, rather crudely, iterate over the output display
+                * in reverse.  This seems to work OK in simple layout cases,
+                * and will allow screens to be referred to by number:  1 -> n)
+                */
+               for (i = res->noutput - 1; i > -1; i--) {
                        oinfo = XRRGetOutputInfo(dpy, res, res->outputs[i]);
 
                        if (oinfo->crtc == None) {
@@ -177,6 +224,7 @@ void FScreenInit(Display *dpy)
                                continue;
 
                        m = monitor_new();
+                       m->number = ++monitor_number;
                        m->coord.x = crtc->x;
                        m->coord.y = crtc->y;
                        m->coord.w = crtc->width;
@@ -185,6 +233,8 @@ void FScreenInit(Display *dpy)
 
                        TAILQ_INSERT_TAIL(&monitor_q, m, entry);
 
+                       monitor_print_debug(m);
+
                        XRRFreeCrtcInfo(crtc);
                }
                XRRFreeScreenResources(res);
@@ -236,6 +286,24 @@ init_monitor_contents(void)
        }
 }
 
+int
+monitor_number_by_name(const char *name)
+{
+       struct monitor *m;
+
+       m = monitor_by_name(name);
+
+       /* XXX: What if 'm' is NULL?  Return first screen?  That's what the old
+        * Xinerama code would have done.
+        *
+        * We'll return -1 to indicate failure.
+        */
+       if (m == NULL)
+               return (-1);
+
+       return (m->number);
+}
+
 /* Intended to be called by modules.  Simply pass in the parameter from the
  * config string sent by mvwm. */
 void FScreenConfigureModule(char *args)
diff --git a/libs/FScreen.h b/libs/FScreen.h
index 624d8ab..f726ea6 100644
--- a/libs/FScreen.h
+++ b/libs/FScreen.h
@@ -29,6 +29,7 @@ typedef enum
 
 struct monitor {
        char    *name;
+       int      number;
        struct {
                int x;
                int y;
@@ -68,6 +69,7 @@ struct monitors               monitor_q;
 struct monitor *monitor_get_current(void);
 struct monitor *monitor_by_name(const char *);
 struct monitor *monitor_by_xy(int, int);
+int             monitor_number_by_name(const char *);
 int             monitor_should_ignore_global(struct monitor *);
 
 #define FSCREEN_MANGLE_USPOS_HINTS_MAGIC ((short)-32109)
diff --git a/mvwm/expand.c b/mvwm/expand.c
index c0538e1..93e6cf3 100644
--- a/mvwm/expand.c
+++ b/mvwm/expand.c
@@ -68,6 +68,7 @@ static char *partial_function_vars[] =
        "hilight.cs",
        "infostore.",
        "shadow.cs",
+       "screennum.",
        NULL
 };
 
@@ -151,7 +152,8 @@ enum
        VAR_GT_,
        VAR_HILIGHT_CS,
        VAR_INFOSTORE_,
-       VAR_SHADOW_CS
+       VAR_SHADOW_CS,
+       VAR_SCREEN_NUM_NAME
 } partial_extended_vars;
 
 enum
@@ -446,6 +448,19 @@ static signed int expand_vars_extended(
                        string = allocated_string;
                }
                goto GOT_STRING;
+       case VAR_SCREEN_NUM_NAME:
+               is_numeric = True;
+
+               if (rest == NULL)
+                       return -1;
+
+               /* Can't fail; always returns an int. */
+               val = monitor_number_by_name(rest);
+
+               if (val == -1)
+                       return -1;
+
+               goto GOT_STRING;
        default:
                break;
        }


-- Thomas Adam

-- 
"Deep in my heart I wish I was wrong.  But deep in my heart I know I am
not." -- Morrissey ("Girl Least Likely To" -- off of Viva Hate.)

Reply via email to