Bug 318331 - Default build does not support Xinerama - detect support at runtimep=Sylvain Pasche <sylvain.pasche@gmail.com>r+sr=roc
authorasqueella@gmail.com
Wed, 02 May 2007 13:07:32 -0700
changeset 1020 2ffdae2ac2c185480a7473b933e60eca35981c86
parent 1019 94c9e29842d1f2a11f9a9a274aab27afd61673b0
child 1021 85611e1f4717b960ef2cae2145a0230e4fad69cf
push idunknown
push userunknown
push dateunknown
bugs318331
milestone1.9a5pre
Bug 318331 - Default build does not support Xinerama - detect support at runtimep=Sylvain Pasche <sylvain.pasche@gmail.com>r+sr=roc
config/autoconf.mk.in
config/static-config.mk
config/system-headers
configure.in
toolkit/library/Makefile.in
widget/src/gtk2/Makefile.in
widget/src/gtk2/nsScreenGtk.cpp
widget/src/gtk2/nsScreenGtk.h
widget/src/gtk2/nsScreenManagerGtk.cpp
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -486,19 +486,16 @@ MOZ_XFT_LIBS		= @MOZ_XFT_LIBS@
 MOZ_ENABLE_COREXFONTS	= @MOZ_ENABLE_COREXFONTS@
 
 MOZ_ENABLE_PANGO        = @MOZ_ENABLE_PANGO@
 MOZ_PANGO_CFLAGS        = @MOZ_PANGO_CFLAGS@
 MOZ_PANGO_LIBS          = @MOZ_PANGO_LIBS@
 
 MOZ_EXTRA_X11CONVERTERS	= @MOZ_EXTRA_X11CONVERTERS@
 
-MOZ_ENABLE_XINERAMA	= @MOZ_ENABLE_XINERAMA@
-MOZ_XINERAMA_LIBS	= @MOZ_XINERAMA_LIBS@
-
 MOZ_XIE_LIBS		= @MOZ_XIE_LIBS@
 XT_LIBS			= @XT_LIBS@
 
 GLIB_CFLAGS	= @GLIB_CFLAGS@
 GLIB_LIBS	= @GLIB_LIBS@
 GLIB_GMODULE_LIBS	= @GLIB_GMODULE_LIBS@
 LIBIDL_CFLAGS = @LIBIDL_CFLAGS@
 LIBIDL_LIBS = @LIBIDL_LIBS@
--- a/config/static-config.mk
+++ b/config/static-config.mk
@@ -88,20 +88,16 @@ ifdef MOZ_SVG
 STATIC_EXTRA_LIBS	+= $(MOZ_CAIRO_LIBS)
 else # not MOZ_SVG
 ifdef MOZ_ENABLE_CANVAS # not SVG, but yes on canvas
 STATIC_EXTRA_LIBS	+= $(MOZ_CAIRO_LIBS)
 endif
 endif
 endif
 
-ifdef MOZ_ENABLE_XINERAMA
-STATIC_EXTRA_LIBS	+= $(MOZ_XINERAMA_LIBS)
-endif
-
 ifneq  (,$(MOZ_ENABLE_GTK2))
 STATIC_EXTRA_LIBS	+= $(XLDFLAGS) $(XT_LIBS)
 endif
 
 ifdef MOZ_ENABLE_XPRINT
 STATIC_EXTRA_LIBS	+= $(MOZ_XPRINT_LDFLAGS)
 endif
 
--- a/config/system-headers
+++ b/config/system-headers
@@ -881,17 +881,16 @@ wx/listctrl.h
 wx/log.h
 wx/toolbar.h
 wx/wx.h
 wx/xrc/xmlres.h
 X11/cursorfont.h
 X11/extensions/Print.h
 X11/extensions/shape.h
 X11/extensions/XIElib.h
-X11/extensions/Xinerama.h
 X11/extensions/XShm.h
 X11/extensions/Xrender.h
 X11/Intrinsic.h
 X11/keysymdef.h
 X11/keysym.h
 X11/Shell.h
 X11/StringDefs.h
 X11/Xatom.h
--- a/configure.in
+++ b/configure.in
@@ -2879,23 +2879,16 @@ else
     # crashes in plugins linked against Motif - Bug #98892
     case "${target_os}" in
     aix*)
         XT_LIBS="-lXm $XT_LIBS"
         ;;
     esac
 
     dnl ========================================================
