Index: /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	(revision 20432)
+++ /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	(revision 20433)
@@ -66,4 +66,7 @@
 }
 #endif /* VBOX_SECURELABEL */
+
+static SDL_Surface *gWMIcon;                    /**< the application icon */
+static RTNATIVETHREAD gSdlNativeThread;         /**< the SDL thread */
 
 //
@@ -83,5 +86,6 @@
  * @param iFixedHeight   fixed SDL height (-1 means not set)
  */
-VBoxSDLFB::VBoxSDLFB(bool fFullscreen, bool fResizable, bool fShowSDLConfig,
+VBoxSDLFB::VBoxSDLFB(uint32_t uScreenId,
+                     bool fFullscreen, bool fResizable, bool fShowSDLConfig,
                      bool fKeepHostRes, uint32_t u32FixedWidth,
                      uint32_t u32FixedHeight, uint32_t u32FixedBPP)
@@ -94,5 +98,10 @@
 #endif
 
+    mScreenId       = uScreenId;
     mScreen         = NULL;
+#ifdef VBOX_WITH_SDL13
+    mWindow         = 0;
+    mTexture        = 0;
+#endif
     mSurfVRAM       = NULL;
     mfInitialized   = false;
@@ -105,5 +114,4 @@
     mFixedSDLHeight = u32FixedHeight;
     mFixedSDLBPP    = u32FixedBPP;
-    mDefaultSDLBPP  = 32;
     mCenterXOffset  = 0;
     mCenterYOffset  = 0;
@@ -122,11 +130,39 @@
     mLabelOffs      = 0;
 #endif
-    mWMIcon         = NULL;
-
-    /* memorize the thread that inited us, that's the SDL thread */
-    mSdlNativeThread = RTThreadNativeSelf();
 
     rc = RTCritSectInit(&mUpdateLock);
     AssertMsg(rc == VINF_SUCCESS, ("Error from RTCritSectInit!\n"));
+
+    resizeGuest();
+    Assert(mScreen);
+    mfInitialized = true;
+}
+
+VBoxSDLFB::~VBoxSDLFB()
+{
+    LogFlow(("VBoxSDLFB::~VBoxSDLFB\n"));
+    if (mSurfVRAM)
+    {
+        SDL_FreeSurface(mSurfVRAM);
+        mSurfVRAM = NULL;
+    }
+    mScreen = NULL;
+
+#ifdef VBOX_SECURELABEL
+    if (mLabelFont)
+        pTTF_CloseFont(mLabelFont);
+    if (pTTF_Quit)
+        pTTF_Quit();
+#endif
+
+    RTCritSectDelete(&mUpdateLock);
+}
+
+void VBoxSDLFB::init(bool fShowSDLConfig)
+{
+    LogFlow(("VBoxSDLFB::init\n"));
+
+    /* memorize the thread that inited us, that's the SDL thread */
+    gSdlNativeThread = RTThreadNativeSelf();
 
 #ifdef RT_OS_WINDOWS
@@ -143,5 +179,5 @@
     RTEnvSet("SDL_VIDEO_X11_DGAMOUSE", "0");
 #endif
-    rc = SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE);
+    int rc = SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE);
     if (rc != 0)
     {
@@ -154,14 +190,6 @@
     if (videoInfo)
     {
-        switch (videoInfo->vfmt->BitsPerPixel)
-        {
-            case 16: mDefaultSDLBPP = 16; break;
-            case 24: mDefaultSDLBPP = 24; break;
-            default:
-            case 32: mDefaultSDLBPP = 32; break;
-        }
-
         /* output what SDL is capable of */
-        if (mfShowSDLConfig)
+        if (fShowSDLConfig)
             RTPrintf("SDL capabilities:\n"
                      "  Hardware surface support:                    %s\n"
@@ -193,24 +221,29 @@
     if (12320 == g_cbIco64x01)
     {
-        mWMIcon = SDL_AllocSurface(SDL_SWSURFACE, 64, 64, 24, 0xff, 0xff00, 0xff0000, 0);
+        gWMIcon = SDL_AllocSurface(SDL_SWSURFACE, 64, 64, 24, 0xff, 0xff00, 0xff0000, 0);
         /** @todo make it as simple as possible. No PNM interpreter here... */
-        if (mWMIcon)
+        if (gWMIcon)
         {
-            memcpy(mWMIcon->pixels, g_abIco64x01+32, g_cbIco64x01-32);
-            SDL_WM_SetIcon(mWMIcon, NULL);
+            memcpy(gWMIcon->pixels, g_abIco64x01+32, g_cbIco64x01-32);
+            SDL_WM_SetIcon(gWMIcon, NULL);
         }
     }
-
-    resizeGuest();
-    Assert(mScreen);
-    mfInitialized = true;
-}
-
-VBoxSDLFB::~VBoxSDLFB()
-{
-    LogFlow(("VBoxSDLFB::~VBoxSDLFB\n"));
-    RTCritSectDelete(&mUpdateLock);
-}
-
+}
+
+/**
+ * Terminate SDL
+ *
+ * @remarks must be called from the SDL thread!
+ */
+void VBoxSDLFB::uninit()
+{
+    AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
+    SDL_QuitSubSystem(SDL_INIT_VIDEO);
+    if (gWMIcon)
+    {
+        SDL_FreeSurface(gWMIcon);
+        gWMIcon = NULL;
+    }
+}
 
 /**
@@ -280,9 +313,5 @@
         return E_INVALIDARG;
 
-    if (mSurfVRAM)
-    {
-        *address = (BYTE *) mSurfVRAM->pixels;
-    }
-    else
+    if (!mSurfVRAM)
     {
         /* That's actually rather bad. */
@@ -290,4 +319,6 @@
         return E_FAIL;
     }
+
+    *address = (BYTE *) mSurfVRAM->pixels;
     LogFlow(("VBoxSDL::GetAddress returning %p\n", *address));
     return S_OK;
@@ -425,4 +456,5 @@
     SDL_Event event;
     event.type       = SDL_USEREVENT;
+    event.user.code  = mScreenId;
     event.user.type  = SDL_USER_EVENT_UPDATERECT;
     // 16 bit is enough for coordinates
@@ -502,4 +534,5 @@
     event.type       = SDL_USEREVENT;
     event.user.type  = SDL_USER_EVENT_RESIZE;
