Subject: Re: Solaris Xinerama support

From: Chris Ross <[email-masked]>
Date: Mon, 16 Aug 2004 18:07:27 -0400

Dan Espen wrote:
> 
> Didn't you say the Sol 9/10 header would work on Sol 8.
> Why not make the header required.  If someone wants Xinerama
> on Sol 8, make them supply the header.

   It does, but it seems like having the xinerama support enabled
with no user effort for Solaris 8 users would be worth having.
You don't need to be an admin, or even very smart, to build
a window manager.  Making sure you can put an extension somewhere
and have auto-conf'd programs find them requires more of the
user.

   It only requires putting 4 lines in FScreen.c.  One #def,
and three prototypes.  Actually, we're only using two of the
functions, so we could take out the other prototype.

           - Chris
--
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: Dan Espen <[email-masked]>
Date: Mon, 16 Aug 2004 19:01:34 -0400

> functions, so we could take out the other prototype.

If the #define'd stuff is only used on Solaris, when the header
isn't there, and the library support is there,  I'd say that was
OK.

-- 
Dan Espen                           E-mail: [email-masked]

---

From: Chris Ross <[email-masked]>
Date: Fri, 20 Aug 2004 09:32:35 -0400

> isn't there, and the library support is there,  I'd say that was

   Yup.  That's how it's done.  Only if the libXinerama stuff
isn't found will it look for Solaris' calls, and only if those
are found will it look for the header.  If the header is found,
the few lines (to replace the header) I added don't get used.

   The following should be the full diff against CVS HEAD for
this patch.  Thanks for all your help!

                              - Chris

Index: configure.in
===================================================================
RCS file: /home/cvs/fvwm/fvwm/configure.in,v
retrieving revision 1.294
diff -u -u -r1.294 configure.in
--- configure.in	23 May 2004 16:20:23 -0000	1.294
+++ configure.in	20 Aug 2004 13:26:58 -0000
@@ -298,8 +298,18 @@
   $UNSET ac_cv_lib_Xinerama_XineramaIsActive
   AC_CHECK_LIB(Xinerama, XineramaIsActive,
     with_xinerama=yes; Xinerama_LIBS=-lXinerama; AC_DEFINE(HAVE_XINERAMA),
+    AC_CHECK_LIB(Xext, XineramaGetState,
+      [ AC_DEFINE(HAVE_XINERAMA) AC_DEFINE(HAVE_SOLARIS_XINERAMA)
+      with_xinerama=yes; Xinerama_LIBS=-lXext
+      my_CPPFLAGS="$CPPFLAGS"; CPPFLAGS="$X_CPPFLAGS $CPPFLAGS"
+      my_hdr="X11/extensions/xinerama.h"
+      AC_CHECK_HEADER($my_hdr, AC_DEFINE(HAVE_SOLARIS_XINERAMA_H)
+	problem_xinerama=" (Using Solaris Xinerama calls)",
+	problem_xinerama=" (Failed to find Sun's $my_hdr)")
+      CPPFLAGS="$my_CPPFLAGS"],
     with_xinerama=no; Xinerama_LIBS=
     problem_xinerama=": Failed to detect libXinerama",
+    [$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS]),
     [$X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS])
 fi
 AC_SUBST(Xinerama_LIBS)
Index: acconfig.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/acconfig.h,v
retrieving revision 1.72
diff -u -u -r1.72 acconfig.h
--- acconfig.h	8 Jul 2004 10:08:09 -0000	1.72
+++ acconfig.h	20 Aug 2004 13:26:58 -0000
@@ -32,6 +32,14 @@
 /* Define if Xinerama library is used. */
 #undef HAVE_XINERAMA
 
+/* Define if Solaris' Xinerama calls are being used. */
+/* (Solaris 7 11/99 and later) */
+#undef HAVE_SOLARIS_XINERAMA
+
+/* Define if Solaris' X11/extensions/xinerama.h header is provided. */
+/* (Solaris 9 and later) */
+#undef HAVE_SOLARIS_XINERAMA_H
+
 /* Define if Xrender library is used. */
 #undef HAVE_XRENDER
 
Index: fvwm/fvwm.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.c,v
retrieving revision 1.368
diff -u -u -r1.368 fvwm.c
--- fvwm/fvwm.c	15 Jul 2004 13:12:28 -0000	1.368
+++ fvwm/fvwm.c	20 Aug 2004 13:26:59 -0000
@@ -1312,6 +1312,9 @@
 	strcat(support_str, " Bidi text,");
 #endif
 #ifdef HAVE_XINERAMA
+# ifdef HAVE_SOLARIS_XINERAMA
+	strcat(support_str, " [Solaris' odd-ball]");
+# endif
 	strcat(support_str, " Xinerama,");
 #endif
 #ifdef HAVE_XRENDER
Index: libs/FScreen.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/libs/FScreen.c,v
retrieving revision 1.22
diff -u -u -r1.22 FScreen.c
--- libs/FScreen.c	17 Mar 2004 14:42:54 -0000	1.22
+++ libs/FScreen.c	20 Aug 2004 13:26:59 -0000
@@ -69,8 +69,62 @@
 #include "PictureBase.h"
 
 #ifdef HAVE_XINERAMA
