Can you try this patch against 5.07, and see what it does when your X server is configured in the way that was resulting in a 0x0 screen before? Thanks...

cvs diff: Diffing .
Index: screens.c
===================================================================
RCS file: /cvsroot/xscreensaver/driver/screens.c,v
retrieving revision 1.12
diff -u -r1.12 screens.c
--- screens.c   8 Aug 2008 21:06:07 -0000       1.12
+++ screens.c   14 Aug 2008 08:47:21 -0000
@@ -99,7 +99,7 @@
  *      monitors, xscreensaver just ignores them (which allows them to
  *      display duplicates or overlaps).
  *
- *   5a) Nvidia fucks it up:
+ *  5a) Nvidia fucks it up:
  *
  *      Nvidia drivers as of Aug 2008 running in "TwinView" mode
  *      apparently report correct screen geometry via Xinerama, but
@@ -108,6 +108,10 @@
  *      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.
+ *
+ *  5b) Also sometimes RANDR says stupid shit like, "You have one
+ *      screen, and it has no available orientations or sizes."
+ *
  */
 
 #ifdef HAVE_CONFIG_H
@@ -151,6 +155,8 @@
   int x, y, width, height;
   monitor_sanity sanity;       /* I'm not crazy you're the one who's crazy */
   int enemy;                   /* which monitor it overlaps or duplicates */
+  char *err;                   /* msg to print at appropriate later time;
+                                   exists only on monitor #0. */
 };
 
 static Bool layouts_differ_p (monitor **a, monitor **b);
@@ -164,6 +170,7 @@
   while (*m2) 
     {
       if ((*m2)->desc) free ((*m2)->desc);
+      if ((*m2)->err) free ((*m2)->err);
       free (*m2);
       m2++;
     }
@@ -171,10 +178,24 @@
 }
 
 
+static char *
+append (char *s1, const char *s2)
+{
+  char *s = (char *) malloc ((s1 ? strlen(s1) : 0) +
+                             (s2 ? strlen(s2) : 0) + 3);
+  *s = 0;
+  if (s1) strcat (s, s1);
+  if (s1 && s2) strcat (s, "\n");
+  if (s2) strcat (s, s2);
+  if (s1) free (s1);
+  return s;
+}
+
+
 #ifdef HAVE_XINERAMA
 
 static monitor **
-xinerama_scan_monitors (Display *dpy)
+xinerama_scan_monitors (Display *dpy, char **errP)
 {
   Screen *screen = DefaultScreenOfDisplay (dpy);
   int event, error, nscreens, i;
@@ -213,7 +234,7 @@
 #ifdef HAVE_XF86VMODE
 
 static monitor **
-vidmode_scan_monitors (Display *dpy)
+vidmode_scan_monitors (Display *dpy, char **errP)
 {
   int event, error, nscreens, i;
   monitor **monitors;
@@ -312,7 +333,7 @@
 #ifdef HAVE_RANDR
 
 static monitor **
-randr_scan_monitors (Display *dpy)
+randr_scan_monitors (Display *dpy, char **errP)
 {
   int event, error, major, minor, nscreens, i, j;
   monitor **monitors;
@@ -350,6 +371,13 @@
 # endif /* HAVE_RANDR_12 */
     }
 
+  if (nscreens <= 0)
+    {
+      *errP = append (*errP,
+                      "WARNING: RANDR reported no screens!  Ignoring it.");
+      return 0;
+    }
+
   monitors = (monitor **) calloc (nscreens + 1, sizeof(*monitors));
   if (!monitors) return 0;
 
@@ -442,6 +470,25 @@
         }
     }
 
+  /* Work around more fucking brain damage. */
+  {
+    int ok = 0;
+    int i = 0;
+    while (monitors[i]) 
+      {
+        if (monitors[i]->width != 0 && monitors[i]->height != 0)
+          ok++;
+        i++;
+      }
+    if (! ok)
+      {
+        *errP = append (*errP,
+              "WARNING: RANDR says all screens are 0x0!  Ignoring it.");
+        free_monitors (monitors);
+        monitors = 0;
+      }
+  }
+
   return monitors;
 }
 
@@ -449,7 +496,7 @@
 
 
 static monitor **
-basic_scan_monitors (Display *dpy)
+basic_scan_monitors (Display *dpy, char **errP)
 {
   int nscreens = ScreenCount (dpy);
   int i;
@@ -492,14 +539,15 @@
      modifying xscreensaver to try to get this information from RandR.
  */
 static monitor **
-randr_versus_xinerama_fight (Display *dpy, monitor **randr_monitors)
+randr_versus_xinerama_fight (Display *dpy, monitor **randr_monitors, 
+                             char **errP)
 {
   monitor **xinerama_monitors;
 
   if (!randr_monitors) 
     return 0;
 
-  xinerama_monitors = xinerama_scan_monitors (dpy);
+  xinerama_monitors = xinerama_scan_monitors (dpy, errP);
   if (!xinerama_monitors)
     return randr_monitors;
 
@@ -511,19 +559,17 @@
   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());
+      *errP = append (*errP,
+                      "WARNING: RANDR reports 1 screen but Xinerama\n"
+                      "\t\treports multiple.  Believing Xinerama.");
       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());