-    dnl = Check for Xinerama
-    dnl ========================================================
-    AC_CHECK_LIB(Xinerama, XineramaIsActive, [MOZ_XINERAMA_LIBS="-lXinerama"],,
-        $XLIBS $XEXT_LIBS)
-    AC_CHECK_HEADER(X11/extensions/Xinerama.h)
-
-    dnl ========================================================
     dnl = Check for XShm
     dnl ========================================================
     AC_CHECK_LIB(Xext, XShmCreateImage, _HAVE_XSHM_XEXT=1,,
         $XLIBS $XEXT_LIBS)
     AC_CHECK_HEADER(X11/extensions/XShm.h)
     if test "$ac_cv_header_X11_extensions_XShm_h" = "yes" &&
         test -n "$_HAVE_XSHM_XEXT"; then
         AC_DEFINE(HAVE_XSHM)
@@ -5243,40 +5236,16 @@ dnl ====================================
 MOZ_ARG_DISABLE_BOOL(oji,
 [  --disable-oji           Disable Open JVM Integration support],
     MOZ_OJI=,
     MOZ_OJI=1)
 if test -n "$MOZ_OJI"; then
     AC_DEFINE(OJI)
 fi
 
-dnl ========================================================
-dnl = Xinerama support. The autodetection is done above in the Xlib
-dnl = detection routines.
-dnl ========================================================
-
-if test "$MOZ_WIDGET_TOOLKIT" = "gtk2"; then
-    MOZ_ENABLE_XINERAMA=1
-fi
-
-MOZ_ARG_DISABLE_BOOL(xinerama,
-[  --disable-xinerama      Disable Xinerama support],
-    MOZ_ENABLE_XINERAMA=,
-    MOZ_ENABLE_XINERAMA=1 )
-
-if test -n "$MOZ_ENABLE_XINERAMA"; then
-    if test -z "$MOZ_XINERAMA_LIBS" || \
-        test "$ac_cv_header_X11_extensions_Xinerama_h" = "no"; then
-        AC_MSG_ERROR([Cannot find Xinerama library. To build without Xinerama support, rebuild with --disable-xinerama])
-    fi
-    # Xinerama depends on libXext which is not automatically included on older distribs
-    MOZ_XINERAMA_LIBS="$MOZ_XINERAMA_LIBS $XEXT_LIBS"
-    AC_DEFINE(MOZ_ENABLE_XINERAMA)
-fi
-
 dnl bi-directional support always on
 IBMBIDI=1
 AC_DEFINE(IBMBIDI)
 
 dnl ========================================================
 dnl complex text support off by default
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(ctl,
@@ -7637,18 +7606,16 @@ AC_SUBST(MOZ_PROFILELOCKING)
 AC_SUBST(MOZ_IPCD)
 
 AC_SUBST(HAVE_XIE)
 AC_SUBST(MOZ_XIE_LIBS)
 AC_SUBST(MOZ_XPRINT_CFLAGS)
 AC_SUBST(MOZ_XPRINT_LDFLAGS)
 AC_SUBST(MOZ_ENABLE_XPRINT)
 AC_SUBST(MOZ_ENABLE_POSTSCRIPT)
-AC_SUBST(MOZ_XINERAMA_LIBS)
-AC_SUBST(MOZ_ENABLE_XINERAMA)
 
 AC_SUBST(XPCOM_USE_LEA)
 AC_SUBST(BUILD_STATIC_LIBS)
 AC_SUBST(MOZ_ENABLE_LIBXUL)
 AC_SUBST(ENABLE_TESTS)
 AC_SUBST(IBMBIDI)
 AC_SUBST(SUNCTL)
 AC_SUBST(MOZ_UNIVERSALCHARDET)
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -186,20 +186,16 @@ EXTRA_DSO_LDOPTS += \
 	-framework Cocoa \
 	-framework QuickTime \
 	-framework IOKit \
 	-lcrypto \
 	$(TK_LIBS) \
 	$(NULL)
 endif
 
-ifdef MOZ_ENABLE_XINERAMA
-EXTRA_DSO_LDOPTS += $(MOZ_XINERAMA_LIBS)
-endif
-
 ifneq (,$(filter gtk2 qt,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) $(MOZ_XFT_LIBS) $(MOZ_GTK2_LIBS) $(XT_LIBS)
 endif
 
 ifdef MOZ_ENABLE_XFT
 EXTRA_DSO_LDOPTS += $(FT2_LIBS)
 endif
 
--- a/widget/src/gtk2/Makefile.in
+++ b/widget/src/gtk2/Makefile.in
@@ -126,19 +126,16 @@ SHARED_LIBRARY_LIBS = ../xpwidgets/libxp
 EXTRA_DSO_LDOPTS += \
 		$(MOZ_COMPONENT_LIBS) \
 		-lgkgfx \
 		-lgtkxtbin \
                 $(MOZ_STARTUP_NOTIFICATION_LIBS) \
 		$(XLDFLAGS) \
 		$(XLIBS) \
 		$(MOZ_GTK2_LIBS)
-ifdef MOZ_ENABLE_XINERAMA
-EXTRA_DSO_LDOPTS += $(MOZ_XINERAMA_LIBS)
-endif
 
 ifeq ($(MOZ_ENABLE_CAIRO_GFX),1)
 EXTRA_DSO_LDOPTS += -lthebes
 endif
 
 EXPORTS		= \
 		nsIGdkPixbufImage.h \
                 nsGTKToolkit.h \
--- a/widget/src/gtk2/nsScreenGtk.cpp
+++ b/widget/src/gtk2/nsScreenGtk.cpp
@@ -225,20 +225,18 @@ nsScreenGtk :: Init (PRBool aReInit)
       }
 
       mAvailRect.IntersectRect(mAvailRect, workarea);
     }
   }
   g_free (workareas);
 }
 
