diff -Naur original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
--- original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	2009-02-16 16:53:42.000000000 +0100
+++ VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	2009-03-07 17:14:38.000000000 +0100
@@ -66,6 +66,14 @@
 }
 #endif /* VBOX_SECURELABEL */
 
+static int npot(int input)
+{
+    int pot = 1;
+    while(pot < input) pot <<= 1;
+
+    return pot;
+}
+
 //
 // Constructor / destructor
 //
@@ -83,8 +91,9 @@
  * @param iFixedHeight   fixed SDL height (-1 means not set)
  */
 VBoxSDLFB::VBoxSDLFB(bool fFullscreen, bool fResizable, bool fShowSDLConfig,
-                     bool fKeepHostRes, uint32_t u32FixedWidth,
-                     uint32_t u32FixedHeight, uint32_t u32FixedBPP)
+                     bool fKeepHostRes, bool fOpenGL, bool fStretch,
+                     uint32_t u32FixedWidth, uint32_t u32FixedHeight,
+                     uint32_t u32FixedBPP)
 {
     int rc;
     LogFlow(("VBoxSDLFB::VBoxSDLFB\n"));
@@ -123,6 +132,18 @@
 #endif
     mWMIcon         = NULL;
 
+#ifdef VBOX_OPENGL
+    mfOpenGL        = fOpenGL;
+    mfStretch       = fStretch;
+    mTextures[0]    = 0;
+    mTextures[1]    = 0;
+
+    mfGuestDisplayList = 0;
+
+    mGuestVirtualXRes = 0;
+    mGuestVirtualYRes = 0;
+#endif
+
     /* memorize the thread that inited us, that's the SDL thread */
     mSdlNativeThread = RTThreadNativeSelf();
 
@@ -735,6 +756,105 @@
 
     /* now adjust the SDL resolution */
     resizeSDL();
+
+#ifdef VBOX_OPENGL
+
+    if (mfOpenGL)
+    {
+        mfGuestDisplayList = glGenLists(1);
+        glNewList(mfGuestDisplayList, GL_COMPILE);
+
+        int texture_width  = npot(mGuestXRes);
+        int texture_height = npot(mGuestYRes);
+
+        /* Since our textures are probably bigger than our guest's resolution
+         * we need to calculate proper texture coordinates. */
+        float x_scale = float(double(mGuestXRes) / double(texture_width));
+        float y_scale = float(double(mGuestYRes) / double(texture_height));
+
+        int x0, y0, x1, y1;
+
+        mGuestVirtualXRes = mGuestXRes;
+        mGuestVirtualYRes = mGuestYRes;
+
+        /* There is no point in calculating all of that if the resolutions are the same. */
+        if (uint32_t(mScreen->w) == mGuestXRes && uint32_t(mScreen->h) == mGuestYRes)
+        {
+            x0 = 0;
+            x1 = mGuestXRes;
+            y0 = 0;
+            y1 = mGuestYRes;
+        }
+
+        /* We should center the display only if we aren't supposed to stretch it and it's smaller than our screen
+         * or at least one dimension matches.*/
+        else if ((mfStretch == false && uint32_t(mScreen->w) >= mGuestXRes && uint32_t(mScreen->h) >= mGuestYRes) ||
+                 (uint32_t(mScreen->w) == mGuestXRes || uint32_t(mScreen->h) == mGuestYRes))
+        {
+            int difference;
+            difference = mScreen->w - mGuestXRes;
+
+            /* If our guest's resolution is bigger than the screen we just
+             * fill the whole area. */
+            if (difference < 0) difference = 0;
+            x0 = difference / 2;
+            x1 = x0 + mGuestXRes;
+
+            /* Now we do the same for the height. */
+            difference = mScreen->h - mGuestYRes;
+            if (difference < 0) difference = 0;
+            y0 = difference / 2;
+            y1 = y0 + mGuestYRes;
+        }
+        else
+        {
+
+            double aspect = ((double)mGuestXRes) / ((double)mGuestYRes);
+
+            int guest_height = (int)((( double )mScreen->w) / aspect);
+            if (guest_height > mScreen->h)
+            {
+                int guest_width = (int)(aspect * ((double)mScreen->h));
+
+                x0 = (int)((mScreen->w - guest_width) / 2);
+                x1 = x0 + guest_width;
+                y0 = 0;
+                y1 = mScreen->h;
+            }
+            else
+            {
+                x0 = 0;
+                x1 = mScreen->w;
+                y0 = (int)((mScreen->h - guest_height) / 2);
+                y1 = y0 + guest_height;
+            }
+
+            mGuestVirtualXRes = x1 - x0;
+            mGuestVirtualYRes = y1 - y0;
+        }
+
+        mCenterXOffset = x0;
+        mCenterYOffset = y0;
+
+        #if 0 // This printf may come in handy if the code above would appear buggy.
+            printf( "Resolution has changed!\nhost: %dx%d\nguest: %dx%d\ntexture: %dx%d\ntexture coords: %f %f\n"
+                    "quad: %dx%d\nposition: %dx%d\nhost aspect: %f\nquest aspect: %f\n\n",
+                    mScreen->w, mScreen->h, mGuestXRes, mGuestYRes, texture_width, texture_height, x_scale, y_scale,
+                    x1 - x0, y1 - y0, x0, y0, ((double)mScreen->w) / ((double)mScreen->h), ((double)mGuestXRes) / ((double)mGuestYRes) );
+        #endif
+
+        glBegin(GL_QUADS);
+            glTexCoord2f(0.0f, 0.0f);       glVertex2i(x0, y1);
+            glTexCoord2f(0.0f, y_scale);    glVertex2i(x0, y0);
+            glTexCoord2f(x_scale, y_scale); glVertex2i(x1, y0);
+            glTexCoord2f(x_scale, 0.0f);    glVertex2i(x1, y1);
+        glEnd();
+
+        glEndList();
+    }
+
+#endif
+
 }
 
 /**
@@ -758,7 +878,17 @@
      * functions to blit from our system memory surface to the VRAM.
      * Therefore, SDL can take advantage of hardware acceleration.
      */
