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
 };
 
@@ -101,7 +106,8 @@
    /* Driver specifics. */
 
    Window window;
-   int xscreen; /* TODO: what is this? something with multi-monitor? */
+   int xscreen; /* X Screen ID */
+   int adapter; /* allegro virtual adapter id/index */
    GLXWindow glxwindow;
    GLXContext context;
    Atom wm_delete_window_atom;
@@ -184,6 +190,8 @@
 void _al_xglx_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *info);
 int _al_xglx_get_num_video_adapters(ALLEGRO_SYSTEM_XGLX *s);
 
+int _al_xglx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s);
+int _al_xglx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter);
 
 /* glx_config */
 void _al_xglx_config_select_visual(ALLEGRO_DISPLAY_XGLX *glx);
Index: src/x/xfullscreen.c
===================================================================
--- src/x/xfullscreen.c	(revision 14233)
+++ src/x/xfullscreen.c	(working copy)
@@ -14,6 +14,8 @@
     void (*get_display_offset)(ALLEGRO_SYSTEM_XGLX *, int, int *, int *);
     int (*get_num_adapters)(ALLEGRO_SYSTEM_XGLX *);
     void (*get_monitor_info)(ALLEGRO_SYSTEM_XGLX *, int, ALLEGRO_MONITOR_INFO *);
+    int (*get_default_adapter)(ALLEGRO_SYSTEM_XGLX *);
+    int (*get_xscreen)(ALLEGRO_SYSTEM_XGLX *, int);
 };
 
 
@@ -21,7 +23,66 @@
 static _ALLEGRO_XGLX_MMON_INTERFACE mmon_interface;
 
 
+/* generic multi-head x */
+static int _al_xsys_mheadx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s)
+{
+   int i;
+ 
+   ALLEGRO_DEBUG("mhead get default adapter\n");
+   
+   if(ScreenCount(s->x11display) == 1)
+      return 0;
 
+   _al_mutex_lock(&s->lock);
+   
+   Window focus;
+   int revert_to = 0;
+   XGetInputFocus(s->x11display, &focus, &revert_to);
+   XWindowAttributes attr;
+   Screen *focus_screen;
+   
+   XGetWindowAttributes(s->x11display, focus, &attr);
+   focus_screen = attr.screen;
+   
+   for(i = 0; i < ScreenCount(s->x11display); i++) {
+      if(ScreenOfDisplay(s->x11display, i) == focus_screen) {
+         _al_mutex_unlock(&s->lock);
+         return i;
+      }
+   }
+   
+   _al_mutex_unlock(&s->lock);
+   return 0;
+}
+
+/* in pure multi-head mode, allegro's virtual adapters map directly to X Screens. */
+static int _al_xsys_mheadx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter)
+{
+   (void)s;
+   ALLEGRO_DEBUG("mhead get screen %i\n", adapter);
+   return adapter;
+}
+
+static void _al_xsys_get_active_window_center(ALLEGRO_SYSTEM_XGLX *s, int *x, int *y)
+{
+   Window focus;
+   int revert_to = 0;
+   
+   _al_mutex_lock(&s->lock);
+   
+   XGetInputFocus(s->x11display, &focus, &revert_to);
+   XWindowAttributes attr;
+   
+   XGetWindowAttributes(s->x11display, focus, &attr);
+
+   _al_mutex_unlock(&s->lock);
+   
+   /* check the center of the window with focus
+    * might be a bit more useful than just checking the top left */
+   *x = (attr.x + (attr.x + attr.width) / 2);
+   *y = (attr.y + (attr.y + attr.height) / 2);  
+}
+
 /*---------------------------------------------------------------------------
  *
  * Xinerama
@@ -101,6 +162,31 @@
    mi->y2 = mi->y1 + s->xinerama_screen_info[adapter].height;
 }
 
+static int _al_xsys_xinerama_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s)
+{
+   int center_x = 0, center_y = 0;
+   _al_xsys_get_active_window_center(s, &center_x, &center_y);
+   
+   int i;
+   for(i = 0; i < s->xinerama_screen_count; i++) {
+      if(center_x >= s->xinerama_screen_info[i].x_org && center_x <= s->xinerama_screen_info[i].x_org + s->xinerama_screen_info[i].width &&
+         center_y >= s->xinerama_screen_info[i].y_org && center_y <= s->xinerama_screen_info[i].y_org + s->xinerama_screen_info[i].height)
+      {
+         return i;
+      }
+   }
+   
+   return 0;
+}
+
+/* similar to multi-head x, but theres only one X Screen, so we return 0 always */
+static int _al_xsys_xinerama_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter)
+{
+   (void)s;
+   (void)adapter;
+   return 0;
+}
+
 #endif /* ALLEGRO_XWINDOWS_WITH_XINERAMA */
 
 