-#ifdef MOZ_ENABLE_XINERAMA
 void
 nsScreenGtk :: Init (XineramaScreenInfo *aScreenInfo)
 {
   nsRect xineRect(aScreenInfo->x_org, aScreenInfo->y_org,
                   aScreenInfo->width, aScreenInfo->height);
 
   mScreenNum = aScreenInfo->screen_number;
 
   mAvailRect = mRect = xineRect;
 }
-#endif // MOZ_ENABLE_XINERAMA
--- a/widget/src/gtk2/nsScreenGtk.h
+++ b/widget/src/gtk2/nsScreenGtk.h
@@ -38,36 +38,39 @@
 #ifndef nsScreenGtk_h___
 #define nsScreenGtk_h___
 
 #include "nsIScreen.h"
 #include "nsRect.h"
 #include "gdk/gdk.h"
 #include <X11/Xlib.h>
 
-#ifdef MOZ_ENABLE_XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif // MOZ_ENABLE_XINERAMA
+// from Xinerama.h
+typedef struct {
+   int   screen_number;
+   short x_org;
+   short y_org;
+   short width;
+   short height;
+} XineramaScreenInfo;
 
 //------------------------------------------------------------------------
 
 class nsScreenGtk : public nsIScreen
 {
 public:
   nsScreenGtk();
   ~nsScreenGtk();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISCREEN
 
   void Init(PRBool aReInit = PR_FALSE);
   void ReInit() { Init(PR_TRUE); }
-#ifdef MOZ_ENABLE_XINERAMA
   void Init(XineramaScreenInfo *aScreenInfo);
-#endif
 
   Atom NetWorkareaAtom() { return mNetWorkareaAtom; }
 
 private:
   GdkWindow *mRootWindow;
   PRUint32 mScreenNum;
   Atom mNetWorkareaAtom;
   nsRect mRect; // in pixels, not twips
--- a/widget/src/gtk2/nsScreenManagerGtk.cpp
+++ b/widget/src/gtk2/nsScreenManagerGtk.cpp
@@ -15,16 +15,17 @@
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 2000
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *   Sylvain Pasche <sylvain.pasche@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -35,26 +36,23 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsScreenManagerGtk.h"
 #include "nsScreenGtk.h"
 #include "nsIComponentManager.h"
 #include "nsRect.h"
 #include "nsAutoPtr.h"
+#include "prlink.h"
 
 #include <gdk/gdkx.h>
 
-#ifdef MOZ_ENABLE_XINERAMA
-// this header rocks!
-extern "C"
-{
-#include <X11/extensions/Xinerama.h>
-}
-#endif /* MOZ_ENABLE_XINERAMA */
+// prototypes from Xinerama.h
+typedef Bool (*_XnrmIsActive_fn)(Display *dpy);
+typedef XineramaScreenInfo* (*_XnrmQueryScreens_fn)(Display *dpy, int *number);
 
 nsScreenManagerGtk :: nsScreenManagerGtk ( )
 {
   // nothing else to do. I guess we could cache a bunch of information
   // here, but we want to ask the device at runtime in case anything
   // has changed.
   mNumScreens = 0;
 }
@@ -74,47 +72,49 @@ NS_IMPL_ISUPPORTS1(nsScreenManagerGtk, n
 nsresult
 nsScreenManagerGtk :: EnsureInit(void)
 {
   if (!mCachedScreenArray) {
     mCachedScreenArray = do_CreateInstance("@mozilla.org/supports-array;1");
     if (!mCachedScreenArray) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
-#ifdef MOZ_ENABLE_XINERAMA
-    // get the number of screens via xinerama
-    XineramaScreenInfo *screenInfo;
-    if (XineramaIsActive(GDK_DISPLAY())) {
-      screenInfo = XineramaQueryScreens(GDK_DISPLAY(), &mNumScreens);
+    XineramaScreenInfo *screenInfo = NULL;
+
+    // We are leaking xineramalib, but there is no other way to do this.
+    PRLibrary* xineramalib = PR_LoadLibrary("libXinerama.so.1");
+    if (xineramalib) {
+      _XnrmIsActive_fn _XnrmIsActive = (_XnrmIsActive_fn)
+          PR_FindFunctionSymbol(xineramalib, "XineramaIsActive");
+
+      _XnrmQueryScreens_fn _XnrmQueryScreens = (_XnrmQueryScreens_fn)
+          PR_FindFunctionSymbol(xineramalib, "XineramaQueryScreens");
+          
+      // get the number of screens via xinerama
+      if (_XnrmIsActive && _XnrmQueryScreens &&
+          _XnrmIsActive(GDK_DISPLAY())) {
+        screenInfo = _XnrmQueryScreens(GDK_DISPLAY(), &mNumScreens);
+      }
     }
-    else {
-      screenInfo = NULL;
-      mNumScreens = 1;
-    }
-#else
-    mNumScreens = 1;
-#endif
-    // there will be < 2 screens if we are either not building with
-    // xinerama support or xinerama isn't running on the current
-    // display.
-    if (mNumScreens < 2) {
+    // screenInfo == NULL if either Xinerama couldn't be loaded or
+    // isn't running on the current display
+    if (!screenInfo) {
       mNumScreens = 1;
       nsRefPtr<nsScreenGtk> screen = new nsScreenGtk();
       if (!screen)
         return NS_ERROR_OUT_OF_MEMORY;
 
       screen->Init();
 
       nsISupports *supportsScreen = screen;
       mCachedScreenArray->AppendElement(supportsScreen);
     }
     // If Xinerama is enabled and there's more than one screen, fill
     // in the info for all of the screens.  If that's not the case
     // then nsScreenGTK() defaults to the screen width + height
-#ifdef MOZ_ENABLE_XINERAMA
     else {
 #ifdef DEBUG
       printf("Xinerama superpowers activated for %d screens!\n", mNumScreens);
 #endif
       int i;
       for (i=0; i < mNumScreens; i++) {
         nsRefPtr<nsScreenGtk> screen = new nsScreenGtk();
         if (!screen) {
@@ -127,20 +127,19 @@ nsScreenManagerGtk :: EnsureInit(void)
         nsISupports *screenSupports = screen;
         mCachedScreenArray->AppendElement(screenSupports);
       }
     }
 
     if (screenInfo) {
       XFree(screenInfo);
     }
-#endif /* MOZ_ENABLE_XINERAMA */
   }
 
-  return NS_OK;;
+  return NS_OK;
 }
 
 
 //
 // ScreenForRect 
 //
 // Returns the screen that contains the rectangle. If the rect overlaps
 // multiple screens, it picks the screen with the greatest area of intersection.