rpms/xscreensaver/F-9 xscreensaver-5.06-bz457685-nvidia-jwz.patch, NONE, 1.1 xscreensaver.spec, 1.71, 1.72

Mamoru Tasaka (mtasaka) fedora-extras-commits at redhat.com
Sat Aug 9 03:13:11 UTC 2008


Author: mtasaka

Update of /cvs/extras/rpms/xscreensaver/F-9
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv20197/F-9

Modified Files:
	xscreensaver.spec 
Added Files:
	xscreensaver-5.06-bz457685-nvidia-jwz.patch 
Log Message:
* Sat Aug  9 2008 Mamoru Tasaka <mtasaka at ioa.s.u-tokyo.ac.jp> - 1:5.06-3
- Fallback to Xinerama extension when Xrandr reports less screens
  than Xinerama
  (bug 457685: patch by jwz and Aaron Plattner <aplattner at nvidia.com>)


xscreensaver-5.06-bz457685-nvidia-jwz.patch:

--- NEW FILE xscreensaver-5.06-bz457685-nvidia-jwz.patch ---
Index: screens.c
===================================================================
RCS file: /cvsroot/xscreensaver/driver/screens.c,v
retrieving revision 1.7
retrieving revision 1.12
diff -u -r1.7 -r1.12
--- screens.c	8 Jul 2008 05:22:46 -0000	1.7
+++ screens.c	8 Aug 2008 21:06:07 -0000	1.12
@@ -98,6 +98,16 @@
  *      to put seperate savers on those duplicated-or-overlapping
  *      monitors, xscreensaver just ignores them (which allows them to
  *      display duplicates or overlaps).
+ *
+ *   5a) Nvidia fucks it up:
+ *
+ *      Nvidia drivers as of Aug 2008 running in "TwinView" mode
+ *      apparently report correct screen geometry via Xinerama, but
+ *      report one giant screen via RANDR.  The response from the
+ *      nvidia developers is, "we don't support RANDR, use Xinerama
+ *      instead."  Which is a seriously lame answer.  So, xscreensaver
+ *      has to query *both* extensions, and make a guess as to which
+ *      is to be believed.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -143,6 +153,9 @@
   int enemy;			/* which monitor it overlaps or duplicates */
 };
 