+    event.user.code  = mScreenId;
 
     /* Try multiple times if necessary */
@@ -593,5 +626,5 @@
 {
     LogFlowFunc (("mGuestXRes: %d, mGuestYRes: %d\n", mGuestXRes, mGuestYRes));
-    AssertMsg(mSdlNativeThread == RTThreadNativeSelf(),
+    AssertMsg(gSdlNativeThread == RTThreadNativeSelf(),
               ("Wrong thread! SDL is not threadsafe!\n"));
 
@@ -643,8 +676,8 @@
     if (mUsesGuestVRAM)
     {
-
         /* Create a source surface from guest VRAM. */
         mSurfVRAM = SDL_CreateRGBSurfaceFrom(mPtrVRAM, mGuestXRes, mGuestYRes, mBitsPerPixel,
                                              mBytesPerLine, Rmask, Gmask, Bmask, Amask);
+        LogRel(("mSurfVRAM from guest %d x %d\n", mGuestXRes,  mGuestYRes));
     }
     else
@@ -653,4 +686,5 @@
         mSurfVRAM = SDL_CreateRGBSurface(SDL_SWSURFACE, mGuestXRes, mGuestYRes, mBitsPerPixel,
                                          Rmask, Gmask, Bmask, Amask);
+        LogRel(("mSurfVRAM from SDL %d x %d\n", mGuestXRes,  mGuestYRes));
     }
     LogFlow(("VBoxSDL:: created VRAM surface %p\n", mSurfVRAM));
@@ -751,4 +785,78 @@
     mTopOffset = 0;
 
+#if defined(VBOX_WITH_SDL13)
+    int sdlWindowFlags = SDL_WINDOW_SHOWN;
+    if (mfResizable)
+        sdlWindowFlags |= SDL_WINDOW_RESIZABLE;
+    if (!mWindow)
+    {
+        SDL_DisplayMode desktop_mode;
+        int x = 40 + mScreenId * 20;
+        int y = 40 + mScreenId * 15;
+
+        SDL_GetDesktopDisplayMode(&desktop_mode);
+        /* create new window */
+       
+        char szTitle[64];
+        RTStrPrintf(szTitle, sizeof(szTitle), "SDL window %d", mScreenId);
+        mWindow = SDL_CreateWindow(szTitle, x, y,
+                                   newWidth, newHeight, sdlWindowFlags);
+        if (SDL_CreateRenderer(mWindow, -1,
+                               SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD) < 0)
+            AssertReleaseFailed();
+
+        SDL_GetRendererInfo(&mRenderInfo);
+
+        mTexture = SDL_CreateTexture(desktop_mode.format,
+                                     SDL_TEXTUREACCESS_STREAMING, newWidth, newHeight);
+        if (!mTexture)
+            AssertReleaseFailed();
+    }
+    else
+    {
+        int w, h;
+        uint32_t format;
+        int access;
+
+        /* resize current window */
+        SDL_GetWindowSize(mWindow, &w, &h);
+
+        if (w != (int)newWidth || h != (int)newHeight)
+            SDL_SetWindowSize(mWindow, newWidth, newHeight);
+
+        SDL_QueryTexture(mTexture, &format, &access, &w, &h);
+        SDL_SelectRenderer(mWindow);
+        SDL_DestroyTexture(mTexture);
+        mTexture = SDL_CreateTexture(format, access, newWidth, newHeight);
+        if (!mTexture)
+            AssertReleaseFailed();
+    }
+
+    void *pixels;
+    int pitch;
+    int w, h, bpp;
+    uint32_t Rmask, Gmask, Bmask, Amask;
+    uint32_t format;
+
+    if (SDL_QueryTexture(mTexture, &format, NULL, &w, &h) < 0)
+        AssertReleaseFailed();
+
+    if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask))
+        AssertReleaseFailed();
+
+    if (SDL_QueryTexturePixels(mTexture, &pixels, &pitch) == 0)
+    {
+        mScreen = SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch,
+                                           Rmask, Gmask, Bmask, Amask);
+    }
+    else
+    {
+        mScreen = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
+        AssertReleaseFailed();
+    }
+
+    SDL_SetClipRect(mScreen, NULL);
+
+#else
     /*
      * Now set the screen resolution and get the surface pointer
@@ -756,4 +864,5 @@
      */
     mScreen = SDL_SetVideoMode(newWidth, newHeight, 0, sdlFlags);
+#endif
 #ifdef VBOX_SECURELABEL
     /*
@@ -816,5 +925,5 @@
 {
 #ifdef VBOXSDL_WITH_X11
-    AssertMsg(mSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
+    AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
 #endif
     Assert(mScreen);
@@ -822,5 +931,5 @@
     if (!mScreen || !mSurfVRAM)
         return;
-
+    
     /* the source and destination rectangles */
     SDL_Rect srcRect;
@@ -880,7 +989,4 @@
     dstRect.h = RT_MAX(0, h - yCutoffGuest);
 
-    //RTPrintf("y = %d h = %d mapped to srcY %d srcH %d mapped to dstY = %d dstH %d (guestrel: %d, mLabelHeight: %d, mTopOffset: %d)\n",
-    //         y, h, srcRect.y, srcRect.h, dstRect.y, dstRect.h, fGuestRelative, mLabelHeight, mTopOffset);
-
     /*
      * Now we just blit
@@ -888,6 +994,15 @@
     SDL_BlitSurface(mSurfVRAM, &srcRect, mScreen, &dstRect);
     /* hardware surfaces don't need update notifications */
+#if defined(VBOX_WITH_SDL13)
+    AssertRelease(mScreen->flags & SDL_PREALLOC);
+    SDL_SelectRenderer(mWindow);
+    SDL_DirtyTexture(mTexture, 1, &dstRect);
+    AssertRelease(mRenderInfo.flags & SDL_RENDERER_PRESENTCOPY);
+    SDL_RenderCopy(mTexture, &dstRect, &dstRect);
+    SDL_RenderPresent();
+#else
     if ((mScreen->flags & SDL_HWSURFACE) == 0)
         SDL_UpdateRect(mScreen, dstRect.x, dstRect.y, dstRect.w, dstRect.h);
+#endif
 
 #ifdef VBOX_SECURELABEL