-    int sdlFlags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
+    int sdlFlags = 0;
+
+#ifdef VBOX_OPENGL
+    if (mfOpenGL == false)
+        sdlFlags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
+    else
+        sdlFlags = SDL_OPENGL;
+#else
+    sdlFlags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
+#endif
+
 #ifndef RT_OS_OS2 /* doesn't seem to work for some reason... */
     if (mfResizable)
         sdlFlags |= SDL_RESIZABLE;
@@ -817,6 +947,26 @@
     /* we don't have any extra space by default */
     mTopOffset = 0;
 
+#ifdef VBOX_OPENGL
+    if (mfOpenGL)
+    {
+        SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+        SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+        SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+        SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+        SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
+        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+        if (mScreen)
+        {
+            if (glIsTexture(mTextures[0]) == GL_TRUE) glDeleteTextures(1, &mTextures[0]);
+            if (glIsTexture(mTextures[1]) == GL_TRUE) glDeleteTextures(1, &mTextures[1]);
+            if (glIsList(mfGuestDisplayList) == GL_TRUE) glDeleteLists(mfGuestDisplayList, 1);
+        }
+    }
+#endif
+
     /*
      * Now set the screen resolution and get the surface pointer
      * @todo BPP is not supported!
@@ -862,8 +1012,78 @@
         resizeUI(mScreen->w, mScreen->h);
 #endif
         if (mfShowSDLConfig)
-            RTPrintf("Resized to %dx%d, screen surface type: %s\n", mScreen->w, mScreen->h,
-                     ((mScreen->flags & SDL_HWSURFACE) == 0) ? "software" : "hardware");
+        {
+            const char * type = 0;
+            if ((mScreen->flags & SDL_HWSURFACE) == 1) type = "hardware";
+            else if ((mScreen->flags & SDL_OPENGL) == 1) type = "opengl";
+            else type = "software";
+            RTPrintf("Resized to %dx%d, screen surface type: %s\n", mScreen->w, mScreen->h, type);
+        }
+
+#ifdef VBOX_OPENGL
+        if (mfOpenGL)
+        {
+            glViewport(0, 0, mScreen->w, mScreen->h);
+            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+            glClearDepth(1.0f);
+            glShadeModel(GL_FLAT);
+            glDisable(GL_BLEND);
+            glDisable(GL_DEPTH_TEST);
+            glDepthMask(GL_FALSE);
+
+            glMatrixMode(GL_PROJECTION);
+            glLoadIdentity();
+            glOrtho(0, mScreen->w, 0, mScreen->h, 1, -1);
+
+            glMatrixMode(GL_MODELVIEW);
+            glLoadIdentity();
+
+            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+            glColor3f(1.0f, 1.0f, 1.0f);
+
+            int texture_width  = npot(mGuestXRes);
+            int texture_height = npot(mGuestYRes);
+
+            glEnable(GL_TEXTURE_2D);
+            glGenTextures(1, &mTextures[0]);
+            glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+            glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+            switch( mBitsPerPixel )
+            {
+                case 32:
+                    glTexImage2D(GL_TEXTURE_2D, 0, 4, texture_width, texture_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
+                    break;
+                case 24:
+                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height, 0, GL_BGR,  GL_UNSIGNED_BYTE, 0);
+                case 16:
+                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, texture_width, texture_height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
+                    break;
+                default:
+                    break;
+            }
+
+#ifdef VBOX_SECURELABEL
+            /** @todo Since it's not open source I'm unable to code support for secure label. */
+
+            #if 0
+            if (fPaintLabel)
+            {
+                glGenTextures(1, &mTextures[1]);
+                glBindTexture(GL_TEXTURE_2D, mTextures[1]);
+                glTexImage2D(GL_TEXTURE_2D, 0, 4, texture_width, mLabelHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
+            }
+            #endif
+#endif
+
+        }
+#endif
+
     }
     repaint();
 }
