Subject: FVWM single-logical-screen patch

From: Sidik Isani <[email-masked]>
Date: Tue, 4 Sep 2001 09:41:53 -1000 (HST)

Hello FVWM workers -

   I've just generated a small patch against fvwm-snap-20010831
   to allow "Xinerama" behavior to be emulated correctly on our
   HP "SLS" (Single Logical Screen) configurations.  What I added
   was a way to tell FVWM where the divisions between the monitors
   are for cases where there is no Xinerama extension to query.
   It is like a fvwm2rc-configurable version of XINERAMA_EMULATION,
   (but I don't draw the white lines, and all monitors must be the
   same resolution.)  I also moved the generation of the FScreen
   configuration command for modules into FScreen.c so it is near
   the point where it is also decoded.
 
   I should probably test the patch some more, but I'd like to
   get your thoughts on the way I did it to see if you agree, or
   would rather have it implemented another way.  The man page
   has been updated to show how two more (optional) parameters
   can be added to the Xinerama line to specify how many equal-sized
   monitors wide&high the screen which FVWM sees is composed of.
   You can test it on a regular screen.
 
   This patch shouldn't break anything since it just adds optional
   parameters to the Xinerama command.  Please let me know what you
   think of it, and thanks for your time!

Be seeing you,

- Sidik

P.S.: Dominik, the previous file I sent you was gzipped.  Maybe
  something remove the .gz?  The final size is 7574 bytes, and
  I put a copy at:

http://software.cfht.hawaii.edu/fvwm2-xinerama-sls.patch

  and here it is in plain text, since the Welcome message says
  patches are appropriate...

diff -ru fvwm-snap-20010831/fvwm/fvwm2.1 fvwm-snap-20010831-sls/fvwm/fvwm2.1
--- fvwm-snap-20010831/fvwm/fvwm2.1	Tue Aug 21 01:30:03 2001
+++ fvwm-snap-20010831-sls/fvwm/fvwm2.1	Mon Sep  3 15:51:13 2001
@@ -6520,7 +6520,7 @@
 then the scroll amount is measured in pixels.
 
 .TP
-.BI "Xinerama [ " bool " | " primary-screen " ]"
+.BI "Xinerama [ " bool " | " primary-screen " [ " wide " " high  " ] ]"
 Enables Xinerama support if the boolean argument is true and
 disables it if the argument is false.  If instead an integer
 argument is given as
@@ -6531,6 +6531,23 @@
 as the primary screen's number.  Any negative value disables the
 primary screen feature.  Calling this command without arguments
 turns on Xinerama support with the primary screen 0 if it was disabled before and turns it off if it was enabled.
+
+For multi-screen implementations other than Xinerama, such as
+Single Logical Screen, it is possible to simulate a Xinerama
+configuration if the total screen seen by FVWM is made up of
+equal sized monitors in a rectangular grid.  Add two more arguments,
+.IR wide ,
+which must be an integer value dividing evenly into the
+total desktop width, and
+.IR high ,
+which must be an integer value dividing evenly into the
+total desktop height.  For an example with two monitors side-by-side
+which appear as one screen through the X-Server, use:
+.EX
+Xinerama 1 2 1
+.EE
+to simulate Xinerama with screen 1 as the primary.  These extra
+parameters should not be added if the X-Server supports Xinerama.
 
 .SS COMMANDS FOR USER FUNCTIONS AND SHELL COMMANDS
 
diff -ru fvwm-snap-20010831/fvwm/modconf.c fvwm-snap-20010831-sls/fvwm/modconf.c
--- fvwm-snap-20010831/fvwm/modconf.c	Mon Aug 27 01:30:02 2001
+++ fvwm-snap-20010831-sls/fvwm/modconf.c	Mon Sep  3 12:41:08 2001
@@ -220,13 +220,7 @@
 
 static void send_xinerama_state(int modnum)
 {
-  char msg[100];
-  int scr;
-
-  scr = (FScreenIsEnabled()) ? FScreenGetPrimaryScreen() : -1;
-  sprintf(msg, "%s %d", XINERAMA_CONFIG_STRING, scr);
-  SendName(modnum, M_CONFIG_INFO, 0, 0, 0, msg);
-
+  SendName(modnum, M_CONFIG_INFO, 0, 0, 0, FScreenGetConfiguration());
   return;
 }
 