@@ -904,15 +1019,9 @@
 void VBoxSDLFB::repaint()
 {
-    AssertMsg(mSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
+    AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
     LogFlow(("VBoxSDLFB::repaint\n"));
     update(0, 0, mScreen->w, mScreen->h, false /* fGuestRelative */);
 }
 
-bool VBoxSDLFB::getFullscreen()
-{
-    LogFlow(("VBoxSDLFB::getFullscreen\n"));
-    return mfFullscreen;
-}
-
 /**
  * Toggle fullscreen mode
@@ -922,5 +1031,5 @@
 void VBoxSDLFB::setFullscreen(bool fFullscreen)
 {
-    AssertMsg(mSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
+    AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
     LogFlow(("VBoxSDLFB::SetFullscreen: fullscreen: %d\n", fFullscreen));
     mfFullscreen = fFullscreen;
@@ -965,26 +1074,4 @@
 }
 
-/**
- * Returns the current x offset of the start of the guest screen
- *
- * @returns current x offset in pixels
- */
-int VBoxSDLFB::getXOffset()
-{
-    /* there can only be an offset for centering */
-    return mCenterXOffset;
-}
-
-/**
- * Returns the current y offset of the start of the guest screen
- *
- * @returns current y offset in pixels
- */
-int VBoxSDLFB::getYOffset()
-{
-    /* we might have a top offset and a center offset */
-    return mTopOffset + mCenterYOffset;
-}
-
 #ifdef VBOX_SECURELABEL
 /**
@@ -1051,5 +1138,5 @@
 {
 #ifdef VBOXSDL_WITH_X11
-    AssertMsg(mSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
+    AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
 #endif
     /* only when the function is present */
@@ -1086,32 +1173,4 @@
 }
 #endif /* VBOX_SECURELABEL */
-
-/**
- * Terminate SDL
- *
- * @remarks must be called from the SDL thread!
- */
-void VBoxSDLFB::uninit()
-{
-    AssertMsg(mSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
-    if (mSurfVRAM)
-    {
-        SDL_FreeSurface(mSurfVRAM);
-        mSurfVRAM = NULL;
-    }
-    SDL_QuitSubSystem(SDL_INIT_VIDEO);
-#ifdef VBOX_SECURELABEL
-    if (mLabelFont)
-        pTTF_CloseFont(mLabelFont);
-    if (pTTF_Quit)
-        pTTF_Quit();
-#endif
-    mScreen = NULL;
-    if (mWMIcon)
-    {
-        SDL_FreeSurface(mWMIcon);
-        mWMIcon = NULL;
-    }
-}
 
 // IFramebufferOverlay
Index: /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h	(revision 20432)
+++ /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h	(revision 20433)
@@ -42,5 +42,5 @@
 extern DECLSPEC void (SDLCALL *pTTF_Quit)(void);
 }
-#endif /* VBOX_SECURELABEL */
+#endif /* VBOX_SECURELABEL && !VBOX_WITH_SDL13 */
 
 class VBoxSDLFBOverlay;