@@ -949,13 +1169,47 @@
     //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
-     */
-    SDL_BlitSurface(mSurfVRAM, &srcRect, mScreen, &dstRect);
-    /* hardware surfaces don't need update notifications */
-    if ((mScreen->flags & SDL_HWSURFACE) == 0)
-        SDL_UpdateRect(mScreen, dstRect.x, dstRect.y, dstRect.w, dstRect.h);
+#ifdef VBOX_OPENGL
+    if (mfOpenGL == false)
+#endif
+    {
+        /*
+        * Now we just blit
+        */
+        SDL_BlitSurface(mSurfVRAM, &srcRect, mScreen, &dstRect);
+        /* hardware surfaces don't need update notifications */
+        if ((mScreen->flags & SDL_HWSURFACE) == 0)
+            SDL_UpdateRect(mScreen, dstRect.x, dstRect.y, dstRect.w, dstRect.h);
+    }
+
+#ifdef VBOX_OPENGL
+    else
+    {
+        glBindTexture(GL_TEXTURE_2D, mTextures[0]);
+
+        glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
+        glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
+        glPixelStorei(GL_UNPACK_ROW_LENGTH, mGuestXRes);
+
+        switch( mBitsPerPixel )
+        {
+            case 32:
+                glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, mSurfVRAM->pixels);
+                break;
+            case 24:
+                glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_BGR, GL_UNSIGNED_BYTE, mSurfVRAM->pixels);
+                break;
+            case 16:
+                glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, mSurfVRAM->pixels);
+                break;
+            default:
+                break;
+        }
+
+        glCallList(mfGuestDisplayList);
+        SDL_GL_SwapBuffers();
+    }
+#endif
 
 #ifdef VBOX_SECURELABEL
     if (fPaintLabel)
@@ -1053,6 +1307,38 @@
     return mTopOffset + mCenterYOffset;
 }
 
