SDLFramebuffer.cpp revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/** @file
*
* VBox frontends: Basic Frontend (BFE):
* Implementation of SDLFramebuffer class
*/
/*
* Copyright (C) 2006 InnoTek Systemberatung GmbH
*
* 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 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.
*
* If you received this file as part of a commercial VirtualBox
* distribution, then only the terms of your commercial VirtualBox
* license agreement apply instead of the previous paragraph.
*/
#ifdef VBOXBFE_WITHOUT_COM
# include "COMDefs.h"
#else
#endif
#define LOG_GROUP LOG_GROUP_GUI
#include <signal.h>
#include "SDLFramebuffer.h"
//
// Constructor / destructor
//
/**
* SDL framebuffer constructor. It is called from the main
* (i.e. SDL) thread. Therefore it is safe to use SDL calls
* here.
*/
{
int rc;
LogFlow(("SDLFramebuffer::SDLFramebuffer\n"));
#if defined (__WIN32__)
refcnt = 0;
#endif
mfFullscreen = false;
mTopOffset = 0;
/* memorize the thread that inited us, that's the SDL thread */
#ifdef VBOX_SECURELABEL
mLabelFont = NULL;
mLabelHeight = 0;
#endif
#ifdef __LINUX__
/* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */
#endif
/*
* Start with standard screen dimensions.
*/
mWidth = 640;
mHeight = 480;
resize();
}
{
LogFlow(("SDLFramebuffer::~SDLFramebuffer\n"));
#ifdef VBOX_SECURELABEL
if (mLabelFont)
TTF_Quit();
#endif
}
/**
* Returns the current framebuffer width in pixels.
*
* @returns COM status code
* @param width Address of result buffer.
*/
{
LogFlow(("SDLFramebuffer::GetWidth\n"));
if (!width)
return E_INVALIDARG;
return S_OK;
}
/**
* Returns the current framebuffer height in pixels.
*
* @returns COM status code
* @param height Address of result buffer.
*/
{
LogFlow(("SDLFramebuffer::GetHeight\n"));
if (!height)
return E_INVALIDARG;
return S_OK;
}
/**
* Lock the framebuffer (make its address immutable).
*
* @returns COM status code
*/
{
LogFlow(("SDLFramebuffer::Lock\n"));
return S_OK;
}
/**
* Unlock the framebuffer.
*
* @returns COM status code
*/
{
LogFlow(("SDLFramebuffer::Unlock\n"));
return S_OK;
}
/**
* Return the framebuffer start address.
*
* @returns COM status code.
* @param address Pointer to result variable.
*/
{
LogFlow(("SDLFramebuffer::GetAddress\n"));
if (!address)
return E_INVALIDARG;
/* subtract the reserved extra area */
return S_OK;
}
/**
* Return the current framebuffer color depth.
*
* @returns COM status code
* @param colorDepth Address of result variable
*/
{
LogFlow(("SDLFramebuffer::GetColorDepth\n"));
if (!colorDepth)
return E_INVALIDARG;
return S_OK;
}
/**
* Return the current framebuffer line size in bytes.
*
* @returns COM status code.
* @param lineSize Address of result variable.
*/
{
LogFlow(("SDLFramebuffer::GetLineSize\n"));
if (!lineSize)
return E_INVALIDARG;
return S_OK;
}
/**
* Notify framebuffer of an update.
*
* @returns COM status code
* @param x Update region upper left corner x value.
* @param y Update region upper left corner y value.
* @param w Update region width in pixels.
* @param h Update region height in pixels.
* @param finished Address of output flag whether the update
* could be fully processed in this call (which
* has to return immediately) or VBox should wait
* for a call to the update complete API before
* continuing with display updates.
*/
{
LogFlow(("SDLFramebuffer::NotifyUpdate: x = %d, y = %d, w = %d, h = %d\n",
x, y, w, h));
#ifdef __LINUX__
/*
* SDL does not allow us to make this call from any other
* thread. So we have to send an event to the main SDL
* thread and process it there. For sake of simplicity, we encode
* all information in the event parameters.
*/
// 16 bit is enough for coordinates
// printf("%s:%d event=%p\n",__FILE__,__LINE__,&event);
SDL_GetError()));
/* in order to not flood the SDL event queue, yield the CPU */
#else /* !__LINUX__ */
update(x, y + mTopOffset, w, h);
#endif /* !__LINUX__ */
/*
* The Display thread can continue as we will lock the framebuffer
* from the SDL thread when we get to actually doing the update.
*/
if (finished)
return S_OK;
}
/**
* Request a display resize from the framebuffer.
*
* @returns COM status code.
* @param w New display width in pixels.
* @param h New display height in pixels.
* @param finished Address of output flag whether the update
* could be fully processed in this call (which
* has to return immediately) or VBox should wait
* for all call to the resize complete API before
* continuing with display updates.
*/
{
LogFlow(("SDLFramebuffer::RequestResize: w = %d, h = %d\n", w, h));
/*
* SDL does not allow us to make this call from any other
* thread. So we have to send an event to the main SDL
* thread and tell VBox to wait.
*/
if (!finished)
{
AssertMsgFailed(("RequestResize requires the finished flag!\n"));
return E_FAIL;
}
mWidth = w;
mHeight = h;
/* we want this request to be processed quickly, so yield the CPU */
*finished = false;
return S_OK;
}
{
return E_NOTIMPL;
}
{
return E_NOTIMPL;
}
//
// Internal public methods
//
/**
* Method that does the actual resize.
*
* @remarks Must be called from the SDL thread!
*/
void SDLFramebuffer::resize()
{
if (mfFullscreen)
{
#ifdef __WIN32__
/* this flag causes a crash on Windows, mScreen->pixels is NULL */
sdlFlags &= ~SDL_HWSURFACE;
#endif
}
#ifdef VBOX_SECURELABEL
/* try to add the label size */
#endif
#ifdef VBOX_SECURELABEL
/* if it didn't work, then we have to go for the original resolution and paint over the guest */
if (!mScreen)
{
/* we don't have any extra space */
mTopOffset = 0;
}
else
{
/* we now have some extra space */
}
#endif
if (mScreen)
repaint();
}
/**
* Update specified framebuffer area.
*
* @remarks Must be called from the SDL thread on Linux! Update region
* on the whole framebuffer, including y offset!
* @param x left column
* @param y top row
* @param w width in pixels
* @param h heigh in pixels
*/
void SDLFramebuffer::update(int x, int y, int w, int h)
{
#ifdef __LINUX__
#endif
#ifdef VBOX_SECURELABEL
/*
* Cut down the update area to the untrusted portion
*/
if (safeY < mLabelHeight)
#endif
#ifdef VBOX_SECURELABEL
paintSecureLabel(x, y, w, h, false);
#endif
}
/**
* Repaint the whole framebuffer
*
* @remarks Must be called from the SDL thread!
*/
void SDLFramebuffer::repaint()
{
LogFlow(("SDLFramebuffer::repaint\n"));
}
bool SDLFramebuffer::getFullscreen()
{
LogFlow(("SDLFramebuffer::getFullscreen\n"));
return mfFullscreen;
}
/**
* Toggle fullscreen mode
*
* @remarks Must be called from the SDL thread!
*/
{
resize();
}
/**
* Returns the current y offset of the start of the guest screen
*
* @returns current y offset in pixels
*/
int SDLFramebuffer::getYOffset()
{
return mTopOffset;
}
/**
* Returns the number of horizontal pixels of the host console
*
* @return X resolution
* @remarks currently not used in SDL mode
*/
int SDLFramebuffer::getHostXres()
{
return 0;
}
/**
* Returns the number of vertical pixels of the host console
*
* @return Y resolution
* @remarks currently not used in SDL mode
*/
int SDLFramebuffer::getHostYres()
{
return 0;
}
/**
* Returns the number of bits per pixels of the host console
*
* @return bits per pixel
* @remarks currently not used in SDL mode
*/
{
return 0;
}
#ifdef VBOX_SECURELABEL
/**
* Setup the secure labeling parameters
*
* @returns VBox status code
* @param height height of the secure label area in pixels
* @param font file path fo the TrueType font file
* @param pointsize font size in points
*/
{
LogFlow(("SDLFramebuffer:initSecureLabel: new offset: %d pixels, new font: %s, new pointsize: %d\n",
TTF_Init();
if (!mLabelFont)
{
return VERR_OPEN_FAILED;
}
repaint();
return VINF_SUCCESS;
}
/**
* Set the secure label text and repaint the label
*
* @param text UTF-8 string of new label
* @remarks must be called from the SDL thread!
*/
{
paintSecureLabel(0, 0, 0, 0, true);
}
/**
* Paint the secure label if required
*
* @param fForce Force the repaint
* @remarks must be called from the SDL thread!
*/
{
/* check if we can skip the paint */
{
return;
}
/* first fill the background */
/* now the text */
if (mLabelFont && mSecureLabelText)
{
rect.x = 10;
}
/* make sure to update the screen */
}
#endif /* VBOX_SECURELABEL */