@@ -50,8 +50,12 @@
 {
 public:
-    VBoxSDLFB(bool fFullscreen = false, bool fResizable = true, bool fShowSDLConfig = false,
+    VBoxSDLFB(uint32_t uScreenId,
+              bool fFullscreen = false, bool fResizable = true, bool fShowSDLConfig = false,
               bool fKeepHostRes = false, uint32_t u32FixedWidth = ~(uint32_t)0,
               uint32_t u32FixedHeight = ~(uint32_t)0, uint32_t u32FixedBPP = ~(uint32_t)0);
     virtual ~VBoxSDLFB();
+
+    static void init(bool fShowSDLConfig);
+    static void uninit();
 
 #ifdef RT_OS_WINDOWS
@@ -118,11 +122,16 @@
     void update(int x, int y, int w, int h, bool fGuestRelative);
     void repaint();
-    bool getFullscreen();
     void setFullscreen(bool fFullscreen);
-    int  getXOffset();
-    int  getYOffset();
     void getFullscreenGeometry(uint32_t *width, uint32_t *height);
+    uint32_t getScreenId() { return mScreenId; }
     uint32_t getGuestXRes() { return mGuestXRes; }
     uint32_t getGuestYRes() { return mGuestYRes; }
+    int32_t getOriginX() { return mOriginX; }
+    int32_t getOriginY() { return mOriginY; }
+    int32_t getXOffset() { return mCenterXOffset; }
+    int32_t getYOffset() { return mCenterYOffset; }
+#ifdef VBOX_WITH_SDL13
+    bool hasWindow(SDL_WindowID id) { return mScreen && mWindow == id; }
+#endif
 #ifdef VBOX_SECURELABEL
     int  initSecureLabel(uint32_t height, char *font, uint32_t pointsize, uint32_t labeloffs);
@@ -131,14 +140,23 @@
     void paintSecureLabel(int x, int y, int w, int h, bool fForce);
 #endif
-    void uninit();
     void setWinId(uint64_t winId) { mWinId = winId; }
+    void setOrigin(int32_t axOrigin, int32_t ayOrigin) { mOriginX = axOrigin; mOriginY = ayOrigin; }
+    bool getFullscreen() { return mfFullscreen; }
 
 private:
-    /** the sdl thread */
-    RTNATIVETHREAD mSdlNativeThread;
     /** current SDL framebuffer pointer (also includes screen width/height) */
     SDL_Surface *mScreen;
+#ifdef VBOX_WITH_SDL13
+    /** the SDL window */
+    SDL_WindowID mWindow;
+    /** the texture */
+    SDL_TextureID mTexture;
+    /** render info */
+    SDL_RendererInfo mRenderInfo;
+#endif
     /** false if constructor failed */
     bool mfInitialized;
+    /** the screen number of this framebuffer */
+    uint32_t mScreenId;
     /** maximum possible screen width in pixels (~0 = no restriction) */
     uint32_t mMaxScreenWidth;
@@ -149,4 +167,6 @@
     /** current guest screen height in pixels */
     ULONG mGuestYRes;
+    int32_t mOriginX;
+    int32_t mOriginY;
     /** fixed SDL screen width (~0 = not set) */
     uint32_t mFixedSDLWidth;
@@ -155,6 +175,4 @@
     /** fixed SDL bits per pixel (~0 = not set) */
     uint32_t mFixedSDLBPP;
-    /** default BPP */
-    uint32_t mDefaultSDLBPP;
     /** Y offset in pixels, i.e. guest-nondrawable area at the top */
     uint32_t mTopOffset;
@@ -189,4 +207,5 @@
     /** secure label offset from the top of the secure label */
     uint32_t mLabelOffs;
+
 #endif
 #ifdef RT_OS_WINDOWS
@@ -201,7 +220,4 @@
     BOOL mUsesGuestVRAM;
     BOOL mfSameSizeRequested;
-
-    /** the application Icon */
-    SDL_Surface *mWMIcon;
 };
 
Index: /trunk/src/VBox/Frontends/VBoxSDL/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/Makefile.kmk	(revision 20432)
+++ /trunk/src/VBox/Frontends/VBoxSDL/Makefile.kmk	(revision 20433)
@@ -66,6 +66,10 @@
 
 VBoxSDL_DEFS       =
-ifdef VBOX_WITH_SECURELABEL
- VBoxSDL_DEFS     += VBOX_SECURELABEL
+ifdef VBOX_WITH_SDL13
+ VBoxSDL_DEFS     += VBOX_WITH_SDL13
+else
+ ifdef VBOX_WITH_SECURELABEL
+  VBoxSDL_DEFS    += VBOX_SECURELABEL
+ endif
 endif
 ifdef VBOX_WITH_VRDP
Index: /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	(revision 20432)
+++ /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	(revision 20433)
@@ -148,5 +148,5 @@
 static void    InputGrabStart(void);
 static void    InputGrabEnd(void);
-static void    SendMouseEvent(int dz, int button, int down);
+static void    SendMouseEvent(VBoxSDLFB *fb, int dz, int button, int down);
 static void    UpdateTitlebar(TitlebarMode mode, uint32_t u32User = 0);
 static void    SetPointerShape(const PointerShapeChangeData *data);
@@ -158,4 +158,7 @@
 static int     WaitSDLEvent(SDL_Event *event);
 static void    SetFullscreen(bool enable);
+#ifdef VBOX_WITH_SDL13
+static VBoxSDLFB * getFbFromWinId(SDL_WindowID id);
+#endif
 
 
@@ -188,5 +191,5 @@
 static BOOL gfGuestScrollLockPressed = FALSE;
 static BOOL gfACPITerm = FALSE;
-static BOOL gfXCursorEnabled = TRUE;
+static BOOL gfXCursorEnabled = FALSE;
 static int  gcGuestNumLockAdaptions = 2;
 static int  gcGuestCapsLockAdaptions = 2;
@@ -206,5 +209,7 @@
 static ComPtr<IProgress> gProgress;
 
-static VBoxSDLFB  *gpFrameBuffer = NULL;
+static unsigned   gcMonitors = 1;
+static VBoxSDLFB  *gpFramebuffer[64];
+//static VBoxSDLFB  *gpFramebufferCurrent = NULL;
 static SDL_Cursor *gpDefaultCursor = NULL;
 #ifdef VBOXSDL_WITH_X11
@@ -215,10 +220,12 @@
 #endif
 static SDL_Cursor *gpCustomCursor = NULL;
+#ifndef VBOX_WITH_SDL13
 static WMcursor   *gpCustomOrigWMcursor = NULL;
+#endif
 static SDL_Cursor *gpOffCursor = NULL;
 static SDL_TimerID gSdlResizeTimer = NULL;
 static SDL_TimerID gSdlQuitTimer = NULL;
 
-#ifdef VBOXSDL_WITH_X11
+#if defined(VBOXSDL_WITH_X11) && !defined(VBOX_WITH_SDL13)
 static SDL_SysWMinfo gSdlInfo;
 #endif
@@ -1961,23 +1968,36 @@
 #endif
 
-    // create our SDL framebuffer instance
-    gpFrameBuffer = new VBoxSDLFB(fFullscreen, fResizable, fShowSDLConfig, false,
-                                  fixedWidth, fixedHeight, fixedBPP);
-
-    if (!gpFrameBuffer)
-    {
-        RTPrintf("Error: could not create framebuffer object!\n");
-        goto leave;
+    /* static initialization of the SDL stuff */
+    VBoxSDLFB::init(fShowSDLConfig);
+
+    gMachine->COMGETTER(MonitorCount)(&gcMonitors);
+    if (gcMonitors > 64)
+        gcMonitors = 64;
+
+    for (unsigned i = 0; i < gcMonitors; i++)
+    {
+        // create our SDL framebuffer instance
+        gpFramebuffer[i] = new VBoxSDLFB(i, fFullscreen, fResizable, fShowSDLConfig, false,
+                                         fixedWidth, fixedHeight, fixedBPP);
+
+        if (!gpFramebuffer[i])
+        {
+            RTPrintf("Error: could not create framebuffer object!\n");
+            goto leave;
+        }
     }
 
 #ifdef VBOX_WIN32_UI
-    gpFrameBuffer->setWinId(winId);
-#endif
-
-    if (!gpFrameBuffer->initialized())
-        goto leave;
-    gpFrameBuffer->AddRef();
-    if (fFullscreen)
-        SetFullscreen(true);
+    gpFramebuffer[0]->setWinId(winId);
+#endif
+
+    for (unsigned i = 0; i < gcMonitors; i++)
+    {
+        if (!gpFramebuffer[i]->initialized())
+            goto leave;
+        gpFramebuffer[i]->AddRef();
+        if (fFullscreen)
+            SetFullscreen(true);
+    }
 
 #ifdef VBOX_SECURELABEL
@@ -2011,5 +2031,5 @@
             rcVBox = RTLdrGetSymbol(gLibrarySDL_ttf, "TTF_Quit", (void**)&pTTF_Quit);
         if (RT_SUCCESS(rcVBox))
-            rcVBox = gpFrameBuffer->initSecureLabel(SECURE_LABEL_HEIGHT, secureLabelFontFile, secureLabelPointSize, secureLabelFontOffs);
+            rcVBox = gpFramebuffer[0]->initSecureLabel(SECURE_LABEL_HEIGHT, secureLabelFontFile, secureLabelPointSize, secureLabelFontOffs);
         if (RT_FAILURE(rcVBox))
         {
@@ -2024,6 +2044,6 @@
          * Now update the label
          */
-        gpFrameBuffer->setSecureLabelColor(secureLabelColorFG, secureLabelColorBG);
-        gpFrameBuffer->setSecureLabelText(labelUtf8.raw());
+        gpFramebuffer[0]->setSecureLabelColor(secureLabelColorFG, secureLabelColorBG);
+        gpFramebuffer[0]->setSecureLabelText(labelUtf8.raw());
     }
 #endif
@@ -2037,11 +2057,19 @@
 #endif
 
-    // register our framebuffer
-    rc = gDisplay->SetFramebuffer(VBOX_VIDEO_PRIMARY_SCREEN, gpFrameBuffer);
-    if (rc != S_OK)
-    {
-        RTPrintf("Error: could not register framebuffer object!\n");
-        goto leave;
-    }
+    for (unsigned i = 0; i < gcMonitors; i++)
+    {
+        // register our framebuffer
+        rc = gDisplay->SetFramebuffer(i, gpFramebuffer[i]);
+        if (rc != S_OK)
+        {
+            RTPrintf("Error: could not register framebuffer object!\n");
+            goto leave;
+        }
+        IFramebuffer *dummyFb;
+        int xOrigin, yOrigin;
+        rc = gDisplay->GetFramebuffer(i, &dummyFb, &xOrigin, &yOrigin);
+        gpFramebuffer[i]->setOrigin(xOrigin, yOrigin);
+    }
+//    gpFramebufferCurrent = gpFramebuffer[0];
 
     // register a callback for global events
@@ -2144,14 +2172,14 @@
     gpDefaultCursor = SDL_GetCursor();
 
-#ifdef VBOXSDL_WITH_X11
+#if !defined(VBOX_WITH_SDL13)
+# if defined(VBOXSDL_WITH_X11)
     /* Get Window Manager info. We only need the X11 display. */
     SDL_VERSION(&gSdlInfo.version);
     if (!SDL_GetWMInfo(&gSdlInfo))
-    {
         RTPrintf("Error: could not get SDL Window Manager info -- no Xcursor support!\n");
-        gfXCursorEnabled = FALSE;
-    }
-
-# if !defined(VBOX_WITHOUT_XCURSOR)
+    else
+        gfXCursorEnabled = TRUE;
+
+#  if !defined(VBOX_WITHOUT_XCURSOR)
     /* SDL uses its own (plain) default cursor. Use the left arrow cursor instead which might look
      * much better if a mouse cursor theme is installed. */
@@ -2162,6 +2190,6 @@
         SDL_SetCursor(gpDefaultCursor);
     }
-# endif
-#endif /* VBOXSDL_WITH_X11 */
+#  endif
+# endif /* VBOXSDL_WITH_X11 */
 
     /* create a fake empty cursor */
@@ -2172,4 +2200,5 @@
         gpCustomCursor->wm_cursor = NULL;
     }