+      *errP = append (*errP,
+                      "WARNING: RANDR and Xinerama report different\n"
+                      "\t\tscreen layouts!  Believing RANDR.");
       free_monitors (xinerama_monitors);
       return randr_monitors;
     }
@@ -540,7 +586,7 @@
    for stress-testing purposes.
  */
 static monitor **
-debug_scan_monitors (Display *dpy)
+debug_scan_monitors (Display *dpy, char **errP)
 {
   static const char * const geoms[] = {
     "1600x1028+0+22",
@@ -587,7 +633,7 @@
 
 #ifdef QUAD_MODE
 static monitor **
-quadruple (monitor **monitors, Bool debug_p)
+quadruple (monitor **monitors, Bool debug_p, char **errP)
 {
   int i, j, count = 0;
   monitor **monitors2;
@@ -627,35 +673,38 @@
 {
   saver_preferences *p = &si->prefs;
   monitor **monitors = 0;
+  char *err = 0;
 
 # ifdef DEBUG_MULTISCREEN
-    if (! monitors) monitors = debug_scan_monitors (si->dpy);
+    if (! monitors) monitors = debug_scan_monitors (si->dpy, &err);
 # endif
 
 # ifdef HAVE_RANDR
   if (! p->getviewport_full_of_lies_p)
-    if (! monitors) monitors = randr_scan_monitors (si->dpy);
+    if (! monitors) monitors = randr_scan_monitors (si->dpy, &err);
 
 #  ifdef HAVE_XINERAMA
-   monitors = randr_versus_xinerama_fight (si->dpy, monitors);
+   monitors = randr_versus_xinerama_fight (si->dpy, monitors, &err);
 #  endif
 # endif /* HAVE_RANDR */
 
 # ifdef HAVE_XF86VMODE
-  if (! monitors) monitors = vidmode_scan_monitors (si->dpy);
+  if (! monitors) monitors = vidmode_scan_monitors (si->dpy, &err);
 # endif
 
 # ifdef HAVE_XINERAMA
-  if (! monitors) monitors = xinerama_scan_monitors (si->dpy);
+  if (! monitors) monitors = xinerama_scan_monitors (si->dpy, &err);
 # endif
 
-  if (! monitors) monitors = basic_scan_monitors (si->dpy);
+  if (! monitors) monitors = basic_scan_monitors (si->dpy, &err);
 
 # ifdef QUAD_MODE
   if (p->quad_p)
-    monitors = quadruple (monitors, p->debug_p);
+    monitors = quadruple (monitors, p->debug_p, &err);
 # endif
 
+  if (monitors && err) monitors[0]->err = err;
+
   return monitors;
 }
 
@@ -840,6 +889,18 @@
       count++;
     }
 
+  if (monitors[0]->err)                /* deferred error msg */
+    {
+      char *token = strtok (monitors[0]->err, "\n");
+      while (token)
+        {
+          fprintf (stderr, "%s: %s\n", blurb(), token);
+          token = strtok (0, "\n");
+        }
+      free (monitors[0]->err);
+      monitors[0]->err = 0;
+    }
+
   if (count == 0)
     fprintf (stderr, "%s: no screens!\n", blurb());
   else
Index: test-randr.c
===================================================================
RCS file: /cvsroot/xscreensaver/driver/test-randr.c,v
retrieving revision 1.4
diff -u -r1.4 test-randr.c
--- test-randr.c        5 Jul 2008 12:55:38 -0000       1.4
+++ test-randr.c        14 Aug 2008 08:45:54 -0000
@@ -285,7 +285,11 @@
         }
 
       XSync (dpy, False);
-      fprintf (stderr, "\n%s: awaiting events...\n", progname);
+
+      fprintf (stderr, "\n%s: awaiting events...\n\n"
+          "\t(If you resize the screen or add/remove monitors, this should\n"
+          "\tnotice that and print stuff.  Otherwise, hit ^C.)\n\n",
+               progname);
       while (1)
         {
          XEvent event;
Index: xscreensaver.c
===================================================================
RCS file: /cvsroot/xscreensaver/driver/xscreensaver.c,v
retrieving revision 1.148
diff -u -r1.148 xscreensaver.c
--- xscreensaver.c      19 Jul 2008 10:15:24 -0000      1.148
+++ xscreensaver.c      14 Aug 2008 08:51:55 -0000
@@ -2124,6 +2124,10 @@
 #     endif
    }, { "DRI",                                 "DRI",
         True,  0
+   }, { "NV-CONTROL",                           "NVidia",
+        True,  0
+   }, { "NV-GLX",                               "NVidia GLX",
+        True,  0
    }, { "Apple-DRI",                            "Apple-DRI (XDarwin)",
         True,  0
    },

Reply via email to