@@ -117,16 +203,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 +227,94 @@
    /* 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;
+   }
 
-         ALLEGRO_DEBUG("xrandr: got crtc %d.\n", ncrtc);
+   s->xrandr_res_count = ScreenCount(s->x11display);
+   
+   s->xrandr_output_count = 0; // just in case
+   for(xscr = 0; xscr < ScreenCount(s->x11display); xscr++) {
 
-         if (crtc_info->noutput > 0) {
-            XRROutputInfo **new_output_info = s->xrandr_outputs;
-            int new_output_count = s->xrandr_output_count + crtc_info->noutput;
+      res = s->xrandr_res[xscr] = XRRGetScreenResources (s->x11display, XRootWindow(s->x11display, xscr));
+      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;
+            }
 
-            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);
+            ALLEGRO_DEBUG("xrandr: got crtc %d.\n", ncrtc);
 
-               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;
+            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;
+
+               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 +325,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 +336,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 +369,12 @@
 {
    int mode_idx = -1;
    XRRModeInfo *mi = NULL;
-
-   if (d->xscreen < 0 || d->xscreen >= s->xrandr_output_count)
+   XRRScreenResources *res = NULL;
+   
+   if (d->adapter < 0 || d->adapter >= s->xrandr_output_count)
       return false;
-
-   XRRModeInfo *cur_mode = s->xrandr_stored_modes[d->xscreen];
+   
+   XRRModeInfo *cur_mode = s->xrandr_outputs[d->adapter]->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));
@@ -271,23 +388,25 @@
       ALLEGRO_DEBUG("xrandr: new mode: %dx%d@%d old mode: %dx%d@%d.\n", w,h,refresh, cur_mode->width, cur_mode->height, cur_refresh_rate);
    }
    
-   mode_idx = _al_xglx_fullscreen_select_mode(s, d->xscreen, w, h, format, refresh);
+   mode_idx = _al_xglx_fullscreen_select_mode(s, d->adapter, w, h, format, refresh);
    if (mode_idx == -1) {
       ALLEGRO_DEBUG("xrandr: mode %dx%d@%d not found.\n", w,h,refresh);
       return false;
    }
 
-   mi = &s->xrandr_res->modes[mode_idx];
+   res = s->xrandr_res[s->xrandr_outputs[d->adapter]->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->adapter]->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->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
@@ -313,28 +432,27 @@
 
 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];
+            break;
          }
       }
 
       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 +463,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 +510,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;
@@ -399,6 +519,7 @@
 
       *x = crtc_info->x;
       *y = crtc_info->y;
+      ALLEGRO_DEBUG("xrandr: display offset: %ix%i.\n", *x, *y);
       XRRFreeCrtcInfo(crtc_info);
    }
 }
@@ -423,7 +544,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;
@@ -437,6 +559,46 @@
    XRRFreeCrtcInfo(crtc_info);
 }
 
+static int _al_xsys_xrandr_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s)
+{
+   ALLEGRO_DEBUG("xrandr get default adapter\n");
+   
+   /* if we have more than one res, means we're in hybrid multi-head X + xrandr mode
+    * use multi-head X code to get default adapter */
+   if(s->xrandr_res_count > 1)
+      return _al_xsys_mheadx_get_default_adapter(s);
+   
+   int center_x = 0, center_y = 0;
+   _al_xsys_get_active_window_center(s, &center_x, &center_y);
+   
+   int i;
+   for(i = 0; i < s->xrandr_output_count; i++) {
+      XRRScreenResources *res = s->xrandr_res[s->xrandr_outputs[i]->res_id];
+      XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(s->x11display, res, s->xrandr_outputs[i]->output->crtc);
+      if(center_x >= (int)crtc_info->x && center_x <= (int)(crtc_info->x + crtc_info->width) &&
+         center_y >= (int)crtc_info->y && center_y <= (int)(crtc_info->y + crtc_info->height))
+      {
+         ALLEGRO_DEBUG("xrandr selected default: %i\n", i);
+         return i;
+      }
+   }
+   
+   ALLEGRO_DEBUG("xrandr selected fallback: 0\n");
+   
+   return 0;
+}
+
+static int _al_xsys_xrandr_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter)
+{
+   ALLEGRO_DEBUG("xrandr get xscreen for adapter %i\n", adapter);
+   if(s->xrandr_res_count > 1)
+      return _al_xsys_mheadx_get_xscreen(s, adapter);
+   
+   ALLEGRO_DEBUG("xrandr selected default xscreen (ScreenCount:%i res_count:%i)\n", ScreenCount(s->x11display), s->xrandr_res_count);
+   /* should always only be one X Screen with normal xrandr */
+   return 0;
+}
+
 static void _al_xsys_xrandr_init(ALLEGRO_SYSTEM_XGLX *s)
 {
    int event_base = 0;
@@ -444,6 +606,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;
 
@@ -487,6 +651,8 @@
       mmon_interface.get_display_offset    = _al_xsys_xrandr_get_display_offset;
       mmon_interface.get_num_adapters      = _al_xsys_xrandr_get_num_adapters;
       mmon_interface.get_monitor_info      = _al_xsys_xrandr_get_monitor_info;
+      mmon_interface.get_default_adapter   = _al_xsys_xrandr_get_default_adapter;
+      mmon_interface.get_xscreen           = _al_xsys_xrandr_get_xscreen;
    }
 
    _al_mutex_unlock(&s->lock);