+#endif /* !VBOX_WITH_SDL13 */
 
     /*
@@ -2276,7 +2305,12 @@
                     {
                         LogFlow(("SDL_USER_EVENT_RESIZE\n"));
-                        gpFrameBuffer->resizeGuest();
+                        IFramebuffer *dummyFb;
+                        int xOrigin, yOrigin;
+                        gpFramebuffer[event.user.code]->resizeGuest();
+                        /* update xOrigin, yOrigin -> mouse */
+                        rc = gDisplay->GetFramebuffer(event.user.code, &dummyFb, &xOrigin, &yOrigin);
+                        gpFramebuffer[event.user.code]->setOrigin(xOrigin, yOrigin);
                         /* notify the display that the resize has been completed */
-                        gDisplay->ResizeCompleted(0);
+                        gDisplay->ResizeCompleted(event.user.code);
                         break;
                     }
@@ -2400,10 +2434,33 @@
              * The screen needs to be repainted.
              */
+#ifdef VBOX_WITH_SDL13
+            case SDL_WINDOWEVENT:
+            {
+                switch (event.window.event)
+                {
+                    case SDL_WINDOWEVENT_EXPOSED:
+                    {
+                        VBoxSDLFB *fb = getFbFromWinId(event.window.windowID);
+                        if (fb)
+                            fb->repaint();
+                        break;
+                    }
+                    case SDL_WINDOWEVENT_FOCUS_GAINED:
+                    {
+                        /* XXX hack */
+//                        gpFramebufferCurrent = getFbFromWinId(event.window.windowID);
+                        break;
+                    }
+                    default:
+                        break;
+                }
+            }
+#else 
             case SDL_VIDEOEXPOSE:
             {
-                /// @todo that somehow doesn't seem to work!
-                gpFrameBuffer->repaint();
+                gpFramebuffer[0]->repaint();
                 break;
             }
+#endif
 
             /*
@@ -2543,5 +2600,11 @@
                 if (gfGrabbed || UseAbsoluteMouse())
                 {
-                    SendMouseEvent(0, 0, 0);
+                    VBoxSDLFB *fb;
+#ifdef VBOX_WITH_SDL13
+                    fb = getFbFromWinId(event.motion.windowID);
+#else
+                    fb = NULL;
+#endif
+                    SendMouseEvent(fb, 0, 0, 0);
                 }
                 break;
@@ -2596,5 +2659,11 @@
                     }
 
-                    SendMouseEvent(dz, event.type == SDL_MOUSEBUTTONDOWN, bev->button);
+                    VBoxSDLFB *fb;
+#ifdef VBOX_WITH_SDL13
+                    fb = getFbFromWinId(event.button.windowID);
+#else
+                    fb = NULL;
+#endif
+                    SendMouseEvent(fb, dz, event.type == SDL_MOUSEBUTTONDOWN, bev->button);
                 }
                 break;
@@ -2671,6 +2740,6 @@
                         x, y, w, h));
 
-                Assert(gpFrameBuffer);
-                gpFrameBuffer->update(x, y, w, h, true /* fGuestRelative */);
+                Assert(gpFramebuffer[event.user.code]);
+                gpFramebuffer[event.user.code]->update(x, y, w, h, true /* fGuestRelative */);
 
                 #undef DECODEX
@@ -2705,7 +2774,12 @@
             {
                 LogFlow(("SDL_USER_EVENT_RESIZE\n"));
-                gpFrameBuffer->resizeGuest();
+                IFramebuffer *dummyFb;
+                int xOrigin, yOrigin;
+                gpFramebuffer[event.user.code]->resizeGuest();
+                /* update xOrigin, yOrigin -> mouse */
+                rc = gDisplay->GetFramebuffer(event.user.code, &dummyFb, &xOrigin, &yOrigin);
+                gpFramebuffer[event.user.code]->setOrigin(xOrigin, yOrigin);
                 /* notify the display that the resize has been completed */
-                gDisplay->ResizeCompleted(0);
+                gDisplay->ResizeCompleted(event.user.code);
                 break;
             }