+/**
+ * Returns the current visible x resolution of the guest screen,
+ * that is - if the guest's framebuffer is stretched then it returns
+ * the resolution of that rectangle.
+ *
+ * @returns current visible x resolution
+ */
+uint32_t VBoxSDLFB::getGuestVirtualXRes()
+{
+#ifdef VBOX_OPENGL
+    if (mfOpenGL) return mGuestVirtualXRes;
+#endif
+
+    return mGuestXRes;
+}
+
+/**
+ * Returns the current visible y resolution of the guest screen,
+ * that is - if the guest's framebuffer is stretched then it returns
+ * the resolution of that rectangle.
+ *
+ * @returns current visible y resolution
+ */
+uint32_t VBoxSDLFB::getGuestVirtualYRes()
+{
+#ifdef VBOX_OPENGL
+    if (mfOpenGL) return mGuestVirtualYRes;
+#endif
+
+    return mGuestYRes;
+}
+
 #ifdef VBOX_SECURELABEL
 /**
  * Setup the secure labeling parameters
@@ -1127,29 +1413,42 @@
     {
         return;
     }
-    /* first fill the background */
-    SDL_Rect rect = {0, 0, (Uint16)mScreen->w, (Uint16)mLabelHeight};
-    SDL_FillRect(mScreen, &rect, SDL_MapRGB(mScreen->format,
-                                            (mSecureLabelColorBG & 0x00FF0000) >> 16,   /* red   */
-                                            (mSecureLabelColorBG & 0x0000FF00) >> 8,   /* green */
-                                            mSecureLabelColorBG & 0x000000FF)); /* blue  */
-
-    /* now the text */
-    if (mLabelFont != NULL && mSecureLabelText)
-    {
-        SDL_Color clrFg = {(mSecureLabelColorFG & 0x00FF0000) >> 16,
-                           (mSecureLabelColorFG & 0x0000FF00) >> 8,
-                           mSecureLabelColorFG & 0x000000FF, 0};
-        SDL_Surface *sText = (pTTF_RenderUTF8_Blended != NULL)
-                                 ? pTTF_RenderUTF8_Blended(mLabelFont, mSecureLabelText.raw(), clrFg)
-                                 : pTTF_RenderUTF8_Solid(mLabelFont, mSecureLabelText.raw(), clrFg);
-        rect.x = 10;
-        rect.y = mLabelOffs;
-        SDL_BlitSurface(sText, NULL, mScreen, &rect);
-        SDL_FreeSurface(sText);
+
+#ifdef VBOX_OPENGL
+    if (mfOpenGL == false)
+#endif
+    {
+        /* first fill the background */
+        SDL_Rect rect = {0, 0, (Uint16)mScreen->w, (Uint16)mLabelHeight};
+        SDL_FillRect(mScreen, &rect, SDL_MapRGB(mScreen->format,
+                                                (mSecureLabelColorBG & 0x00FF0000) >> 16,   /* red   */
+                                                (mSecureLabelColorBG & 0x0000FF00) >> 8,   /* green */
+                                                mSecureLabelColorBG & 0x000000FF)); /* blue  */
+
+        /* now the text */
+        if (mLabelFont != NULL && mSecureLabelText)
+        {
+            SDL_Color clrFg = {(mSecureLabelColorFG & 0x00FF0000) >> 16,
+                            (mSecureLabelColorFG & 0x0000FF00) >> 8,
+                            mSecureLabelColorFG & 0x000000FF, 0};
+            SDL_Surface *sText = (pTTF_RenderUTF8_Blended != NULL)
+                                    ? pTTF_RenderUTF8_Blended(mLabelFont, mSecureLabelText.raw(), clrFg)
+                                    : pTTF_RenderUTF8_Solid(mLabelFont, mSecureLabelText.raw(), clrFg);
+            rect.x = 10;
+            rect.y = mLabelOffs;
+            SDL_BlitSurface(sText, NULL, mScreen, &rect);
+            SDL_FreeSurface(sText);
+        }
+        /* make sure to update the screen */
+        SDL_UpdateRect(mScreen, 0, 0, mScreen->w, mLabelHeight);
+    }
+
+#ifdef VBOX_OPENGL
+    else
+    {
     }
-    /* make sure to update the screen */
-    SDL_UpdateRect(mScreen, 0, 0, mScreen->w, mLabelHeight);
+#endif
+
 }
 #endif /* VBOX_SECURELABEL */
 