diff -ru fvwm-snap-20010831/fvwm/module_interface.c fvwm-snap-20010831-sls/fvwm/module_interface.c
--- fvwm-snap-20010831/fvwm/module_interface.c	Mon Aug 27 01:30:02 2001
+++ fvwm-snap-20010831-sls/fvwm/module_interface.c	Mon Sep  3 12:41:55 2001
@@ -1225,13 +1225,7 @@
  **********************************************************************/
 void broadcast_xinerama_state(void)
 {
-  char buf[100];
-  int scr;
-
-  scr = (FScreenIsEnabled()) ? FScreenGetPrimaryScreen() : -1;
-  sprintf(buf, "%s %d", XINERAMA_CONFIG_STRING, scr);
-  BroadcastConfigInfoString(buf);
-
+  BroadcastConfigInfoString(FScreenGetConfiguration());
   return;
 }
 
diff -ru fvwm-snap-20010831/fvwm/virtual.c fvwm-snap-20010831-sls/fvwm/virtual.c
--- fvwm-snap-20010831/fvwm/virtual.c	Mon Aug 27 01:30:03 2001
+++ fvwm-snap-20010831-sls/fvwm/virtual.c	Mon Sep  3 15:19:53 2001
@@ -337,15 +337,17 @@
 
 void CMD_Xinerama(F_CMD_ARGS)
 {
-  int val;
+  int n, val[3];
   int toggle;
 
   Scr.flags.do_need_window_update = True;
   Scr.flags.has_xinerama_state_changed = True;
-  if (GetIntegerArguments(action, NULL, &val, 1) == 1)
+  if ((n = GetIntegerArguments(action, NULL, val, 3)) >= 1)
   {
+    if (n >= 3)
+      FScreenSingleLogicalScreen(val[1], val[2]);
+    FScreenSetPrimaryScreen(val[0]);
     FScreenEnable();
-    FScreenSetPrimaryScreen(val);
     return;
   }
   toggle = ParseToggleArgument(action, NULL, -1, 0);
diff -ru fvwm-snap-20010831/libs/FScreen.c fvwm-snap-20010831-sls/libs/FScreen.c
--- fvwm-snap-20010831/libs/FScreen.c	Sun Aug 26 04:47:45 2001
+++ fvwm-snap-20010831-sls/libs/FScreen.c	Mon Sep  3 14:20:48 2001
@@ -114,6 +114,8 @@
 static int                 num_screens        = 0;
 /* # of Xinerama screens, *not* counting the [0]global */
 static int                 total_screens     = 0;
+static int                 total_sls_wide    = 0;
+static int                 total_sls_high    = 0;
 static int                 first_to_check    = 0;
 static int                 last_to_check     = 0;
 static int                 primary_scr       = DEFAULT_PRIMARY_SCREEN + 1;
@@ -284,6 +286,52 @@
 {
   is_xinerama_disabled = 0;
   num_screens = total_screens;
+
+  if (total_sls_wide * total_sls_high > 0)
+  {
+    int row, col, sn;
+    int w;
+    int h;
+    int ws;
+    int hs;
+    unsigned long scr;
+    Window root;
+    XSetWindowAttributes attributes;
+    static XineramaScreenInfo *new_screens;
+
+    num_screens = total_screens = total_sls_wide * total_sls_high;
+
+    scr = DefaultScreen(disp);
+    root = RootWindow(disp, scr);
+
+    new_screens = (XineramaScreenInfo *)
+      safemalloc(sizeof(XineramaScreenInfo) * (1 + total_screens));
+    /* calculate the faked sub screen dimensions */
+
+    new_screens[0] = screens[0];
+    free(screens);
+    screens = new_screens;
+
+    w = DisplayWidth(disp, scr);
+    ws = w / total_sls_wide;
+    h = DisplayHeight(disp, scr);
+    hs = h / total_sls_high;
+
+    sn = 1;
+    for (row = 0; row < total_sls_high; row++)
+    {
+      for (col = 0; col < total_sls_wide; col++)
+      {
+	screens[sn].screen_number = sn - 1;
+	screens[sn].x_org         = col * ws;
+	screens[sn].y_org         = row * hs;
+	screens[sn].width         = ws;
+	screens[sn].height        = hs;
+	sn++;
+      }
+    }
+  }
+
   /* Fill in the screen range */
   FScreenSetState(1);
 #ifdef USE_XINERAMA_EMULATION
@@ -292,6 +340,14 @@
 #endif
 }
 
+void FScreenSingleLogicalScreen(int wide, int high)
+{
+  is_xinerama_disabled = 0;
+  num_screens = wide * high;
+  total_sls_wide = wide;
+  total_sls_high = high;
+}
+
 #if 0
 void FScreenDisableRandR(void)
 {
@@ -327,24 +383,36 @@
  * config string sent by fvwm. */
 void FScreenConfigureModule(char *args)
 {
-  int screen = 0;
+  int val[3];
+  int n;
 
-  GetIntegerArguments(args, NULL, &screen, 1);
-  if (screen < 0)
-  {
-    screen = -1;
-  }
-  FScreenSetPrimaryScreen(screen - 1);
-  if (screen == -1)
+  n = GetIntegerArguments(args, NULL, val, 3);
+  if (n < 1)
   {
     FScreenDisable();
   }
-  else
-  {
-    FScreenEnable();
-  }
+  FScreenSetPrimaryScreen(val[0] - 1);
+  if (n >= 3)
+    FScreenSingleLogicalScreen(val[1], val[2]);
+  FScreenEnable();
 
   return;
+}
+
+/* Here's the function used by FVWM to generate the string which
+ * FScreenConfigureModule expects to receive back as its argument.
+ */
+const char* FScreenGetConfiguration(void)
+{
+  static char msg[100];
+  int scr;
+
+  scr = (FScreenIsEnabled()) ? FScreenGetPrimaryScreen() : -1;
+  sprintf(msg, "%s %d", XINERAMA_CONFIG_STRING, scr);
+  if (total_sls_wide * total_sls_high > 0)
+    sprintf(msg + strlen(msg), " %d %d", total_sls_wide, total_sls_high);
+
+  return msg;
 }
 
 /* Sets the default screen for ...ParseGeometry if no screen spec is given.
diff -ru fvwm-snap-20010831/libs/FScreen.h fvwm-snap-20010831-sls/libs/FScreen.h
--- fvwm-snap-20010831/libs/FScreen.h	Sun Aug 26 04:47:45 2001
+++ fvwm-snap-20010831-sls/libs/FScreen.h	Mon Sep  3 13:04:29 2001
@@ -33,9 +33,11 @@
 void FScreenInit(Display *dpy);
 void FScreenDisable(void);
 void FScreenEnable(void);
+void FScreenSingleLogicalScreen(int wide, int high);
 /* Intended to be called by modules.  Simply pass in the parameter from the
  * config string sent by fvwm. */
 void FScreenConfigureModule(char *args);
+const char* FScreenGetConfiguration(void); /* For use by FVWM */
 void FScreenDisableRandR(void);
 
 int FScreenGetPrimaryScreen(void);
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]

---

From: Dominik Vogt <[email-masked]>
Date: Wed, 5 Sep 2001 18:47:30 +0200

>    think of it, and thanks for your time!

I have applied the patch and rewrote parts of it.  Most Notably I
split the Xinerama command into four: Xinerama,
XineramaPrimaryScreen, XineramaSls and XineramaSlsSize.  Also, it
is possible to switch between SLS and normal Xinerama so you don't
have to restart fvwm to get back to using Xinerama.  For more
details, have a look at the man page.  It would be nice if you
could test this since the changes I made were huge.

BTW, please include ChangeLog and possibly NEWS and AUTHORS
entries with any patches, it's hard to identify the functions that
were changes from a patch file.

Bye

Dominik ^_^  ^_^

 --
Dominik Vogt, [email-masked]
Reply-To: [email-masked]
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]

---

From: Dominik Vogt <[email-masked]>
Date: Wed, 5 Sep 2001 18:47:30 +0200

Bye

Dominik ^_^  ^_^