@@ -2759,5 +2833,5 @@
                  * Now update the label
                  */
-                gpFrameBuffer->setSecureLabelText(labelUtf8.raw());
+                gpFramebuffer[0]->setSecureLabelText(labelUtf8.raw());
                 break;
             }
@@ -2853,16 +2927,17 @@
     }
 
+#ifndef VBOX_WITH_SDL13
     /* restore the default cursor and free the custom one if any */
     if (gpDefaultCursor)
     {
-#ifdef VBOXSDL_WITH_X11
+# ifdef VBOXSDL_WITH_X11
         Cursor pDefaultTempX11Cursor = *(Cursor*)gpDefaultCursor->wm_cursor;
         *(Cursor*)gpDefaultCursor->wm_cursor = gpDefaultOrigX11Cursor;
-#endif /* VBOXSDL_WITH_X11 */
+# endif /* VBOXSDL_WITH_X11 */
         SDL_SetCursor(gpDefaultCursor);
-#if defined(VBOXSDL_WITH_X11) && !defined(VBOX_WITHOUT_XCURSOR)
+# if defined(VBOXSDL_WITH_X11) && !defined(VBOX_WITHOUT_XCURSOR)
         if (gfXCursorEnabled)
             XFreeCursor(gSdlInfo.info.x11.display, pDefaultTempX11Cursor);
-#endif /* VBOXSDL_WITH_X11 && !VBOX_WITHOUT_XCURSOR */
+# endif /* VBOXSDL_WITH_X11 && !VBOX_WITHOUT_XCURSOR */
     }
 
@@ -2874,17 +2949,21 @@
         if (pCustomTempWMCursor)
         {
-#if defined (RT_OS_WINDOWS)
+# if defined (RT_OS_WINDOWS)
             ::DestroyCursor(*(HCURSOR *) pCustomTempWMCursor);
-#elif defined (VBOXSDL_WITH_X11) && !defined (VBOX_WITHOUT_XCURSOR)
+# elif defined (VBOXSDL_WITH_X11) && !defined (VBOX_WITHOUT_XCURSOR)
             if (gfXCursorEnabled)
                 XFreeCursor(gSdlInfo.info.x11.display, *(Cursor *) pCustomTempWMCursor);
-#endif /* VBOXSDL_WITH_X11 && !VBOX_WITHOUT_XCURSOR */
+# endif /* VBOXSDL_WITH_X11 && !VBOX_WITHOUT_XCURSOR */
             free(pCustomTempWMCursor);
         }
     }
+#endif
 
     LogFlow(("Releasing mouse, keyboard, vrdpserver, display, console...\n"));
     if (gDisplay)
-        gDisplay->SetFramebuffer(VBOX_VIDEO_PRIMARY_SCREEN, NULL);
+    {
+        for (unsigned i = 0; i < gcMonitors; i++)
+            gDisplay->SetFramebuffer(0, NULL);
+    }
     gMouse = NULL;
     gKeyboard = NULL;
@@ -2895,10 +2974,17 @@
     gProgress = NULL;
     // we can only uninitialize SDL here because it is not threadsafe
-    if (gpFrameBuffer)
-    {
-        LogFlow(("Releasing framebuffer...\n"));
-        gpFrameBuffer->uninit();
-        gpFrameBuffer->Release();
-    }
+
+    for (unsigned i = 0; i < gcMonitors; i++)
+    {      
+        if (gpFramebuffer[i])
+        {
+            LogFlow(("Releasing framebuffer...\n"));
+            gpFramebuffer[i]->Release();
+            gpFramebuffer[i] = NULL;
+        }
+    }
+
+    VBoxSDLFB::uninit();
+
 #ifdef VBOX_SECURELABEL
     /* must do this after destructing the framebuffer */
@@ -3137,4 +3223,127 @@
 
 #ifdef VBOXSDL_WITH_X11