@@ -1161,6 +1460,15 @@
 void VBoxSDLFB::uninit()
 {
     AssertMsg(mSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
+#ifdef VBOX_OPENGL
+    if (mfOpenGL)
+    {
+        if (glIsTexture(mTextures[0]) == GL_TRUE) glDeleteTextures(1, &mTextures[0]);
+        if (glIsTexture(mTextures[1]) == GL_TRUE) glDeleteTextures(1, &mTextures[1]);
+        if (glIsList(mfGuestDisplayList) == GL_TRUE) glDeleteLists(mfGuestDisplayList, 1);
+    }
+#endif
+
     if (mSurfVRAM)
     {
         SDL_FreeSurface(mSurfVRAM);
diff -Naur original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Framebuffer.h VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Framebuffer.h
--- original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Framebuffer.h	2009-02-16 16:53:42.000000000 +0100
+++ VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Framebuffer.h	2009-03-07 15:46:47.000000000 +0100
@@ -50,8 +50,9 @@
 {
 public:
     VBoxSDLFB(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);
+              bool fKeepHostRes = false, bool fOpenGL = false, bool fStretch = false,
+              uint32_t u32FixedWidth = ~(uint32_t)0, uint32_t u32FixedHeight = ~(uint32_t)0,
+              uint32_t u32FixedBPP = ~(uint32_t)0);
     virtual ~VBoxSDLFB();
 
 #ifdef RT_OS_WINDOWS
@@ -128,6 +129,8 @@
     void getFullscreenGeometry(uint32_t *width, uint32_t *height);
     uint32_t getGuestXRes() { return mGuestXRes; }
     uint32_t getGuestYRes() { return mGuestYRes; }
+    uint32_t getGuestVirtualXRes();
+    uint32_t getGuestVirtualYRes();
 #ifdef VBOX_SECURELABEL
     int  initSecureLabel(uint32_t height, char *font, uint32_t pointsize, uint32_t labeloffs);
     void setSecureLabelText(const char *text);
@@ -177,6 +180,19 @@
     bool mfResizable;
     /** flag whether we print out SDL information */
     bool mfShowSDLConfig;
+#ifdef VBOX_OPENGL
+    /** flag whenever OpenGL acceleration should be used */
+    bool mfOpenGL;
+    /** flag whenever we are stretching the framebuffer if it's smaller
+     *  than the actual resolution (works only with mfOpenGL)*/
+    bool mfStretch;
+    /** a display list used to render guest's framebuffer */
+    GLuint mfGuestDisplayList;
+    /** visible (affected by stretching) x resolution */
+    uint32_t mGuestVirtualXRes;
+    /** visible (affected by stretching) y resolution */
+    uint32_t mGuestVirtualYRes;
+#endif
     /** handle to window where framebuffer context is being drawn*/
     uint64_t mWinId;
 #ifdef VBOX_SECURELABEL
@@ -205,6 +221,11 @@
     BOOL mUsesGuestVRAM;
     BOOL mfSameSizeRequested;
 
+#ifdef VBOX_OPENGL
+    /** Two textures - one is the framebuffer, the other is the secure label. */
+    GLuint mTextures[2];
+#endif
+
     /** the application Icon */
     SDL_Surface *mWMIcon;
 };
diff -Naur original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Makefile.kmk VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Makefile.kmk
--- original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Makefile.kmk	2009-02-16 16:53:42.000000000 +0100
+++ VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/Makefile.kmk	2009-03-07 17:19:49.000000000 +0100
@@ -74,9 +74,6 @@
 VBoxSDL_DEFS.freebsd = VBOXSDL_WITH_X11
 VBoxSDL_DEFS.linux = _GNU_SOURCE VBOXSDL_WITH_X11
 VBoxSDL_DEFS.solaris = VBOXSDL_WITH_X11
-ifdef VBOX_OPENGL
- #VBoxSDL_DEFS.linux += VBOX_OPENGL
-endif
 ifndef VBOX_OSE
 # disable for now as this customer-specific GUI
 # VBoxSDL_DEFS.win  = VBOX_WIN32_UI
@@ -102,9 +99,10 @@
 VBoxSDL_LIBPATH = \
 	$(VBOX_LIBPATH_X11)
 endif
-ifdef VBOX_OPENGL
- #VBoxSDL_LIBS.linux += GL
-endif
+# ifdef VBOX_OPENGL
+ VBoxSDL_DEFS.linux += VBOX_OPENGL
+ VBoxSDL_LIBS.linux += GL
+# endif
 
 VBoxSDL_LDFLAGS.darwin = \
 	-framework Foundation -framework AppKit
diff -Naur original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
--- original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	2009-02-16 16:53:42.000000000 +0100
+++ VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	2009-03-07 17:17:37.000000000 +0100
@@ -697,6 +697,11 @@
              "                           but create backup copies before\n"
              "  -convertSettingsIgnore   Allow to auto-convert settings files\n"
              "                           but don't explicitly save the results\n"
+#ifdef VBOX_OPENGL
+             "  -opengl                  Try to use OpenGL for rendering\n"
+             "  -stretch                 Stretch the framebuffer if it doesn't cover the whole screen\n"
+             "                           (only with -opengl)\n"
+#endif
              "\n"
              "Key bindings:\n"
              "  <hostkey> +  f           Switch to full screen / restore to previous view\n"
@@ -1030,6 +1035,8 @@
     VBoxSDLConsoleCallback *consoleCallback = NULL;
     bool fFullscreen = false;
     bool fResizable = true;
+    bool fOpenGL = false;
+    bool fStretch = false;
 #ifdef USE_XPCOM_QUEUE_THREAD
     bool fXPCOMEventThreadSignaled = false;
 #endif
@@ -1567,6 +1574,12 @@
             fConvertSettings = ConvertSettings_Backup;
         else if (strcmp(argv[curArg], "-convertSettingsIgnore") == 0)
             fConvertSettings = ConvertSettings_Ignore;
+#ifdef VBOX_OPENGL
+        else if (strcmp(argv[curArg], "-opengl") == 0)
+            fOpenGL = true;
+        else if (strcmp(argv[curArg], "-stretch") == 0)
+            fStretch = true;
+#endif
         /* just show the help screen */
         else
         {
@@ -1892,7 +1905,7 @@
 #endif
 
     // create our SDL framebuffer instance
-    gpFrameBuffer = new VBoxSDLFB(fFullscreen, fResizable, fShowSDLConfig, false,
+    gpFrameBuffer = new VBoxSDLFB(fFullscreen, fResizable, fShowSDLConfig, false, fOpenGL, fStretch,
                                   fixedWidth, fixedHeight, fixedBPP);
 
     if (!gpFrameBuffer)
@@ -3754,8 +3767,8 @@
     /* 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();
+    int  xMax = xMin + (int)gpFrameBuffer->getGuestVirtualXRes();
+    int  yMax = yMin + (int)gpFrameBuffer->getGuestVirtualYRes();
 
     state = abs ? SDL_GetMouseState(&x, &y) : SDL_GetRelativeMouseState(&x, &y);
 
@@ -3828,6 +3841,18 @@
         }
     }
 
+    if (abs)
+    {
+        /* If our display is stretched then we need to scale mouse coordinates appropriately. */
+        x = x + 1 - xMin;
+        y = y + 1 - yMin;
+
+        double xScale = double(gpFrameBuffer->getGuestXRes()) / double(gpFrameBuffer->getGuestVirtualXRes());
+        double yScale = double(gpFrameBuffer->getGuestYRes()) / double(gpFrameBuffer->getGuestVirtualYRes());
+        x = int(double(x) * xScale);
+        y = int(double(y) * yScale);
+    }
+
     /*
      * Button was pressed but that press is not reflected in the button state?
      */
@@ -3854,9 +3879,7 @@
              * should we do the increment internally in PutMouseEventAbsolute()
              * or state it in PutMouseEventAbsolute() docs?
              */
-            gMouse->PutMouseEventAbsolute(x + 1 - xMin,
-                                          y + 1 - yMin,
-                                          dz, buttons | tmp_button);
+            gMouse->PutMouseEventAbsolute(x, y, dz, buttons | tmp_button);
         }
         else
         {
@@ -3873,9 +3896,7 @@
          * should we do the increment internally in PutMouseEventAbsolute()
          * or state it in PutMouseEventAbsolute() docs?
          */
-        gMouse->PutMouseEventAbsolute(x + 1 - xMin,
-                                      y + 1 - yMin,
-                                      dz, buttons);
+        gMouse->PutMouseEventAbsolute(x, y, dz, buttons);
     }
     else
     {
diff -Naur original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/VBoxSDL.h VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/VBoxSDL.h
--- original_VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/VBoxSDL.h	2009-02-16 16:53:42.000000000 +0100
+++ VirtualBox-2.1.4_OSE/src/VBox/Frontends/VBoxSDL/VBoxSDL.h	2009-03-07 13:28:02.000000000 +0100
@@ -30,6 +30,10 @@
 /* include this first so Windows.h get's in before our stuff. */
 #include <SDL.h>
 
+#ifdef VBOX_OPENGL
+    #include <SDL_opengl.h>
+#endif
+
 /** custom SDL event for display update handling */
 #define SDL_USER_EVENT_UPDATERECT         (SDL_USEREVENT + 4)
 /** custom SDL event for resize handling */
