Framebuffer.cpp revision 75fdda3e5082879b5154be2b80540a68331cd37c
/** @file
*
* VBox frontends: Framebuffer (FB, DirectFB):
* Implementation of VBoxDirectFB class
*/
/*
* Copyright (C) 2006-2009 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
#include "VBoxFB.h"
#include "Framebuffer.h"
{
// initialize screen dimensions
fbWidth = 640;
fbHeight = 480;
{
}
fbSurfaceLocked = 0;
}
{
// free our internal surface
if (fbInternalSurface)
{
}
}
{
if (!width)
return NS_ERROR_INVALID_POINTER;
return NS_OK;
}
{
if (!height)
return NS_ERROR_INVALID_POINTER;
return NS_OK;
}
{
// do we have an internal framebuffer?
if (fbInternalSurface)
{
if (fbSurfaceLocked)
{
printf("internal surface already locked!\n");
} else
{
&fbBufferAddress, (int*)&fbPitch));
fbSurfaceLocked = 1;
}
} else
{
if (fbSurfaceLocked)
{
printf("surface already locked!\n");
} else
{
&fbBufferAddress, (int*)&fbPitch));
fbSurfaceLocked = 1;
}
}
return NS_OK;
}
{
// do we have an internal framebuffer?
if (fbInternalSurface)
{
if (!fbSurfaceLocked)
{
printf("internal surface not locked!\n");
} else
{
fbSurfaceLocked = 0;
}
} else
{
if (!fbSurfaceLocked)
{
printf("surface not locked!\n");
} else
{
fbSurfaceLocked = 0;
}
}
return NS_OK;
}
{
if (!address)
return NS_ERROR_INVALID_POINTER;
return NS_OK;
}
{
if (!bitsPerPixel)
return NS_ERROR_INVALID_POINTER;
switch (pixelFormat)
{
case DSPF_RGB16:
*bitsPerPixel = 16;
break;
case DSPF_RGB24:
*bitsPerPixel = 24;
break;
case DSPF_RGB32:
*bitsPerPixel = 32;
break;
default:
// not good! @@@AH do something!
*bitsPerPixel = 16;
}
return NS_OK;
}
{
if (!bytesPerLine)
return NS_ERROR_INVALID_POINTER;
*bytesPerLine = fbPitch;
return NS_OK;
}
{
if (!pixelFormat)
return NS_ERROR_INVALID_POINTER;
return NS_OK;
}
{
if (!usesGuestVRAM)
return NS_ERROR_INVALID_POINTER;
*usesGuestVRAM = false;
return NS_OK;
}
{
if (!heightReduction)
return NS_ERROR_INVALID_POINTER;
*heightReduction = 0;
return NS_OK;
}
{
if (!overlay)
return NS_ERROR_INVALID_POINTER;
/* Not yet implemented */
*overlay = 0;
return NS_OK;
}
{
if (!winId)
return NS_ERROR_INVALID_POINTER;
*winId = 0;
return NS_OK;
}
{
// we only need to take action if we have a memory framebuffer
if (fbInternalSurface)
{
//printf("blitting %u %u %u %u...\n", x, y, w, h);
blitRectangle.x = x;
blitRectangle.y = y;
blitRectangle.w = w;
blitRectangle.h = h;
if (scaleGuest)
{
&blitRectangle, &hostRectangle));
}
else
{
}
}
return NS_OK;
}
{
printf("RequestResize: aScreenId = %d, pixelFormat = %d, vram = %p, bitsPerPixel = %d, bytesPerLine = %d, w = %d, h = %d, fbSurfaceLocked = %d\n", aScreenId, pixelFormat, vram, bitsPerPixel, bytesPerLine, w, h, fbSurfaceLocked);
// we can't work with a locked surface
if (needsLocking)
{
Unlock();
}
// in any case we gotta free a possible internal framebuffer
if (fbInternalSurface)
{
printf("freeing internal surface\n");
}
// check if we have a fixed host video mode
if (useFixedVideoMode)
{
// does the current video mode differ from what the guest wants?
if ((screenWidth == w) && (screenHeight == h))
{
printf("requested guest mode matches current host mode!\n");
} else
{
createSurface(w, h);
}
} else
{
// we adopt to the guest resolution or the next higher that is available
if (bestMode == -1)
{
// oh oh oh oh
printf("RequestResize: no suitable mode found!\n");
return NS_OK;
}
// does the mode differ from what we wanted?
{
printf("The mode does not fit exactly!\n");
createSurface(w, h);
} else
{
printf("The mode fits exactly!\n");
}
// switch to this mode
}
// update dimensions to the new size
fbWidth = w;
fbHeight = h;
// clear the screen
// if it was locked before the resize, obtain the lock again
if (needsLocking)
{
Lock();
}
if (finished)
*finished = true;
return NS_OK;
}
NS_IMETHODIMP VBoxDirectFB::VideoModeSupported(PRUint32 w, PRUint32 h, PRUint32 bpp, PRBool *supported)
{
if (!supported)
return NS_ERROR_INVALID_POINTER;
*supported = true;
return NS_OK;
}
NS_IMETHODIMP VBoxDirectFB::GetVisibleRegion(PRUint8 *rectangles, PRUint32 count, PRUint32 *countCopied)
{
if (!rects || !countCopied)
return NS_ERROR_INVALID_POINTER;
/** @todo */
*countCopied = 0;
return NS_OK;
}
{
if (!rects)
return NS_ERROR_INVALID_POINTER;
/** @todo */
return NS_OK;
}
{
return NS_ERROR_NOT_IMPLEMENTED;
}
{
printf("creating a new internal surface, w = %u, h = %u...\n", w, h);
// create a surface
return 0;
}