+# ifdef VBOX_WITH_SDL13
+
+    switch (ev->keysym.sym)
+    {
+        case SDLK_ESCAPE:           return 0x01;
+        case SDLK_EXCLAIM:
+        case SDLK_1:                return 0x02;
+        case SDLK_AT:
+        case SDLK_2:                return 0x03;
+        case SDLK_HASH:
+        case SDLK_3:                return 0x04;
+        case SDLK_DOLLAR:
+        case SDLK_4:                return 0x05;
+        /* % */
+        case SDLK_5:                return 0x06;
+        case SDLK_CARET:
+        case SDLK_6:                return 0x07;
+        case SDLK_AMPERSAND:
+        case SDLK_7:                return 0x08;
+        case SDLK_ASTERISK:
+        case SDLK_8:                return 0x09;
+        case SDLK_LEFTPAREN:
+        case SDLK_9:                return 0x0a;
+        case SDLK_RIGHTPAREN:
+        case SDLK_0:                return 0x0b;
+        case SDLK_UNDERSCORE:
+        case SDLK_MINUS:            return 0x0c;
+        case SDLK_PLUS:             return 0x0d;
+        case SDLK_BACKSPACE:        return 0x0e;
+        case SDLK_TAB:              return 0x0f;
+        case SDLK_q:                return 0x10;
+        case SDLK_w:                return 0x11;
+        case SDLK_e:                return 0x12;
+        case SDLK_r:                return 0x13;
+        case SDLK_t:                return 0x14;
+        case SDLK_y:                return 0x15;
+        case SDLK_u:                return 0x16;
+        case SDLK_i:                return 0x17;
+        case SDLK_o:                return 0x18;
+        case SDLK_p:                return 0x19;
+        case SDLK_RETURN:           return 0x1c;
+        case SDLK_KP_ENTER:         return 0x1c | 0x100;
+        case SDLK_LCTRL:            return 0x1d;
+        case SDLK_RCTRL:            return 0x1d | 0x100;
+        case SDLK_a:                return 0x1e;
+        case SDLK_s:                return 0x1f;
+        case SDLK_d:                return 0x20;
+        case SDLK_f:                return 0x21;
+        case SDLK_g:                return 0x22;
+        case SDLK_h:                return 0x23;
+        case SDLK_j:                return 0x24;
+        case SDLK_k:                return 0x25;
+        case SDLK_l:                return 0x26;
+        case SDLK_COLON:            return 0x27;
+        case SDLK_QUOTEDBL:
+        case SDLK_QUOTE:            return 0x28;
+        case SDLK_BACKQUOTE:        return 0x29;
+        case SDLK_LSHIFT:           return 0x2a;
+        case SDLK_z:                return 0x2c;
+        case SDLK_x:                return 0x2d;
+        case SDLK_c:                return 0x2e;
+        case SDLK_v:                return 0x2f;
+        case SDLK_b:                return 0x30;
+        case SDLK_n:                return 0x31;
+        case SDLK_m:                return 0x32;
+        case SDLK_LESS:             return 0x33;
+        case SDLK_GREATER:          return 0x34;
+        case SDLK_KP_DIVIDE:        /*??*/
+        case SDLK_QUESTION:         return 0x35;
+        case SDLK_RSHIFT:           return 0x36;
+        case SDLK_KP_MULTIPLY:
+        case SDLK_PRINT:            return 0x37; /* fixme */
+        case SDLK_LALT:             return 0x38;
+        case SDLK_MODE: /* alt gr*/
+        case SDLK_RALT:             return 0x38 | 0x100;
+        case SDLK_SPACE:            return 0x39;
+        case SDLK_CAPSLOCK:         return 0x3a;
+        case SDLK_F1:               return 0x3b;
+        case SDLK_F2:               return 0x3c;
+        case SDLK_F3:               return 0x3d;
+        case SDLK_F4:               return 0x3e;
+        case SDLK_F5:               return 0x3f;
+        case SDLK_F6:               return 0x40;
+        case SDLK_F7:               return 0x41;
+        case SDLK_F8:               return 0x42;
+        case SDLK_F9:               return 0x43;
+        case SDLK_F10:              return 0x44;
+        case SDLK_PAUSE:            return 0x45; /* not right */
+        case SDLK_NUMLOCK:          return 0x45;
+        case SDLK_SCROLLOCK:        return 0x46;
+        case SDLK_KP7:              return 0x47;
+        case SDLK_HOME:             return 0x47 | 0x100;
+        case SDLK_KP8:              return 0x48;
+        case SDLK_UP:               return 0x48 | 0x100;
+        case SDLK_KP9:              return 0x49;
+        case SDLK_PAGEUP:           return 0x49 | 0x100;
+        case SDLK_KP_MINUS:         return 0x4a;
+        case SDLK_KP4:              return 0x4b;
+        case SDLK_LEFT:             return 0x4b | 0x100;
+        case SDLK_KP5:              return 0x4c;
+        case SDLK_KP6:              return 0x4d;
+        case SDLK_RIGHT:            return 0x4d | 0x100;
+        case SDLK_KP_PLUS:          return 0x4e;
+        case SDLK_KP1:              return 0x4f;
+        case SDLK_END:              return 0x4f | 0x100;
+        case SDLK_KP2:              return 0x50;
+        case SDLK_DOWN:             return 0x50 | 0x100;
+        case SDLK_KP3:              return 0x51;
+        case SDLK_PAGEDOWN:         return 0x51 | 0x100;
+        case SDLK_KP0:              return 0x52;
+        case SDLK_INSERT:           return 0x52 | 0x100;
+        case SDLK_KP_PERIOD:        return 0x53;
+        case SDLK_DELETE:           return 0x53 | 0x100;
+        case SDLK_SYSREQ:           return 0x54;
+        case SDLK_F11:              return 0x57;
+        case SDLK_F12:              return 0x58;
+        case SDLK_F13:              return 0x5b;
+        case SDLK_F14:              return 0x5c;
+        case SDLK_F15:              return 0x5d;
+        case SDLK_MENU:             return 0x5d | 0x100;
+        default:
+                                    return 0;
+    }
     // workaround for SDL keyboard translation issues on Linux
     // keycodes > 0x100 are sent as 0xe0 keycode
@@ -3143,4 +3352,6 @@
     // work on other hosts or on other servers on Linux hosts.
     // For a more general approach, see the Wine code in the GUI.
+
+# else
     static const uint16_t x_keycode_to_pc_keycode[61] =
     {
@@ -3290,5 +3501,5 @@
         keycode -= 8;
     }
-#ifdef RT_OS_LINUX
+# ifdef RT_OS_LINUX
     else if (keycode < 158 && guseEvdevKeymap)
     {
@@ -3296,5 +3507,5 @@
         keycode = evdev_keycode_to_pc_keycode[keycode - 97];
     }
-#endif
+# endif
     else if (keycode < 158)
     {
@@ -3316,5 +3527,5 @@
         keycode = 0;
     }
-
+# endif
 #elif defined(RT_OS_DARWIN)
     /* This is derived partially from SDL_QuartzKeys.h and partially from testing. */
@@ -3491,5 +3702,5 @@
 
 #elif RT_OS_OS2
-        keycode = Keyevent2KeycodeFallback(ev);
+    keycode = Keyevent2KeycodeFallback(ev);
 #endif /* RT_OS_DARWIN */
     return keycode;