-#define FScreenHaveXinerama 1
-#include <X11/extensions/Xinerama.h>
+# define FScreenHaveXinerama 1
+# ifdef HAVE_SOLARIS_XINERAMA
+#  ifdef HAVE_SOLARIS_XINERAMA_H
+#   include <X11/extensions/xinerama.h>
+#  else
+/* Copied from Solaris 9's X11/extensions/xinerama.h */
+#define	MAXFRAMEBUFFERS		16
+Bool XineramaGetState(Display*, int);
+Status XineramaGetInfo(Display*, int, XRectangle*, unsigned char*, int*);
+Status XineramaGetCenterHint(Display*, int, int*, int*);
+#  endif /* HAVE_SOLARIS_XINERAMA_H */
+typedef struct
+{
+	int   screen_number;
+	short x_org;
+	short y_org;
+	short width;
+	short height;
+} XineramaScreenInfo;
+#  define XineramaIsActive(d)		XineramaGetState((d),0)
+#  define XineramaQueryScreens(d,b)	solaris_XineramaQueryScreens((d),(b))
+#  define XineramaQueryExtension(d,b,c)	1	/* Lie, for now */
+static XineramaScreenInfo *
+solaris_XineramaQueryScreens(Display *d, int *xin_nscreens)
+{
+	XineramaScreenInfo *screens = NULL;
+	XRectangle monitors[MAXFRAMEBUFFERS];
+	unsigned char hints[16];
+
+	int result = XineramaGetInfo(d, DefaultScreen(d), monitors, hints,
+				     xin_nscreens);
+	if (result)
+	{
+		int m;
+
+		screens = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * (*xin_nscreens));
+		for (m = 0; m < *xin_nscreens; ++m)
+		{
+			screens[m].screen_number = m;
+			screens[m].x_org = monitors[m].x;
+			screens[m].y_org = monitors[m].y;
+			screens[m].width = monitors[m].width;
+			screens[m].height = monitors[m].height;
+		}
+	}
+	else
+	{
+	    fprintf(stderr, "Error getting Xinerama information\n");
+	    *xin_nscreens = 0;
+	}
+
+	return (screens);
+}
+# else	/* Must be XFree86 Xinerama */
+#  include <X11/extensions/Xinerama.h>
+# endif
 #else
 #define FScreenHaveXinerama 0
 typedef struct

---

From: Dominik Vogt <[email-masked]>
Date: Thu, 26 Aug 2004 11:51:08 +0200

> Index: configure.in

Note that this nesting of AC_CHECK_LIB calls did not work with my
autoconf/automake versions.  I have split it in two separate
calls.

Ciao

Dominik ^_^  ^_^

 --
Dominik Vogt, [email-masked]
Reply-To: [email-masked]

---

From: Dan Espen <[email-masked]>
Date: Thu, 26 Aug 2004 06:48:22 -0400

> autoconf/automake versions.  I have split it in two separate

Darn.  And I tested this on Linux and Solaris.

I woke up in the middle of the night and it dawned on me that I never
updated NEWS.  I figured no one would notice and I could
take care of it when I got up.

---

From: Thomas Adam <[email-masked]>
Date: Thu, 26 Aug 2004 11:51:01 +0100

> take care of it when I got up.

Heh, now *that*'s what I call being passionate about one's work. :)

-- Thomas Adam

-- 
Quis custodiet ipsos custodes?

---

From: Dominik Vogt <[email-masked]>
Date: Thu, 26 Aug 2004 13:43:50 +0200

> Darn.  And I tested this on Linux and Solaris.

They changed something with quoting in autoconf/automake a while
ago.  Unfortunately you have to test with the old and new auto*
versions to make sure some things in configure work fine.

> take care of it when I got up.

If all else fails, I will notice missing NEWS entries sooner or
later ;-)

Ciao

Dominik ^_^  ^_^

---

From: Chris Ross <[email-masked]>
Date: Thu, 26 Aug 2004 11:53:19 -0400

Thanks Dominik.

> versions to make sure some things in configure work fine.

   Odd.  It worked for me, too, using the same version of
autoconf that'd previously generated the configure.  Guess
that must've changed on your system and not mine.  Thanks
for fixing it!

   There were a couple issues with your changes to libs/FScreen.c.
I don't know that I "agree" with the "all code should be
compiled" opinion, but that's certainly your call to make.
And the #ifdef'd code is now more sensible than it was, and
than I'd made it.  Thanks.

   But, there was one typo (capitalization error), and one
error in the #def's.  Solaris' xinerama.h does *not* define
XineramaScreenInfo, since Solaris' xinerama system API is
*completely* different.  I just moved the relevant #def out
one level.  A patch to libs/FScreen.c is attached.  It will
now link both with and without the Solaris xinerama.h
header.

   Thanks again!

                          - Chris
Index: libs/FScreen.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/libs/FScreen.c,v
retrieving revision 1.24
diff -u -r1.24 FScreen.c
--- libs/FScreen.c	26 Aug 2004 09:40:42 -0000	1.24
+++ libs/FScreen.c	26 Aug 2004 15:52:53 -0000
@@ -73,10 +73,10 @@
 # define FScreenHaveXinerama 1
 # ifdef HAVE_SOLARIS_XINERAMA
 #  define FScreenHaveSolarisXinerama 1
+#  define FSCREEN_NEED_SCREENINFO
 #  ifdef HAVE_SOLARIS_XINERAMA_H
 #   include <X11/extensions/xinerama.h>
 #  else
-#   define FSCREEN_NEED_SCREENINFO
 #   define FSCREEN_NEED_SOLARIS_PROTOTYPES
 #  endif
 # else
@@ -114,7 +114,7 @@
 #if FScreenHaveXinerama
 # if FScreenHaveSolarisXinerama
 #  define XineramaQueryExtension(d,b,c) 1 /* Lie, for now */
-#  define XineramaIsActive(d) Xineramagetstate((d),0)
+#  define XineramaIsActive(d) XineramaGetState((d),0)
 # endif
 #else
 # define XineramaQueryExtension(da, b, c) 0