+static Bool layouts_differ_p (monitor **a, monitor **b);
+
+
 static void
 free_monitors (monitor **monitors)
 {
@@ -342,7 +355,7 @@
 
   for (i = 0, j = 0; i < ScreenCount (dpy); i++)
     {
-      Screen *screen = ScreenOfDisplay (dpy, j);
+      Screen *screen = ScreenOfDisplay (dpy, i);
 
       if (! new_randr_p)  /* RANDR 1.0 */
         {
@@ -358,12 +371,17 @@
               SizeID size = -1;
               Rotation rot = ~0;
               XRRScreenSize *rrsizes;
-              int nsizes;
+              int nsizes = 0;
 
               size = XRRConfigCurrentConfiguration (rrc, &rot);
               rrsizes = XRRConfigSizes (rrc, &nsizes);
 
-              if (rot & (RR_Rotate_90|RR_Rotate_270))
+              if (nsizes <= 0)  /* WTF?  Shouldn't happen but does. */
+                {
+                  m->width  = DisplayWidth (dpy, i);
+                  m->height = DisplayHeight (dpy, i);
+                }
+              else if (rot & (RR_Rotate_90|RR_Rotate_270))
                 {
                   m->width  = rrsizes[size].height;
                   m->height = rrsizes[size].width;
@@ -454,6 +472,66 @@
 }
 
 
+#if defined(HAVE_RANDR) && defined(HAVE_XINERAMA)
+
+/*   From: Aaron Plattner <aplattner at nvidia.com>
+     Date: August 7, 2008 10:21:25 AM PDT
+     To: linux-bugs at nvidia.com
+
+     The NVIDIA X driver does not yet support RandR 1.2.  The X server has
+     a compatibility layer in it that allows RandR 1.2 clients to talk to
+     RandR 1.1 drivers through an RandR 1.2 pseudo-output called "default".
+     This reports the total combined resolution of the TwinView display,
+     since it doesn't have any visibility into TwinView metamodes.  There
+     is no way for the driver to prevent the server from turning on this
+     compatibility layer.
+
+     The intention is for X client applications to continue to use the
+     Xinerama extension to query the screen geometry.  RandR 1.2 reports
+     its own Xinerama info for this purpose.  I would recommend against
+     modifying xscreensaver to try to get this information from RandR.
+ */
+static monitor **
+randr_versus_xinerama_fight (Display *dpy, monitor **randr_monitors)
+{
+  monitor **xinerama_monitors;
+
+  if (!randr_monitors) 
+    return 0;
+
+  xinerama_monitors = xinerama_scan_monitors (dpy);
+  if (!xinerama_monitors)
+    return randr_monitors;
+
+  if (! layouts_differ_p (randr_monitors, xinerama_monitors))
+    {
+      free_monitors (xinerama_monitors);
+      return randr_monitors;
+    }
+  else if (   randr_monitors[0] &&   !randr_monitors[1] &&  /* 1 monitor */
+           xinerama_monitors[0] && xinerama_monitors[1])    /* >1 monitor */
+    {
+      fprintf (stderr,
+               "%s: WARNING: RANDR reports 1 screen but Xinerama\n"
+               "%s:          reports multiple.  Believing Xinerama.\n",
+               blurb(), blurb());
+      free_monitors (randr_monitors);
+      return xinerama_monitors;
+    }
+  else
+    {
+      fprintf (stderr,
+               "%s: WARNING: RANDR and Xinerama report different\n"
+               "%s:          screen layouts!  Believing RANDR.\n",
+               blurb(), blurb());
+      free_monitors (xinerama_monitors);
+      return randr_monitors;
+    }
+}
+
+#endif /* HAVE_RANDR && HAVE_XINERAMA */
+
+
 #ifdef DEBUG_MULTISCREEN
 
 /* If DEBUG_MULTISCREEN is defined, then in "-debug" mode, xscreensaver
@@ -557,13 +635,17 @@
 # ifdef HAVE_RANDR
   if (! p->getviewport_full_of_lies_p)
     if (! monitors) monitors = randr_scan_monitors (si->dpy);
-# endif
+
+#  ifdef HAVE_XINERAMA
+   monitors = randr_versus_xinerama_fight (si->dpy, monitors);
+#  endif
+# endif /* HAVE_RANDR */
 
 # ifdef HAVE_XF86VMODE
   if (! monitors) monitors = vidmode_scan_monitors (si->dpy);
 # endif
 
-# ifdef HAVE_XF86VMODE
+# ifdef HAVE_XINERAMA
   if (! monitors) monitors = xinerama_scan_monitors (si->dpy);
 # endif
 
@@ -598,6 +680,38 @@
 }
 
 
+static Bool
+plausible_aspect_ratio_p (monitor **monitors)
+{
+  /* Modern wide-screen monitors come in the following aspect ratios:
+
+            One monitor:        If you tack a 640x480 monitor
+                                onto the right, the ratio is:
+         16 x 9    --> 1.78
+        852 x 480  --> 1.77        852+640 x 480  --> 3.11      "SD 480p"
+       1280 x 720  --> 1.78       1280+640 x 720  --> 2.67      "HD 720p"
+       1280 x 920  --> 1.39       1280+640 x 920  --> 2.09
+       1366 x 768  --> 1.78       1366+640 x 768  --> 2.61      "HD 768p"
+       1440 x 900  --> 1.60       1440+640 x 900  --> 2.31
+       1680 x 1050 --> 1.60       1680+640 x 1050 --> 2.21
+       1690 x 1050 --> 1.61       1690+640 x 1050 --> 2.22
+       1920 x 1080 --> 1.78       1920+640 x 1080 --> 2.37      "HD 1080p"
+       1920 x 1200 --> 1.60       1920+640 x 1200 --> 2.13
+       2560 x 1600 --> 1.60       2560+640 x 1600 --> 2.00
+
+     So that implies that if we ever see an aspect ratio >= 2.0,
+     we can be pretty sure that the X server is lying to us, and
+     that's actually two monitors, not one.
+   */
+  if (monitors[0] && !monitors[1] &&    /* exactly 1 monitor */
+      monitors[0]->height &&
+      monitors[0]->width / (double) monitors[0]->height >= 1.9)
+    return False;
+  else
+    return True;
+}
+
+
 /* Mark the ones that overlap, etc.
  */
 static void
@@ -624,6 +738,7 @@
       if (i != j &&
           monitors[i]->sanity == S_SANE &&
           monitors[j]->sanity == S_SANE &&
+          monitors[i]->screen == monitors[j]->screen &&
           X2 >= X1 &&
           Y2 >= Y1 &&
           (X2+W2) <= (X1+W1) &&
@@ -648,6 +763,7 @@
       {
         if (monitors[i]->sanity != S_SANE) continue; /* already marked */
         if (monitors[j]->sanity != S_SANE) continue;
+        if (monitors[i]->screen != monitors[j]->screen) continue;
 
         if (monitors_overlap_p (monitors[i], monitors[j]))
           {
@@ -656,17 +772,15 @@
           }
       }
 
-  /* Finally, make sure all monitors are enclosed by their X screen.
+  /* Finally, make sure all monitors have sane positions and sizes.
      Xinerama sometimes reports 1024x768 VPs at -1936862040, -1953705044.
    */
   for (i = 0; i < count; i++)
     {
-      int sw = WidthOfScreen (monitors[i]->screen)  * 2;
-      int sh = HeightOfScreen (monitors[i]->screen) * 2;
       if (monitors[i]->sanity != S_SANE) continue; /* already marked */
-      if (X1    <  0 || Y1    <  0 || 
-          W1    <= 0 || H1    <= 0 || 
-          X1+W1 > sw || Y1+H1 > sh)
+      if (X1    <  0      || Y1    <  0 || 
+          W1    <= 0      || H1    <= 0 || 
+          X1+W1 >= 0x7FFF || Y1+H1 >= 0x7FFF)
         {
           monitors[i]->sanity = S_OFFSCREEN;
           monitors[i]->enemy = 0;
@@ -715,6 +829,8 @@
   int count = 0;
   int good_count = 0;
   int bad_count = 0;
+  int implausible_p = !plausible_aspect_ratio_p (monitors);
+
   while (monitors[count])
     {
       if (monitors[count]->sanity == S_SANE)
@@ -778,6 +894,14 @@
                 }
             }
         }
+
+      if (implausible_p)
+        fprintf (stderr,
+                 "%s: WARNING: single screen aspect ratio is %dx%d = %.2f\n"
+                 "%s:          probable X server bug in Xinerama/RANDR!\n",
+                 blurb(), monitors[0]->width, monitors[0]->height,
+                 monitors[0]->width / (double) monitors[0]->height,
+                 blurb());
     }
 }
 


Index: xscreensaver.spec
===================================================================
RCS file: /cvs/extras/rpms/xscreensaver/F-9/xscreensaver.spec,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -r1.71 -r1.72
--- xscreensaver.spec	24 Jul 2008 18:15:08 -0000	1.71
+++ xscreensaver.spec	9 Aug 2008 03:12:41 -0000	1.72
@@ -5,7 +5,7 @@
 
 
 %define modular_conf  1
-%define fedora_rel    2
+%define fedora_rel    3
 
 %define extrarel      %{nil}
 
@@ -33,7 +33,9 @@
 %endif
 Patch1:          xscreensaver-5.00b5-sanitize-hacks.patch
 Patch21:         xscreensaver-5.05-webcollage-default-nonet.patch
-Patch40:         xscreensaver-5.06-bz456399-jwz.patch
+# Patch40 is merged into Patch41
+#Patch40:         xscreensaver-5.06-bz456399-jwz.patch
+Patch41:         xscreensaver-5.06-bz457685-nvidia-jwz.patch
 Requires:        xscreensaver-base = %{epoch}:%{version}-%{release}
 Requires:        xscreensaver-extras = %{epoch}:%{version}-%{release}
 Requires:        xscreensaver-gl-extras = %{epoch}:%{version}-%{release}
@@ -186,7 +188,11 @@
 
 %patch1 -p1 -b .sanitize-hacks
 %patch21 -p1 -b .nonet
-%patch40 -p0 -b .jwz40
+# Patch40 is merged into Patch41
+#%%patch40 -p0 -b .jwz40
+cd driver/
+%patch41 -p0 -b .jwz41
+cd ..
 
 change_option(){
    set +x
@@ -609,8 +615,14 @@
 %defattr(-,root,root,-)
 
 %changelog
+* Sat Aug  9 2008 Mamoru Tasaka <mtasaka at ioa.s.u-tokyo.ac.jp> - 1:5.06-3
+- Fallback to Xinerama extension when Xrandr reports less screens
+  than Xinerama
+  (bug 457685: patch by jwz and Aaron Plattner <aplattner at nvidia.com>)
+
 * Fri Jul 25 2008 Mamoru Tasaka <mtasaka at ioa.s.u-tokyo.ac.jp> - 1:5.06-2
-- Patch from jwz to fix bug 456399
+- Fix crash on start up in some case with dual screen
+  (bug 456399: patch from jwz)
 
 * Thu Jul 24 2008 Mamoru Tasaka <mtasaka at ioa.s.u-tokyo.ac.jp>
 - Build some test binaries for debugging




More information about the fedora-extras-commits mailing list