@@ -3525,5 +3736,5 @@
 static void ProcessKey(SDL_KeyboardEvent *ev)
 {
-#if defined(DEBUG) || defined(VBOX_WITH_STATISTICS)
+#if (defined(DEBUG) || defined(VBOX_WITH_STATISTICS)) && !defined(VBOX_WITH_SDL13)
     if (gMachineDebugger && ev->type == SDL_KEYDOWN)
     {
@@ -3791,5 +4002,9 @@
     SDL_WM_GrabInput(SDL_GRAB_ON);
     // dummy read to avoid moving the mouse
-    SDL_GetRelativeMouseState(NULL, NULL);
+    SDL_GetRelativeMouseState(
+#ifdef VBOX_WITH_SDL13
+                              0,
+#endif
+                              NULL, NULL);
     gfGrabbed = TRUE;
     UpdateTitlebar(TITLEBAR_NORMAL);
@@ -3816,8 +4031,17 @@
  * @param dz  Relative mouse wheel movement
  */
-static void SendMouseEvent(int dz, int down, int button)
+static void SendMouseEvent(VBoxSDLFB *fb, int dz, int down, int button)
 {
     int  x, y, state, buttons;
     bool abs;
+
+#ifdef VBOX_WITH_SDL13
+    if (!fb)
+    {
+        SDL_GetMouseState(0, &x, &y);
+        RTPrintf("MouseEvent: Cannot find fb mouse = %d,%d\n", x, y);
+        return;
+    }
+#endif
 
     /*
@@ -3835,10 +4059,21 @@
 
     /* only used if abs == TRUE */
-    int  xMin = gpFrameBuffer->getXOffset();
-    int  yMin = gpFrameBuffer->getYOffset();
-    int  xMax = xMin + (int)gpFrameBuffer->getGuestXRes();
-    int  yMax = yMin + (int)gpFrameBuffer->getGuestYRes();
-
-    state = abs ? SDL_GetMouseState(&x, &y) : SDL_GetRelativeMouseState(&x, &y);
+    int  xOrigin = fb->getOriginX();
+    int  yOrigin = fb->getOriginY();
+    int  xMin = fb->getXOffset() + xOrigin;
+    int  yMin = fb->getYOffset() + yOrigin;
+    int  xMax = xMin + (int)fb->getGuestXRes();
+    int  yMax = yMin + (int)fb->getGuestYRes();
+
+    state = abs ? SDL_GetMouseState(
+#ifdef VBOX_WITH_SDL13
+                                    0,
+#endif
+                                    &x, &y)
+                : SDL_GetRelativeMouseState(
+#ifdef VBOX_WITH_SDL13
+                                            0,
+#endif
+                                            &x, &y);
 
     /*
@@ -3855,4 +4090,7 @@
     if (abs)
     {
+        x += xOrigin;
+        y += yOrigin;
+
         /*
          * Check if the mouse event is inside the guest area. This solves the
@@ -3937,6 +4175,6 @@
              * or state it in PutMouseEventAbsolute() docs?
              */
-            gMouse->PutMouseEventAbsolute(x + 1 - xMin,
-                                          y + 1 - yMin,
+            gMouse->PutMouseEventAbsolute(x + 1 - xMin + xOrigin,
+                                          y + 1 - yMin + yOrigin,
                                           dz, buttons | tmp_button);
         }
@@ -3956,6 +4194,6 @@
          * or state it in PutMouseEventAbsolute() docs?
          */
-        gMouse->PutMouseEventAbsolute(x + 1 - xMin,
-                                      y + 1 - yMin,
+        gMouse->PutMouseEventAbsolute(x + 1 - xMin + xOrigin,
+                                      y + 1 - yMin + yOrigin,
                                       dz, buttons);
     }
@@ -4521,4 +4759,5 @@
                 }
 
+#ifndef VBOX_WITH_SDL13
                 Cursor cur = XcursorImageLoadCursor (gSdlInfo.info.x11.display, img);
                 Assert (cur);
@@ -4546,4 +4785,5 @@
                     ok = true;
                 }
+#endif
             }
             XcursorImageDestroy (img);
@@ -4630,5 +4870,5 @@
             if (machineState == MachineState_Running)
                 gConsole->Pause();
-            SetFullscreen(!gpFrameBuffer->getFullscreen());
+            SetFullscreen(!gpFramebuffer[0]->getFullscreen());
             if (machineState == MachineState_Running)
                 gConsole->Resume();
@@ -4882,7 +5122,11 @@
         int rc = SDL_PushEvent(event);
         RTSemEventSignal(g_EventSemSDLEvents);
+#ifdef VBOX_WITH_SDL13
+        if (rc == 1)
+#else
         if (rc == 0)
+#endif
             return 0;
-        Log(("PushSDLEventForSure: waiting for 2ms\n"));
+        Log(("PushSDLEventForSure: waiting for 2ms (rc = %d)\n", rc));
         RTThreadSleep(2);
     }
@@ -4900,8 +5144,14 @@
 {
     int rc = SDL_PushEvent(event);
+#ifdef VBOX_WITH_SDL13
+    bool fSuccess = (rc == 1);
+#else
+    bool fSuccess = (rc == 0);
+#endif
+
     RTSemEventSignal(g_EventSemSDLEvents);
-    AssertMsg(!rc, ("SDL_PushEvent returned SDL error\n"));
+    AssertMsg(fSuccess, ("SDL_PushEvent returned SDL error\n"));
     /* A global counter is faster than SDL_PeepEvents() */
-    if (!rc)
+    if (fSuccess)
         ASMAtomicIncS32(&g_cNotifyUpdateEventsPending);
     /* In order to not flood the SDL event queue, yield the CPU or (if there are already many
@@ -4924,5 +5174,5 @@
 static void SetFullscreen(bool enable)
 {
-    if (enable == gpFrameBuffer->getFullscreen())
+    if (enable == gpFramebuffer[0]->getFullscreen())
         return;
 
@@ -4932,5 +5182,5 @@
          * The old/default way: SDL will resize the host to fit the guest screen resolution.
          */
-        gpFrameBuffer->setFullscreen(enable);
+        gpFramebuffer[0]->setFullscreen(enable);
     }
     else
@@ -4944,7 +5194,7 @@
         {
             /* switch to fullscreen */
-            gmGuestNormalXRes = gpFrameBuffer->getGuestXRes();
-            gmGuestNormalYRes = gpFrameBuffer->getGuestYRes();
-            gpFrameBuffer->getFullscreenGeometry(&NewWidth, &NewHeight);
+            gmGuestNormalXRes = gpFramebuffer[0]->getGuestXRes();
+            gmGuestNormalYRes = gpFramebuffer[0]->getGuestYRes();
+            gpFramebuffer[0]->getFullscreenGeometry(&NewWidth, &NewHeight);
         }
         else
@@ -4956,5 +5206,5 @@
         if (NewWidth != 0 && NewHeight != 0)
         {
-            gpFrameBuffer->setFullscreen(enable);
+            gpFramebuffer[0]->setFullscreen(enable);
             gfIgnoreNextResize = TRUE;
             gDisplay->SetVideoModeHint(NewWidth, NewHeight, 0, 0);
@@ -4962,2 +5212,13 @@
     }
 }
+
+#ifdef VBOX_WITH_SDL13
+static VBoxSDLFB * getFbFromWinId(SDL_WindowID id)
+{
+    for (unsigned i = 0; i < gcMonitors; i++)
+        if (gpFramebuffer[i]->hasWindow(id))
+            return gpFramebuffer[i];
+
+    return NULL;
+}
+#endif