@@ -494,21 +660,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;
 
@@ -553,15 +725,18 @@
 {
    int mode_idx = -1;
 
-   mode_idx = _al_xglx_fullscreen_select_mode(s, d->xscreen, w, h, format, refresh_rate);
+   mode_idx = _al_xglx_fullscreen_select_mode(s, d->adapter, 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])) {
+   
+   if (!XF86VidModeSwitchToMode(s->gfxdisplay, d->xscreen, s->xfvm_screen[d->adapter].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;
 }
 
@@ -684,6 +859,32 @@
    mi->y2 = xwa.height;
 }
 
+static int _al_xsys_xfvm_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s)
+{
+   ALLEGRO_DEBUG("xfvm get default adapter\n");
+   
+#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA
+   if (s->xinerama_available) {
+      return _al_xsys_xinerama_get_default_adapter(s);
+   }
+#endif
+
+   return _al_xsys_mheadx_get_default_adapter(s);
+}
+
+static int _al_xsys_xfvm_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter)
+{
+   ALLEGRO_DEBUG("xfvm get xscreen for adapter %i\n", adapter);
+   
+#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA
+   if (s->xinerama_available) {
+      return _al_xsys_xinerama_get_xscreen(s, adapter);
+   }
+#endif
+
+   return _al_xsys_mheadx_get_xscreen(s, adapter);
+}
+
 static void _al_xsys_xfvm_init(ALLEGRO_SYSTEM_XGLX *s)
 {
    int event_base = 0;
@@ -756,6 +957,8 @@
          mmon_interface.get_display_offset    = _al_xsys_xfvm_get_display_offset;
          mmon_interface.get_num_adapters      = _al_xsys_xfvm_get_num_adapters;
          mmon_interface.get_monitor_info      = _al_xsys_xfvm_get_monitor_info;
+         mmon_interface.get_default_adapter   = _al_xsys_xfvm_get_default_adapter;
+         mmon_interface.get_xscreen           = _al_xsys_xfvm_get_xscreen;
       }
    }
 
@@ -810,6 +1013,11 @@
       return true;
 
    /* Shouldn't we avoid initing any more of these than we need? */
+   /* nope, no way to tell which is going to be used on any given system
+    * this way, xrandr always overrides everything else should it succeed.
+    * And when xfvm is chosen, it needs xinerama inited,
+    * incase there are multiple screens.
+    */
 
 #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA
    _al_xsys_xinerama_init(s);
