Index: include/allegro5/internal/aintern_xglx.h
===================================================================
--- include/allegro5/internal/aintern_xglx.h	(revision 14233)
+++ include/allegro5/internal/aintern_xglx.h	(working copy)
@@ -84,12 +84,17 @@
 #endif
 #ifdef ALLEGRO_XWINDOWS_WITH_XRANDR
    int xrandr_available;
-   XRRScreenResources *xrandr_res;
+   int xrandr_res_count;
+   XRRScreenResources **xrandr_res;
    // these are technically changeable at runtime if we handle XRandR events.
    // or more accurately, they can become stale at runtime if we don't handle XRandR events.
    int xrandr_output_count;
-   XRROutputInfo **xrandr_outputs;
-   XRRModeInfo **xrandr_stored_modes;
+   struct xrandr_output_s {
+      int res_id;
+      XRROutputInfo *output;
+      XRRModeInfo *mode;
+   } **xrandr_outputs;
+   
 #endif
 };
 
Index: src/x/xglx_config.c
===================================================================
--- src/x/xglx_config.c	(revision 14233)
+++ src/x/xglx_config.c	(working copy)
@@ -213,7 +213,9 @@
 
    ref = _al_get_new_display_settings();
 
-   fbconfig = glXGetFBConfigs(system->gfxdisplay, glx->xscreen, &num_fbconfigs);
+   /* XXX pass in DefaultScreen here rather than glx->xscreen here, xscreen can be a virtual screen
+    * not related to any actual X Screen if xrandr or xinerama is in use */
+   fbconfig = glXGetFBConfigs(system->gfxdisplay, DefaultScreen(system->x11display), &num_fbconfigs);
    if (!fbconfig || !num_fbconfigs) {
       ALLEGRO_DEBUG("glXGetFBConfigs(xscreen=%d) returned NULL.\n", glx->xscreen);
       return NULL;
Index: src/x/xfullscreen.c
===================================================================
--- src/x/xfullscreen.c	(revision 14233)
+++ src/x/xfullscreen.c	(working copy)
@@ -117,16 +117,21 @@
 {
    XRRScreenResources *res = NULL;
    bool ret = 0;
+   int xscr = 0;
+   int res_idx = 0;
 
-   if (s->xrandr_res) {
-      XRRFreeScreenResources(s->xrandr_res);
+   if(s->xrandr_res) {
+      for(res_idx = 0; res_idx < s->xrandr_res_count; res_idx++) {
+         XRRFreeScreenResources(s->xrandr_res[res_idx]);
+      }
+      free(s->xrandr_res);
    }
-
+   
    if (s->xrandr_outputs) {
       int i;
       for (i = 0; i < s->xrandr_output_count; i++) {
-         XRRFreeOutputInfo(s->xrandr_outputs[i]);
-         s->xrandr_outputs[i] = NULL;
+         XRRFreeOutputInfo(s->xrandr_outputs[i]->output);
+         s->xrandr_outputs[i]->output = NULL;
       }
       al_free(s->xrandr_outputs);
       s->xrandr_outputs = NULL;
@@ -136,73 +141,92 @@
    /* XXX This causes an annoying flicker with the intel driver and a secondary
     * display (at least) so should be deferred until required.
     */
-   res = s->xrandr_res = XRRGetScreenResources (s->x11display, XRootWindow(s->x11display, DefaultScreen(s->x11display)));
-   if (res && res->nmode) {
-      s->xrandr_output_count = 0; // just in case
 
-      // XXX this may not behave correctly if there are any cloned outputs
-      int ncrtc;
-      for (ncrtc = 0; ncrtc < res->ncrtc; ncrtc++) {
-         XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, res, res->crtcs[ncrtc]);
-         if (!crtc_info) {
-            ALLEGRO_WARN("xrandr: failed to fetch crtc %i\n", ncrtc);
-            continue;
-         }
+   s->xrandr_res = al_calloc(ScreenCount(s->x11display), sizeof(*s->xrandr_res));
+   if(!s->xrandr_res) {
+      ALLEGRO_ERROR("xrandr: failed to allocate array for XRRScreenResources structures.\n");
+      return 0;
+   }
+   
+   s->xrandr_output_count = 0; // just in case
+   for(xscr = 0; xscr < ScreenCount(s->x11display); xscr++) {
 
-         ALLEGRO_DEBUG("xrandr: got crtc %d.\n", ncrtc);
+      res = s->xrandr_res[xscr] = XRRGetScreenResources (s->x11display, XRootWindow(s->x11display, xscr)); // DefaultScreen(s->x11display)
+      if (res && res->nmode) {
+         // XXX this may not behave correctly if there are any cloned outputs
+         int ncrtc;
+         for (ncrtc = 0; ncrtc < res->ncrtc; ncrtc++) {
+            XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, res, res->crtcs[ncrtc]);
+            if (!crtc_info) {
+               ALLEGRO_WARN("xrandr: failed to fetch crtc %i\n", ncrtc);
+               continue;
+            }
 
-         if (crtc_info->noutput > 0) {
-            XRROutputInfo **new_output_info = s->xrandr_outputs;
-            int new_output_count = s->xrandr_output_count + crtc_info->noutput;
+            ALLEGRO_DEBUG("xrandr: got crtc %d.\n", ncrtc);
 
-            new_output_info = al_realloc(new_output_info, sizeof(XRROutputInfo *) * new_output_count);
-            if (new_output_info) {
-               memset(new_output_info+s->xrandr_output_count, 0, sizeof(XRROutputInfo*)*crtc_info->noutput);
+            if (crtc_info->noutput > 0) {
+               struct xrandr_output_s **new_output_info = s->xrandr_outputs;
+               int new_output_count = s->xrandr_output_count + crtc_info->noutput;
 
-               int nout;
-               for (nout = 0; nout < crtc_info->noutput; nout++) {
-                  XRROutputInfo *info = XRRGetOutputInfo(s->x11display, res, crtc_info->outputs[nout]);
-                  if (!info) {
-                     ALLEGRO_WARN("xrandr: failed to fetch output %i for crtc %i\n", nout, ncrtc);
-                     continue;
+               new_output_info = al_realloc(new_output_info, sizeof(s->xrandr_outputs) * new_output_count);
+               if (new_output_info) {
+                  memset(new_output_info+s->xrandr_output_count, 0, sizeof(s->xrandr_outputs)*crtc_info->noutput);
+
+                  int nout;
+                  for (nout = 0; nout < crtc_info->noutput; nout++) {
+                     XRROutputInfo *info = XRRGetOutputInfo(s->x11display, res, crtc_info->outputs[nout]);
+                     if (!info) {
+                        ALLEGRO_WARN("xrandr: failed to fetch output %i for crtc %i\n", nout, ncrtc);
+                        continue;
+                     }
+
+                     ALLEGRO_DEBUG("xrandr: added new output[%d].\n", s->xrandr_output_count + nout);
+                     new_output_info[s->xrandr_output_count + nout] = al_calloc(1, sizeof(*s->xrandr_outputs));
+                     if(!new_output_info[s->xrandr_output_count + nout]) {
+                        ALLEGRO_ERROR("xrandr: failed to allocate output structure.\n");
+                        continue;
+                     }
+                     
+                     new_output_info[s->xrandr_output_count + nout]->output = info;
+                     new_output_info[s->xrandr_output_count + nout]->res_id = xscr;
                   }
 
-                  ALLEGRO_DEBUG("xrandr: added new output[%d].\n", s->xrandr_output_count + nout);
-                  new_output_info[s->xrandr_output_count + nout] = info;
+                  s->xrandr_outputs = new_output_info;
+                  s->xrandr_output_count = new_output_count;
+
                }
+               else {
+                  ALLEGRO_ERROR("xrandr: failed to allocate array for output structures.\n");
+                  continue;
+               }
+            }
 
-               s->xrandr_outputs = new_output_info;
-               s->xrandr_output_count = new_output_count;
+            XRRFreeCrtcInfo(crtc_info);
+         }
 
+         if (s->xrandr_output_count > 0) {
+   #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA
+            if (s->xinerama_available && s->xinerama_screen_count != s->xrandr_output_count) {
+               ALLEGRO_WARN("XRandR and Xinerama seem to disagree on how many screens there are (%i vs %i), going to ignore XRandR.\n", s->xrandr_output_count, s->xinerama_screen_count);
+               // only actually going to ignore the output count, and setting of modes on the extra xinerama screens.
             }
-            else {
-               ALLEGRO_ERROR("xrandr: failed to allocate array for output structures.\n");
-               continue;
-            }
+   #else
+            // XXX verify xrandr isn't borked here because of stupidity
+            // XXX  like the nvidia binary driver only implementing XRandR 1.1
+   #endif
+
+            ret = 1;
          }
-
-         XRRFreeCrtcInfo(crtc_info);
+         else {
+            ALLEGRO_WARN("XRandR has no outputs.\n");
+            ret = 0;
+         }
       }
 
-      if (s->xrandr_output_count > 0) {
-#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA
-         if (s->xinerama_available && s->xinerama_screen_count != s->xrandr_output_count) {
-            ALLEGRO_WARN("XRandR and Xinerama seem to disagree on how many screens there are (%i vs %i), going to ignore XRandR.\n", s->xrandr_output_count, s->xinerama_screen_count);
-            // only actually going to ignore the output count, and setting of modes on the extra xinerama screens.
-         }
-#else
-         // XXX verify xrandr isn't borked here because of stupidity
-         // XXX  like the nvidia binary driver only implementing XRandR 1.1
-#endif
-         ALLEGRO_DEBUG("xrandr: found %d outputs.\n",s->xrandr_output_count);
-         ret = 1;
-      }
-      else {
-         ALLEGRO_WARN("XRandR has no outputs.\n");
-         ret = 0;
-      }
    }
 
+   ALLEGRO_DEBUG("xrandr: found %d outputs.\n",s->xrandr_output_count);
+
    return ret;
 }
 
@@ -213,7 +237,7 @@
    if (adapter < 0 || adapter >= s->xrandr_output_count)
       return 0;
 
-   return s->xrandr_outputs[adapter]->nmode;
+   return s->xrandr_outputs[adapter]->output->nmode;
 }
 
 static ALLEGRO_DISPLAY_MODE *_al_xsys_xrandr_get_mode(ALLEGRO_SYSTEM_XGLX *s, int adapter, int id, ALLEGRO_DISPLAY_MODE *mode)
@@ -224,9 +248,13 @@
       return NULL;
       
    int i;
-   for (i = 0; i < s->xrandr_res->nmode; i++) {
-      if (s->xrandr_res->modes[i].id == s->xrandr_outputs[adapter]->modes[id]) {
-         mi = &s->xrandr_res->modes[i];
+
+   /* should we validate res_id here? only way it would be invalid is if the array got stomped on... so a crash would be imminent anyhow */
+   XRRScreenResources *res = s->xrandr_res[s->xrandr_outputs[adapter]->res_id];
+   
+   for (i = 0; i < res->nmode; i++) {
+      if (res->modes[i].id == s->xrandr_outputs[adapter]->output->modes[id]) {
+         mi = &res->modes[i];
          break;
       }
    }
@@ -253,11 +281,12 @@
 {
    int mode_idx = -1;
    XRRModeInfo *mi = NULL;
-
+   XRRScreenResources *res = NULL;
+   
    if (d->xscreen < 0 || d->xscreen >= s->xrandr_output_count)
       return false;
-
-   XRRModeInfo *cur_mode = s->xrandr_stored_modes[d->xscreen];
+   
+   XRRModeInfo *cur_mode = s->xrandr_outputs[d->xscreen]->mode;
    int cur_refresh_rate;
    if (cur_mode->hTotal && cur_mode->vTotal)
       cur_refresh_rate = ((float) cur_mode->dotClock / ((float) cur_mode->hTotal * (float) cur_mode->vTotal));
@@ -277,17 +306,19 @@
       return false;
    }
 
-   mi = &s->xrandr_res->modes[mode_idx];
+   res = s->xrandr_res[s->xrandr_outputs[d->xscreen]->res_id];
 
+   mi = &res->modes[mode_idx];
+
    _al_mutex_lock(&s->lock);
 
    // grab the Crtc info so we can get the info we ARENT changing to pass back to SetCrtcConfig
-   XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, s->xrandr_res, s->xrandr_outputs[d->xscreen]->crtc);
+   XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, res, s->xrandr_outputs[d->xscreen]->output->crtc);
 
    // actually changes the mode, what a name.
    // XXX actually check for failure...
-   int ok = XRRSetCrtcConfig(s->x11display, s->xrandr_res,
-                    s->xrandr_outputs[d->xscreen]->crtc,
+   int ok = XRRSetCrtcConfig(s->x11display, res,
+                    s->xrandr_outputs[d->xscreen]->output->crtc,
                     // proves to XRandR that our info is up to date, or it'll just ignore us
                     crtc_info->timestamp,
                     // we don't want to change any of the config prefixed by crtc_info
@@ -313,28 +344,26 @@
 
 static void _al_xsys_xrandr_store_modes(ALLEGRO_SYSTEM_XGLX *s)
 {
-   al_free(s->xrandr_stored_modes);
-   s->xrandr_stored_modes = al_calloc(s->xrandr_output_count, sizeof(XRRModeInfo*));
-   if (!s->xrandr_stored_modes) {
-      ALLEGRO_ERROR("XRandR failed to allocate memory for stored modes array.\n");
-      return;
-   }
-
    // XXX this might be better placed in xrandr_query, it'd save a bunch of XRRGetCrtcInfo calls.
    int i;
    for (i = 0; i < s->xrandr_output_count; i++) {
-      XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, s->xrandr_res, s->xrandr_outputs[i]->crtc);
-
+      XRRScreenResources *res = s->xrandr_res[s->xrandr_outputs[i]->res_id];
+      
+      XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, res, s->xrandr_outputs[i]->output->crtc);
+      ALLEGRO_DEBUG("xrandr: got %i modes.\n",  res->nmode);
+      
       int j;
-      for (j = 0; j < s->xrandr_res->nmode; j++) {
-         if (s->xrandr_res->modes[j].id == crtc_info->mode) {
-            s->xrandr_stored_modes[i] = &s->xrandr_res->modes[j];
+      for (j = 0; j < res->nmode; j++) {
+         ALLEGRO_DEBUG("xrandr: modecmp %i == %i.\n", (int)res->modes[j].id, (int)crtc_info->mode);
+         if (res->modes[j].id == crtc_info->mode) {
+            ALLEGRO_DEBUG("xrandr: matched mode!\n");
+            s->xrandr_outputs[i]->mode = &res->modes[j];
          }
       }
 
       XRRFreeCrtcInfo(crtc_info);
 
-      if (!s->xrandr_stored_modes[i]) {
+      if (!s->xrandr_outputs[i]->mode) {
          ALLEGRO_WARN("XRandR failed to store mode for adapter %d.\n", i);
       }
    }
@@ -345,31 +374,32 @@
    if (adapter < 0 || adapter >= s->xrandr_output_count)
       return;
    
-   ASSERT(s->xrandr_stored_modes[adapter]);
+   ASSERT(s->xrandr_outputs[adapter]->mode);
    ALLEGRO_DEBUG("xfullscreen: _al_xsys_xrandr_restore_mode (%d, %d)\n",
-                 s->xrandr_stored_modes[adapter]->width, s->xrandr_stored_modes[adapter]->height);
+                 s->xrandr_outputs[adapter]->mode->width, s->xrandr_outputs[adapter]->mode->height);
 
-   XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, s->xrandr_res, s->xrandr_outputs[adapter]->crtc);
+   XRRScreenResources *res = s->xrandr_res[s->xrandr_outputs[adapter]->res_id];
+   XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, res, s->xrandr_outputs[adapter]->output->crtc);
    if (!crtc_info) {
       ALLEGRO_ERROR("xfullscreen: XRRGetCrtcInfo failed.\n");
       return;
    }
 
-   if (s->xrandr_stored_modes[adapter]->width == crtc_info->width &&
-      s->xrandr_stored_modes[adapter]->height == crtc_info->height) {
+   if (s->xrandr_outputs[adapter]->mode->width == crtc_info->width &&
+      s->xrandr_outputs[adapter]->mode->height == crtc_info->height) {
       ALLEGRO_INFO("xfullscreen: mode already restored.\n");
       return;
    }
    // actually changes the mode, what a name.
    int ok = XRRSetCrtcConfig(s->x11display,
-                    s->xrandr_res,
-                    s->xrandr_outputs[adapter]->crtc,
+                    res,
+                    s->xrandr_outputs[adapter]->output->crtc,
                     // proves to XRandR that our info is up to date, or it'll just ignore us
                     crtc_info->timestamp,
                     // we don't want to change any of the config prefixed by crtc_info
                     crtc_info->x,
                     crtc_info->y,
-                    s->xrandr_stored_modes[adapter]->id, // Set the Mode!
+                    s->xrandr_outputs[adapter]->mode->id, // Set the Mode!
                     crtc_info->rotation,
                     crtc_info->outputs,
                     crtc_info->noutput);
@@ -391,7 +421,8 @@
    } else
 #endif
    {
-      XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, s->xrandr_res, s->xrandr_outputs[adapter]->crtc);
+      XRRScreenResources *res = s->xrandr_res[s->xrandr_outputs[adapter]->res_id];
+      XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, res, s->xrandr_outputs[adapter]->output->crtc);
       if (!crtc_info) {
          ALLEGRO_ERROR("XRandR failed to get CrtcInfo, can't get display offset.\n");
          return;
@@ -423,7 +454,8 @@
    }
 #endif
 
-   XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, s->xrandr_res, s->xrandr_outputs[adapter]->crtc);
+   XRRScreenResources *res = s->xrandr_res[s->xrandr_outputs[adapter]->res_id];
+   XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, res, s->xrandr_outputs[adapter]->output->crtc);
    if (!crtc_info) {
       ALLEGRO_ERROR("XRandR failed to get CrtcInfo, can't get monitor info.\n");
       return;
@@ -444,6 +476,8 @@
 
    /* init xrandr info to defaults */
    s->xrandr_available = 0;
+   s->xrandr_res_count = 0;
+   s->xrandr_res = NULL;
    s->xrandr_output_count = 0;
    s->xrandr_outputs = NULL;
 
@@ -494,21 +528,27 @@
 
 static void _al_xsys_xrandr_exit(ALLEGRO_SYSTEM_XGLX *s)
 {
-   int i;
+   // int i;
    ALLEGRO_DEBUG("xfullscreen: XRandR exiting.\n");
-
-   for (i = 0; i < s->xrandr_output_count; i++) {
+   
+   // for (i = 0; i < s->xrandr_output_count; i++) {
    //   XRRFreeOutputInfo(s->xrandr_outputs[i]);
-   }
+   // }
 
+   // for (i = 0; i < s->xrandr_res_count; i++) {
+   //    XRRFreeScreenResources(s->xrandr_res[i]);
+   // }
+
    ALLEGRO_DEBUG("xfullscreen: XRRFreeScreenResources\n");
    //if (s->xrandr_res)
    //   XRRFreeScreenResources(s->xrandr_res);
 
    al_free(s->xrandr_outputs);
-   al_free(s->xrandr_stored_modes);
-
+   al_free(s->xrandr_res);
+   
    s->xrandr_available = 0;
+   s->xrandr_res_count = 0;
+   s->xrandr_res = NULL;
    s->xrandr_output_count = 0;
    s->xrandr_outputs = NULL;
 
@@ -556,12 +596,15 @@
    mode_idx = _al_xglx_fullscreen_select_mode(s, d->xscreen, w, h, format, refresh_rate);
    if (mode_idx == -1)
       return false;
-
+   
    if (!XF86VidModeSwitchToMode(s->gfxdisplay, d->xscreen, s->xfvm_screen[d->xscreen].modes[mode_idx])) {
       ALLEGRO_ERROR("xfullscreen: XF86VidModeSwitchToMode failed\n");
       return false;
    }
 
+   /* scroll to origin, so our view is in the right place */
+   XF86VidModeSetViewPort(s->gfxdisplay, d->xscreen, 0, 0);
+
    return true;
 }
 
Index: src/x/xdisplay.c
===================================================================
--- src/x/xdisplay.c	(revision 14233)
+++ src/x/xdisplay.c	(working copy)
@@ -254,12 +254,19 @@
 
    _al_mutex_lock(&system->lock);
 
-   if (adapter >= ScreenCount(system->x11display)) {
+   /* XXX Can't do this. adapter is a virtual allegro screen which is NOT
+    * related in any way to the X Screen id.
+    * Worked arround the glXGetFBConfigs crash in a different way.
+    * We may want to separate dpy->xscreen from the "adapter"
+    * if the glx config stuff really needs the proper X screen
+    * in separate X Screen mode.
+    */
+   //if (adapter >= ScreenCount(system->x11display)) {
       /* Fail early, as glXGetFBConfigs may crash otherwise. */
-      ALLEGRO_DEBUG("Requested display adapter more than ScreenCount.\n");
-      _al_mutex_unlock(&system->lock);
-      return NULL;
-   }
+   //   ALLEGRO_DEBUG("Requested display adapter more than ScreenCount.\n");
+   //   _al_mutex_unlock(&system->lock);
+   //   return NULL;
+   //}
 
    ALLEGRO_DISPLAY_XGLX *d = al_malloc(sizeof *d);
    ALLEGRO_DISPLAY *display = (void*)d;
@@ -408,7 +415,11 @@
     * window when switching to fullscreen it will use the same
     * monitor (with the MetaCity version I'm using here right now).
     */
-   if ((display->flags & ALLEGRO_FULLSCREEN_WINDOW) || (display->flags & ALLEGRO_FULLSCREEN)) {
+   /* XXX why does this check for ALLEGR)_FULLSCREEN?
+    * Its causing the window to be created at the original mode size,
+    * which then causes scrolling in xf86vm mode
+    */
+   if ((display->flags & ALLEGRO_FULLSCREEN_WINDOW) /*|| (display->flags & ALLEGRO_FULLSCREEN)*/) {
       ALLEGRO_INFO("Toggling fullscreen flag for %d x %d window.\n",
          display->w, display->h);
       reset_size_hints(display);