@@ -851,19 +1059,13 @@
    s->mmon_interface_inited = false;
 }
 
-static int get_default_adapter(void)
-{
-   /* FIXME: the default adapter is not necessarily 0. */
-   return 0;
-}
-
 int _al_xglx_get_num_display_modes(ALLEGRO_SYSTEM_XGLX *s, int adapter)
 {
    if (!init_mmon_interface(s))
       return 0;
 
    if (adapter == -1)
-      adapter = get_default_adapter();
+      adapter = _al_xglx_get_default_adapter(s);
 
    if (!mmon_interface.get_num_display_modes) {
       if (adapter != 0)
@@ -882,7 +1084,7 @@
       return NULL;
 
    if (adapter == -1)
-      adapter = get_default_adapter();
+      adapter = _al_xglx_get_default_adapter(s);
 
    if (!mmon_interface.get_display_mode) {
       mode->width = DisplayWidth(s->x11display, DefaultScreen(s->x11display));
@@ -907,7 +1109,7 @@
       return -1;
    
    if (adapter == -1)
-      adapter = get_default_adapter();
+      adapter = _al_xglx_get_default_adapter(s);
 
    n = _al_xglx_get_num_display_modes(s, adapter);
    if (!n)
@@ -1033,8 +1235,32 @@
    return mmon_interface.get_num_adapters(s);
 }
 
+int _al_xglx_get_default_adapter(ALLEGRO_SYSTEM_XGLX *s)
+{
+   if(s->mmon_interface_inited)
+      return mmon_interface.get_default_adapter(s);
 
+   if(ScreenCount(s->x11display) > 1) {
+      if(init_mmon_interface(s))
+         return mmon_interface.get_default_adapter(s);
+   }
+   
+   return 0;
+}
 
+int _al_xglx_get_xscreen(ALLEGRO_SYSTEM_XGLX *s, int adapter)
+{
+   if(s->mmon_interface_inited)
+      return mmon_interface.get_xscreen(s, adapter);
+   
+   if(ScreenCount(s->x11display) > 1) {
+      if(init_mmon_interface(s))
+         return mmon_interface.get_xscreen(s, adapter);
+   }
+   
+   return 0;
+}
+
 #define X11_ATOM(x)  XInternAtom(x11, #x, False);
 
 /* Note: The system mutex must be locked (exactly once) before
Index: src/x/xdisplay.c
===================================================================
--- src/x/xdisplay.c	(revision 14233)
+++ src/x/xdisplay.c	(working copy)
@@ -241,7 +241,7 @@
 {
    ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
    int adapter = al_get_new_display_adapter();
-
+   
    if (system->x11display == NULL) {
       ALLEGRO_WARN("Not connected to X server.\n");
       return NULL;
@@ -254,13 +254,6 @@
 
    _al_mutex_lock(&system->lock);
 
-   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_DISPLAY_XGLX *d = al_malloc(sizeof *d);
    ALLEGRO_DISPLAY *display = (void*)d;
    ALLEGRO_OGL_EXTRAS *ogl = al_malloc(sizeof *ogl);
@@ -282,11 +275,19 @@
    // FIXME: default? Is this the right place to set this?
    display->flags |= ALLEGRO_OPENGL;
 
-   // store our initial screen, used by fullscreen and glx visual code
-   d->xscreen = adapter;
-   if (d->xscreen < 0)
-      d->xscreen = DefaultScreen(system->x11display);
+   // store our initial virtual adapter, used by fullscreen and positioning code
+   d->adapter = adapter;
+   if(d->adapter < 0)
+      d->adapter = _al_xglx_get_default_adapter(system);
 
+   ALLEGRO_DEBUG("xdpy: selected adapter %i\n", d->adapter);
+   
+   // store or initial X Screen, used by window creation, fullscreen, and glx visual code
+   // XXX Really needs to change when window is moved...
+   d->xscreen = _al_xglx_get_xscreen(system, d->adapter);
+   
+   ALLEGRO_DEBUG("xdpy: selected xscreen %i\n", d->xscreen);
+   
    d->is_mapped = false;
    _al_cond_init(&d->mapped);
 
@@ -408,7 +409,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 ALLEGRO_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);
