Framebuffer.cpp revision dcb33fa4e1aae96f9a34ec993e8b29dc501a3103
c869993e79c1eafbec61a56bf6cea848fe754c71xy/** @file
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * VBox frontends: VBoxSDL (simple frontend based on SDL):
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Implementation of VBoxSDLFB (SDL framebuffer) class
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Copyright (C) 2006-2012 Oracle Corporation
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * This file is part of VirtualBox Open Source Edition (OSE), as
c869993e79c1eafbec61a56bf6cea848fe754c71xy * available from http://www.virtualbox.org. This file is free software;
c869993e79c1eafbec61a56bf6cea848fe754c71xy * you can redistribute it and/or modify it under the terms of the GNU
c869993e79c1eafbec61a56bf6cea848fe754c71xy * General Public License (GPL) as published by the Free Software
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Foundation, in version 2 as it comes in the "COPYING" file of the
c869993e79c1eafbec61a56bf6cea848fe754c71xy * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c869993e79c1eafbec61a56bf6cea848fe754c71xy * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <VBox/com/com.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <VBox/com/array.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <VBox/com/string.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <VBox/com/Guid.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <VBox/com/ErrorInfo.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <VBox/com/VirtualBox.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <iprt/stream.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <iprt/env.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef RT_OS_OS2
c869993e79c1eafbec61a56bf6cea848fe754c71xy# undef RT_MAX
c869993e79c1eafbec61a56bf6cea848fe754c71xy// from <iprt/cdefs.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy# define RT_MAX(Value1, Value2) ((Value1) >= (Value2) ? (Value1) : (Value2))
fa25784ca4b51c206177d891a654f1d36a25d41fxy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyusing namespace com;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#define LOG_GROUP LOG_GROUP_GUI
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <VBox/err.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <VBox/log.h>
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include "VBoxSDL.h"
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include "Framebuffer.h"
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include "Ico64x01.h"
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#if defined(RT_OS_WINDOWS) || defined(RT_OS_LINUX)
c869993e79c1eafbec61a56bf6cea848fe754c71xy#include <SDL_syswm.h> /* for SDL_GetWMInfo() */
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#if defined(VBOX_WITH_XPCOM)
c869993e79c1eafbec61a56bf6cea848fe754c71xyNS_IMPL_THREADSAFE_ISUPPORTS1_CI(VBoxSDLFB, IFramebuffer)
c869993e79c1eafbec61a56bf6cea848fe754c71xyNS_DECL_CLASSINFO(VBoxSDLFB)
c869993e79c1eafbec61a56bf6cea848fe754c71xyNS_IMPL_THREADSAFE_ISUPPORTS2_CI(VBoxSDLFBOverlay, IFramebufferOverlay, IFramebuffer)
c869993e79c1eafbec61a56bf6cea848fe754c71xyNS_DECL_CLASSINFO(VBoxSDLFBOverlay)
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy/* function pointers */
c869993e79c1eafbec61a56bf6cea848fe754c71xyextern "C"
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xyDECLSPEC int (SDLCALL *pTTF_Init)(void);
c869993e79c1eafbec61a56bf6cea848fe754c71xyDECLSPEC TTF_Font* (SDLCALL *pTTF_OpenFont)(const char *file, int ptsize);
c869993e79c1eafbec61a56bf6cea848fe754c71xyDECLSPEC SDL_Surface* (SDLCALL *pTTF_RenderUTF8_Solid)(TTF_Font *font, const char *text, SDL_Color fg);
c869993e79c1eafbec61a56bf6cea848fe754c71xyDECLSPEC SDL_Surface* (SDLCALL *pTTF_RenderUTF8_Blended)(TTF_Font *font, const char *text, SDL_Color fg);
c869993e79c1eafbec61a56bf6cea848fe754c71xyDECLSPEC void (SDLCALL *pTTF_CloseFont)(TTF_Font *font);
c869993e79c1eafbec61a56bf6cea848fe754c71xyDECLSPEC void (SDLCALL *pTTF_Quit)(void);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif /* VBOX_SECURELABEL */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic bool gfSdlInitialized = false; /**< if SDL was initialized */
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic SDL_Surface *gWMIcon = NULL; /**< the application icon */
c869993e79c1eafbec61a56bf6cea848fe754c71xystatic RTNATIVETHREAD gSdlNativeThread = NIL_RTNATIVETHREAD; /**< the SDL thread */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy//
c869993e79c1eafbec61a56bf6cea848fe754c71xy// Constructor / destructor
c869993e79c1eafbec61a56bf6cea848fe754c71xy//
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyVBoxSDLFB::VBoxSDLFB()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyHRESULT VBoxSDLFB::FinalConstruct()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy return 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
fa25784ca4b51c206177d891a654f1d36a25d41fxy
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::FinalRelease()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy return;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * SDL framebuffer constructor. It is called from the main
c869993e79c1eafbec61a56bf6cea848fe754c71xy * (i.e. SDL) thread. Therefore it is safe to use SDL calls
c869993e79c1eafbec61a56bf6cea848fe754c71xy * here.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param fFullscreen flag whether we start in fullscreen mode
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param fResizable flag whether the SDL window should be resizable
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param fShowSDLConfig flag whether we print out SDL settings
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param fKeepHostRes flag whether we switch the host screen resolution
c869993e79c1eafbec61a56bf6cea848fe754c71xy * when switching to fullscreen or not
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param iFixedWidth fixed SDL width (-1 means not set)
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param iFixedHeight fixed SDL height (-1 means not set)
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyHRESULT VBoxSDLFB::init(uint32_t uScreenId,
c869993e79c1eafbec61a56bf6cea848fe754c71xy bool fFullscreen, bool fResizable, bool fShowSDLConfig,
c869993e79c1eafbec61a56bf6cea848fe754c71xy bool fKeepHostRes, uint32_t u32FixedWidth,
c869993e79c1eafbec61a56bf6cea848fe754c71xy uint32_t u32FixedHeight, uint32_t u32FixedBPP,
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl bool fUpdateImage)
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl{
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl int rc;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl LogFlow(("VBoxSDLFB::VBoxSDLFB\n"));
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
c869993e79c1eafbec61a56bf6cea848fe754c71xy mScreenId = uScreenId;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfUpdateImage = fUpdateImage;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mScreen = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_WITH_SDL13
c869993e79c1eafbec61a56bf6cea848fe754c71xy mWindow = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mTexture = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSurfVRAM = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfInitialized = false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfFullscreen = fFullscreen;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfKeepHostRes = fKeepHostRes;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mTopOffset = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfResizable = fResizable;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfShowSDLConfig = fShowSDLConfig;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mFixedSDLWidth = u32FixedWidth;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mFixedSDLHeight = u32FixedHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mFixedSDLBPP = u32FixedBPP;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mCenterXOffset = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mCenterYOffset = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Start with standard screen dimensions. */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mGuestXRes = 640;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mGuestYRes = 480;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mPtrVRAM = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mBitsPerPixel = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mBytesPerLine = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfSameSizeRequested = false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy mLabelFont = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mLabelHeight = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mLabelOffs = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfUpdates = false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy rc = RTCritSectInit(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsg(rc == VINF_SUCCESS, ("Error from RTCritSectInit!\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy resizeGuest();
c869993e79c1eafbec61a56bf6cea848fe754c71xy Assert(mScreen);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfInitialized = true;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef RT_OS_WINDOWS
c869993e79c1eafbec61a56bf6cea848fe754c71xy HRESULT hr = CoCreateFreeThreadedMarshaler(this, //GetControllingUnknown(),
c869993e79c1eafbec61a56bf6cea848fe754c71xy &m_pUnkMarshaler.p);
c869993e79c1eafbec61a56bf6cea848fe754c71xy Log(("CoCreateFreeThreadedMarshaler hr %08X\n", hr));
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy return 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyVBoxSDLFB::~VBoxSDLFB()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl LogFlow(("VBoxSDLFB::~VBoxSDLFB\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mSurfVRAM)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_FreeSurface(mSurfVRAM);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSurfVRAM = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy mScreen = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mLabelFont)
c869993e79c1eafbec61a56bf6cea848fe754c71xy pTTF_CloseFont(mLabelFont);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (pTTF_Quit)
c869993e79c1eafbec61a56bf6cea848fe754c71xy pTTF_Quit();
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectDelete(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xybool VBoxSDLFB::init(bool fShowSDLConfig)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFB::init\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* memorize the thread that inited us, that's the SDL thread */
c869993e79c1eafbec61a56bf6cea848fe754c71xy gSdlNativeThread = RTThreadNativeSelf();
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef RT_OS_WINDOWS
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* default to DirectX if nothing else set */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!RTEnvExist("SDL_VIDEODRIVER"))
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy _putenv("SDL_VIDEODRIVER=directx");
c869993e79c1eafbec61a56bf6cea848fe754c71xy// _putenv("SDL_VIDEODRIVER=windib");
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOXSDL_WITH_X11
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* On some X servers the mouse is stuck inside the bottom right corner.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * See http://wiki.clug.org.za/wiki/QEMU_mouse_not_working */
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTEnvSet("SDL_VIDEO_X11_DGAMOUSE", "0");
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy int rc = SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (rc != 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTPrintf("SDL Error: '%s'\n", SDL_GetError());
c869993e79c1eafbec61a56bf6cea848fe754c71xy return false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy gfSdlInitialized = true;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
c869993e79c1eafbec61a56bf6cea848fe754c71xy Assert(videoInfo);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (videoInfo)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* output what SDL is capable of */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (fShowSDLConfig)
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTPrintf("SDL capabilities:\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Hardware surface support: %s\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Window manager available: %s\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Screen to screen blits accelerated: %s\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Screen to screen colorkey blits accelerated: %s\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Screen to screen alpha blits accelerated: %s\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Memory to screen blits accelerated: %s\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Memory to screen colorkey blits accelerated: %s\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Memory to screen alpha blits accelerated: %s\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Color fills accelerated: %s\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Video memory in kilobytes: %d\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy " Optimal bpp mode: %d\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy "SDL video driver: %s\n",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->hw_available ? "yes" : "no",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->wm_available ? "yes" : "no",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->blit_hw ? "yes" : "no",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->blit_hw_CC ? "yes" : "no",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->blit_hw_A ? "yes" : "no",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->blit_sw ? "yes" : "no",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->blit_sw_CC ? "yes" : "no",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->blit_sw_A ? "yes" : "no",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->blit_fill ? "yes" : "no",
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->video_mem,
c869993e79c1eafbec61a56bf6cea848fe754c71xy videoInfo->vfmt->BitsPerPixel,
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTEnvGet("SDL_VIDEODRIVER"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (12320 == g_cbIco64x01)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy gWMIcon = SDL_AllocSurface(SDL_SWSURFACE, 64, 64, 24, 0xff, 0xff00, 0xff0000, 0);
c869993e79c1eafbec61a56bf6cea848fe754c71xy /** @todo make it as simple as possible. No PNM interpreter here... */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (gWMIcon)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy memcpy(gWMIcon->pixels, g_abIco64x01+32, g_cbIco64x01-32);
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_WM_SetIcon(gWMIcon, NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy return true;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Terminate SDL
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @remarks must be called from the SDL thread!
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::uninit()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (gfSdlInitialized)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_QuitSubSystem(SDL_INIT_VIDEO);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (gWMIcon)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_FreeSurface(gWMIcon);
c869993e79c1eafbec61a56bf6cea848fe754c71xy gWMIcon = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the current framebuffer width in pixels.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param width Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::COMGETTER(Width)(ULONG *width)
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl{
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl LogFlow(("VBoxSDLFB::GetWidth\n"));
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl if (!width)
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl return E_INVALIDARG;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl *width = mGuestXRes;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl return S_OK;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl}
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the current framebuffer height in pixels.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param height Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::COMGETTER(Height)(ULONG *height)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFB::GetHeight\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!height)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *height = mGuestYRes;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Return the current framebuffer color depth.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param bitsPerPixel Address of result variable
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::COMGETTER(BitsPerPixel)(ULONG *bitsPerPixel)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFB::GetBitsPerPixel\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!bitsPerPixel)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* get the information directly from the surface in use */
c869993e79c1eafbec61a56bf6cea848fe754c71xy Assert(mSurfVRAM);
c869993e79c1eafbec61a56bf6cea848fe754c71xy *bitsPerPixel = (ULONG)(mSurfVRAM ? mSurfVRAM->format->BitsPerPixel : 0);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Return the current framebuffer line size in bytes.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param lineSize Address of result variable.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::COMGETTER(BytesPerLine)(ULONG *bytesPerLine)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFB::GetBytesPerLine\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!bytesPerLine)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* get the information directly from the surface */
c869993e79c1eafbec61a56bf6cea848fe754c71xy Assert(mSurfVRAM);
c869993e79c1eafbec61a56bf6cea848fe754c71xy *bytesPerLine = (ULONG)(mSurfVRAM ? mSurfVRAM->pitch : 0);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::COMGETTER(PixelFormat) (ULONG *pixelFormat)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!pixelFormat)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_POINTER;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *pixelFormat = FramebufferPixelFormat_FOURCC_RGB;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns by how many pixels the guest should shrink its
c869993e79c1eafbec61a56bf6cea848fe754c71xy * video mode height values.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param heightReduction Address of result variable.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::COMGETTER(HeightReduction)(ULONG *heightReduction)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!heightReduction)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_POINTER;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy *heightReduction = mLabelHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#else
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl *heightReduction = 0;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl#endif
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl return S_OK;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl}
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns a pointer to an alpha-blended overlay used for displaying status
c869993e79c1eafbec61a56bf6cea848fe754c71xy * icons above the framebuffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param aOverlay The overlay framebuffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::COMGETTER(Overlay)(IFramebufferOverlay **aOverlay)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!aOverlay)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_POINTER;
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Not yet implemented */
c869993e79c1eafbec61a56bf6cea848fe754c71xy *aOverlay = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns handle of window where framebuffer context is being drawn
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param winId Handle of associated window.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::COMGETTER(WinId)(int64_t *winId)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!winId)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_POINTER;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *winId = mWinId;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Notify framebuffer of an update.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param x Update region upper left corner x value.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param y Update region upper left corner y value.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param w Update region width in pixels.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param h Update region height in pixels.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param finished Address of output flag whether the update
c869993e79c1eafbec61a56bf6cea848fe754c71xy * could be fully processed in this call (which
c869993e79c1eafbec61a56bf6cea848fe754c71xy * has to return immediately) or VBox should wait
c869993e79c1eafbec61a56bf6cea848fe754c71xy * for a call to the update complete API before
c869993e79c1eafbec61a56bf6cea848fe754c71xy * continuing with display updates.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::NotifyUpdate(ULONG x, ULONG y,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG w, ULONG h)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * The input values are in guest screen coordinates.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFB::NotifyUpdate: x = %d, y = %d, w = %d, h = %d\n",
c869993e79c1eafbec61a56bf6cea848fe754c71xy x, y, w, h));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOXSDL_WITH_X11
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * SDL does not allow us to make this call from any other thread than
c869993e79c1eafbec61a56bf6cea848fe754c71xy * the main SDL thread (which initialized the video mode). So we have
c869993e79c1eafbec61a56bf6cea848fe754c71xy * to send an event to the main SDL thread and process it there. For
c869993e79c1eafbec61a56bf6cea848fe754c71xy * sake of simplicity, we encode all information in the event parameters.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Event event;
c869993e79c1eafbec61a56bf6cea848fe754c71xy event.type = SDL_USEREVENT;
c869993e79c1eafbec61a56bf6cea848fe754c71xy event.user.code = mScreenId;
c869993e79c1eafbec61a56bf6cea848fe754c71xy event.user.type = SDL_USER_EVENT_UPDATERECT;
c869993e79c1eafbec61a56bf6cea848fe754c71xy // 16 bit is enough for coordinates
c869993e79c1eafbec61a56bf6cea848fe754c71xy event.user.data1 = (void*)(uintptr_t)(x << 16 | y);
c869993e79c1eafbec61a56bf6cea848fe754c71xy event.user.data2 = (void*)(uintptr_t)(w << 16 | h);
c869993e79c1eafbec61a56bf6cea848fe754c71xy PushNotifyUpdateEvent(&event);
c869993e79c1eafbec61a56bf6cea848fe754c71xy#else /* !VBOXSDL_WITH_X11 */
c869993e79c1eafbec61a56bf6cea848fe754c71xy update(x, y, w, h, true /* fGuestRelative */);
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif /* !VBOXSDL_WITH_X11 */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::NotifyUpdateImage(ULONG aX,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG aY,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG aWidth,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG aHeight,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ComSafeArrayIn(BYTE, aImage))
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("NotifyUpdateImage: %d,%d %dx%d\n", aX, aY, aWidth, aHeight));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy com::SafeArray<BYTE> image(ComSafeArrayInArg(aImage));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Copy to mSurfVRAM. */
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Rect srcRect;
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Rect dstRect;
c869993e79c1eafbec61a56bf6cea848fe754c71xy srcRect.x = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy srcRect.y = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy srcRect.w = (uint16_t)aWidth;
c869993e79c1eafbec61a56bf6cea848fe754c71xy srcRect.h = (uint16_t)aHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy dstRect.x = (int16_t)aX;
c869993e79c1eafbec61a56bf6cea848fe754c71xy dstRect.y = (int16_t)aY;
c869993e79c1eafbec61a56bf6cea848fe754c71xy dstRect.w = (uint16_t)aWidth;
c869993e79c1eafbec61a56bf6cea848fe754c71xy dstRect.h = (uint16_t)aHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy const uint32_t Rmask = 0x00FF0000, Gmask = 0x0000FF00, Bmask = 0x000000FF, Amask = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Surface *surfSrc = SDL_CreateRGBSurfaceFrom(image.raw(), aWidth, aHeight, 32, aWidth * 4,
c869993e79c1eafbec61a56bf6cea848fe754c71xy Rmask, Gmask, Bmask, Amask);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (surfSrc)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectEnter(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mfUpdates)
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_BlitSurface(surfSrc, &srcRect, mSurfVRAM, &dstRect);
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectLeave(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_FreeSurface(surfSrc);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy return NotifyUpdate(aX, aY, aWidth, aHeight);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xyextern ComPtr<IDisplay> gpDisplay;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::NotifyChange(ULONG aScreenId,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG aXOrigin,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG aYOrigin,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG aWidth,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG aHeight)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogRel(("NotifyChange: %d %d,%d %dx%d\n",
c869993e79c1eafbec61a56bf6cea848fe754c71xy aScreenId, aXOrigin, aYOrigin, aWidth, aHeight));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy ComPtr<IDisplaySourceBitmap> pSourceBitmap;
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!mfUpdateImage)
c869993e79c1eafbec61a56bf6cea848fe754c71xy gpDisplay->QuerySourceBitmap(aScreenId, pSourceBitmap.asOutParam());
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectEnter(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Disable screen updates. */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfUpdates = false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mfUpdateImage)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy mGuestXRes = aWidth;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mGuestYRes = aHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mPtrVRAM = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mBitsPerPixel = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mBytesPerLine = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Save the new bitmap. */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mpPendingSourceBitmap = pSourceBitmap;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectLeave(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Event event;
c869993e79c1eafbec61a56bf6cea848fe754c71xy event.type = SDL_USEREVENT;
c869993e79c1eafbec61a56bf6cea848fe754c71xy event.user.type = SDL_USER_EVENT_NOTIFYCHANGE;
c869993e79c1eafbec61a56bf6cea848fe754c71xy event.user.code = mScreenId;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy PushSDLEventForSure(&event);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTThreadYield();
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns whether we like the given video mode.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param width video mode width in pixels
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param height video mode height in pixels
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param bpp video mode bit depth in bits per pixel
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param supported pointer to result variable
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::VideoModeSupported(ULONG width, ULONG height, ULONG bpp, BOOL *supported)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!supported)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_POINTER;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* are constraints set? */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if ( ( (mMaxScreenWidth != ~(uint32_t)0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy && (width > mMaxScreenWidth))
c869993e79c1eafbec61a56bf6cea848fe754c71xy || ( (mMaxScreenHeight != ~(uint32_t)0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy && (height > mMaxScreenHeight)))
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* nope, we don't want that (but still don't freak out if it is set) */
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef DEBUG
c869993e79c1eafbec61a56bf6cea848fe754c71xy printf("VBoxSDL::VideoModeSupported: we refused mode %dx%dx%d\n", width, height, bpp);
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy *supported = false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* anything will do */
c869993e79c1eafbec61a56bf6cea848fe754c71xy *supported = true;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::GetVisibleRegion(BYTE *aRectangles, ULONG aCount,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG *aCountCopied)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy PRTRECT rects = (PRTRECT)aRectangles;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!rects)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_POINTER;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /// @todo
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy NOREF(aCount);
c869993e79c1eafbec61a56bf6cea848fe754c71xy NOREF(aCountCopied);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::SetVisibleRegion(BYTE *aRectangles, ULONG aCount)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy PRTRECT rects = (PRTRECT)aRectangles;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!rects)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_POINTER;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /// @todo
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy NOREF(aCount);
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::ProcessVHWACommand(BYTE *pCommand)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_NOTIMPL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFB::Notify3DEvent(ULONG uType, ComSafeArrayIn(BYTE, aData))
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_NOTIMPL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy//
c869993e79c1eafbec61a56bf6cea848fe754c71xy// Internal public methods
c869993e79c1eafbec61a56bf6cea848fe754c71xy//
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/* This method runs on the main SDL thread. */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::notifyChange(ULONG aScreenId)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Disable screen updates. */
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectEnter(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!mfUpdateImage && mpPendingSourceBitmap.isNull())
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Do nothing. Change event already processed. */
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectLeave(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Release the current bitmap and keep the pending one. */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mpSourceBitmap = mpPendingSourceBitmap;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mpPendingSourceBitmap.setNull();
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl RTCritSectLeave(&mUpdateLock);
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl if (mpSourceBitmap.isNull())
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl {
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl mPtrVRAM = NULL;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl mBitsPerPixel = 32;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mBytesPerLine = mGuestXRes * 4;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy BYTE *pAddress = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG ulWidth = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG ulHeight = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG ulBitsPerPixel = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG ulBytesPerLine = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG ulPixelFormat = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy mpSourceBitmap->QueryBitmapInfo(&pAddress,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &ulWidth,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &ulHeight,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &ulBitsPerPixel,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &ulBytesPerLine,
c869993e79c1eafbec61a56bf6cea848fe754c71xy &ulPixelFormat);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if ( mGuestXRes == ulWidth
c869993e79c1eafbec61a56bf6cea848fe754c71xy && mGuestYRes == ulHeight
c869993e79c1eafbec61a56bf6cea848fe754c71xy && mBitsPerPixel == ulBitsPerPixel
c869993e79c1eafbec61a56bf6cea848fe754c71xy && mBytesPerLine == ulBytesPerLine
c869993e79c1eafbec61a56bf6cea848fe754c71xy && mPtrVRAM == pAddress
c869993e79c1eafbec61a56bf6cea848fe754c71xy )
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfSameSizeRequested = true;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfSameSizeRequested = false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy mGuestXRes = ulWidth;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mGuestYRes = ulHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mPtrVRAM = pAddress;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz mBitsPerPixel = ulBitsPerPixel;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mBytesPerLine = ulBytesPerLine;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy resizeGuest();
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mfUpdateImage)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy gpDisplay->SetFramebufferUpdateMode(aScreenId, FramebufferUpdateMode_NotifyUpdateImage);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy gpDisplay->InvalidateAndUpdateScreen(aScreenId);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Method that does the actual resize of the guest framebuffer and
c869993e79c1eafbec61a56bf6cea848fe754c71xy * then changes the SDL framebuffer setup.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::resizeGuest()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlowFunc (("mGuestXRes: %d, mGuestYRes: %d\n", mGuestXRes, mGuestYRes));
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsg(gSdlNativeThread == RTThreadNativeSelf(),
c869993e79c1eafbec61a56bf6cea848fe754c71xy ("Wrong thread! SDL is not threadsafe!\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectEnter(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy const uint32_t Rmask = 0x00FF0000, Gmask = 0x0000FF00, Bmask = 0x000000FF, Amask = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* first free the current surface */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mSurfVRAM)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_FreeSurface(mSurfVRAM);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSurfVRAM = NULL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mPtrVRAM)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Create a source surface from the source bitmap. */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSurfVRAM = SDL_CreateRGBSurfaceFrom(mPtrVRAM, mGuestXRes, mGuestYRes, mBitsPerPixel,
c869993e79c1eafbec61a56bf6cea848fe754c71xy mBytesPerLine, Rmask, Gmask, Bmask, Amask);
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDL:: using the source bitmap\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSurfVRAM = SDL_CreateRGBSurface(SDL_SWSURFACE, mGuestXRes, mGuestYRes, mBitsPerPixel,
c869993e79c1eafbec61a56bf6cea848fe754c71xy Rmask, Gmask, Bmask, Amask);
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDL:: using SDL_SWSURFACE\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDL:: created VRAM surface %p\n", mSurfVRAM));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mfSameSizeRequested)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfSameSizeRequested = false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDL:: the same resolution requested, skipping the resize.\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* now adjust the SDL resolution */
c869993e79c1eafbec61a56bf6cea848fe754c71xy resizeSDL();
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Enable screen updates. */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mfUpdates = true;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectLeave(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy repaint();
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Sets SDL video mode. This is independent from guest video
c869993e79c1eafbec61a56bf6cea848fe754c71xy * mode changes.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @remarks Must be called from the SDL thread!
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::resizeSDL(void)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDL:resizeSDL\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * We request a hardware surface from SDL so that we can perform
c869993e79c1eafbec61a56bf6cea848fe754c71xy * accelerated system memory to VRAM blits. The way video handling
c869993e79c1eafbec61a56bf6cea848fe754c71xy * works it that on the one hand we have the screen surface from SDL
c869993e79c1eafbec61a56bf6cea848fe754c71xy * and on the other hand we have a software surface that we create
c869993e79c1eafbec61a56bf6cea848fe754c71xy * using guest VRAM memory for linear modes and using SDL allocated
c869993e79c1eafbec61a56bf6cea848fe754c71xy * system memory for text and non linear graphics modes. We never
c869993e79c1eafbec61a56bf6cea848fe754c71xy * directly write to the screen surface but always use SDL blitting
c869993e79c1eafbec61a56bf6cea848fe754c71xy * functions to blit from our system memory surface to the VRAM.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Therefore, SDL can take advantage of hardware acceleration.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy int sdlFlags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifndef RT_OS_OS2 /* doesn't seem to work for some reason... */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mfResizable)
c869993e79c1eafbec61a56bf6cea848fe754c71xy sdlFlags |= SDL_RESIZABLE;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mfFullscreen)
c869993e79c1eafbec61a56bf6cea848fe754c71xy sdlFlags |= SDL_FULLSCREEN;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Now we have to check whether there are video mode restrictions
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Rect **modes;
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Get available fullscreen/hardware modes */
c869993e79c1eafbec61a56bf6cea848fe754c71xy modes = SDL_ListModes(NULL, sdlFlags);
c869993e79c1eafbec61a56bf6cea848fe754c71xy Assert(modes != NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* -1 means that any mode is possible (usually non fullscreen) */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (modes != (SDL_Rect **)-1)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * according to the SDL documentation, the API guarantees that
c869993e79c1eafbec61a56bf6cea848fe754c71xy * the modes are sorted from larger to smaller, so we just
c869993e79c1eafbec61a56bf6cea848fe754c71xy * take the first entry as the maximum.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mMaxScreenWidth = modes[0]->w;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mMaxScreenHeight = modes[0]->h;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* no restriction */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mMaxScreenWidth = ~(uint32_t)0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mMaxScreenHeight = ~(uint32_t)0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy uint32_t newWidth;
c869993e79c1eafbec61a56bf6cea848fe754c71xy uint32_t newHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* reset the centering offsets */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mCenterXOffset = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mCenterYOffset = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* we either have a fixed SDL resolution or we take the guest's */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mFixedSDLWidth != ~(uint32_t)0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy newWidth = mFixedSDLWidth;
c869993e79c1eafbec61a56bf6cea848fe754c71xy newHeight = mFixedSDLHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy newWidth = RT_MIN(mGuestXRes, mMaxScreenWidth);
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy newHeight = RT_MIN(mGuestYRes + mLabelHeight, mMaxScreenHeight);
c869993e79c1eafbec61a56bf6cea848fe754c71xy#else
c869993e79c1eafbec61a56bf6cea848fe754c71xy newHeight = RT_MIN(mGuestYRes, mMaxScreenHeight);
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* we don't have any extra space by default */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mTopOffset = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#if defined(VBOX_WITH_SDL13)
c869993e79c1eafbec61a56bf6cea848fe754c71xy int sdlWindowFlags = SDL_WINDOW_SHOWN;
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mfResizable)
c869993e79c1eafbec61a56bf6cea848fe754c71xy sdlWindowFlags |= SDL_WINDOW_RESIZABLE;
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!mWindow)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_DisplayMode desktop_mode;
c869993e79c1eafbec61a56bf6cea848fe754c71xy int x = 40 + mScreenId * 20;
c869993e79c1eafbec61a56bf6cea848fe754c71xy int y = 40 + mScreenId * 15;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_GetDesktopDisplayMode(&desktop_mode);
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* create new window */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy char szTitle[64];
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTStrPrintf(szTitle, sizeof(szTitle), "SDL window %d", mScreenId);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mWindow = SDL_CreateWindow(szTitle, x, y,
c869993e79c1eafbec61a56bf6cea848fe754c71xy newWidth, newHeight, sdlWindowFlags);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (SDL_CreateRenderer(mWindow, -1,
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD) < 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertReleaseFailed();
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_GetRendererInfo(&mRenderInfo);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy mTexture = SDL_CreateTexture(desktop_mode.format,
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_TEXTUREACCESS_STREAMING, newWidth, newHeight);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!mTexture)
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertReleaseFailed();
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy int w, h;
c869993e79c1eafbec61a56bf6cea848fe754c71xy uint32_t format;
c869993e79c1eafbec61a56bf6cea848fe754c71xy int access;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* resize current window */
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_GetWindowSize(mWindow, &w, &h);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (w != (int)newWidth || h != (int)newHeight)
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_SetWindowSize(mWindow, newWidth, newHeight);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_QueryTexture(mTexture, &format, &access, &w, &h);
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_SelectRenderer(mWindow);
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_DestroyTexture(mTexture);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mTexture = SDL_CreateTexture(format, access, newWidth, newHeight);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!mTexture)
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertReleaseFailed();
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy void *pixels;
c869993e79c1eafbec61a56bf6cea848fe754c71xy int pitch;
c869993e79c1eafbec61a56bf6cea848fe754c71xy int w, h, bpp;
c869993e79c1eafbec61a56bf6cea848fe754c71xy uint32_t Rmask, Gmask, Bmask, Amask;
c869993e79c1eafbec61a56bf6cea848fe754c71xy uint32_t format;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (SDL_QueryTexture(mTexture, &format, NULL, &w, &h) < 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertReleaseFailed();
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask))
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertReleaseFailed();
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (SDL_QueryTexturePixels(mTexture, &pixels, &pitch) == 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy mScreen = SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch,
c869993e79c1eafbec61a56bf6cea848fe754c71xy Rmask, Gmask, Bmask, Amask);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy mScreen = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertReleaseFailed();
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_SetClipRect(mScreen, NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#else
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Now set the screen resolution and get the surface pointer
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @todo BPP is not supported!
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mScreen = SDL_SetVideoMode(newWidth, newHeight, 0, sdlFlags);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Set the Window ID. Currently used for OpenGL accelerated guests.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy# if defined (RT_OS_WINDOWS)
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_SysWMinfo info;
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_VERSION(&info.version);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (SDL_GetWMInfo(&info))
c869993e79c1eafbec61a56bf6cea848fe754c71xy mWinId = (LONG64) info.window;
c869993e79c1eafbec61a56bf6cea848fe754c71xy# elif defined (RT_OS_LINUX)
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_SysWMinfo info;
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_VERSION(&info.version);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (SDL_GetWMInfo(&info))
c869993e79c1eafbec61a56bf6cea848fe754c71xy mWinId = (LONG64) info.info.x11.wmwindow;
c869993e79c1eafbec61a56bf6cea848fe754c71xy# else
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* XXX ignore this for other architectures */
c869993e79c1eafbec61a56bf6cea848fe754c71xy# endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * For non fixed SDL resolution, the above call tried to add the label height
c869993e79c1eafbec61a56bf6cea848fe754c71xy * to the guest height. If it worked, we have an offset. If it didn't the below
c869993e79c1eafbec61a56bf6cea848fe754c71xy * code will try again with the original guest resolution.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mFixedSDLWidth == ~(uint32_t)0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* if it didn't work, then we have to go for the original resolution and paint over the guest */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!mScreen)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy mScreen = SDL_SetVideoMode(newWidth, newHeight - mLabelHeight, 0, sdlFlags);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* we now have some extra space */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mTopOffset = mLabelHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* in case the guest resolution is small enough, we do have a top offset */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mFixedSDLHeight - mGuestYRes >= mLabelHeight)
c869993e79c1eafbec61a56bf6cea848fe754c71xy mTopOffset = mLabelHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* we also might have to center the guest picture */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mFixedSDLWidth > mGuestXRes)
c869993e79c1eafbec61a56bf6cea848fe754c71xy mCenterXOffset = (mFixedSDLWidth - mGuestXRes) / 2;
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mFixedSDLHeight > mGuestYRes + mLabelHeight)
c869993e79c1eafbec61a56bf6cea848fe754c71xy mCenterYOffset = (mFixedSDLHeight - (mGuestYRes + mLabelHeight)) / 2;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsg(mScreen, ("Error: SDL_SetVideoMode failed!\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mScreen)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_WIN32_UI
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* inform the UI code */
c869993e79c1eafbec61a56bf6cea848fe754c71xy resizeUI(mScreen->w, mScreen->h);
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mfShowSDLConfig)
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTPrintf("Resized to %dx%d, screen surface type: %s\n", mScreen->w, mScreen->h,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ((mScreen->flags & SDL_HWSURFACE) == 0) ? "software" : "hardware");
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Update specified framebuffer area. The coordinates can either be
c869993e79c1eafbec61a56bf6cea848fe754c71xy * relative to the guest framebuffer or relative to the screen.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @remarks Must be called from the SDL thread on Linux!
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param x left column
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param y top row
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param w width in pixels
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param h height in pixels
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param fGuestRelative flag whether the above values are guest relative or screen relative;
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::update(int x, int y, int w, int h, bool fGuestRelative)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOXSDL_WITH_X11
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectEnter(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy Log(("Updates %d, %d,%d %dx%d\n", mfUpdates, x, y, w, h));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!mfUpdates)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy RTCritSectLeave(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy Assert(mScreen);
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl Assert(mSurfVRAM);
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl if (!mScreen || !mSurfVRAM)
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl {
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl RTCritSectLeave(&mUpdateLock);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* the source and destination rectangles */
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Rect srcRect;
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Rect dstRect;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* this is how many pixels we have to cut off from the height for this specific blit */
c869993e79c1eafbec61a56bf6cea848fe754c71xy int yCutoffGuest = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy bool fPaintLabel = false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* if we have a label and no space for it, we have to cut off a bit */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (mLabelHeight && !mTopOffset)
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl {
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (y < (int)mLabelHeight)
c869993e79c1eafbec61a56bf6cea848fe754c71xy yCutoffGuest = mLabelHeight - y;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * If we get a SDL window relative update, we
c869993e79c1eafbec61a56bf6cea848fe754c71xy * just perform a full screen update to keep things simple.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @todo improve
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!fGuestRelative)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* repaint the label if necessary */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (y < (int)mLabelHeight)
c869993e79c1eafbec61a56bf6cea848fe754c71xy fPaintLabel = true;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy x = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy w = mGuestXRes;
c869993e79c1eafbec61a56bf6cea848fe754c71xy y = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy h = mGuestYRes;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy srcRect.x = x;
c869993e79c1eafbec61a56bf6cea848fe754c71xy srcRect.y = y + yCutoffGuest;
c869993e79c1eafbec61a56bf6cea848fe754c71xy srcRect.w = w;
c869993e79c1eafbec61a56bf6cea848fe754c71xy srcRect.h = RT_MAX(0, h - yCutoffGuest);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Destination rectangle is just offset by the label height.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * There are two cases though: label height is added to the
c869993e79c1eafbec61a56bf6cea848fe754c71xy * guest resolution (mTopOffset == mLabelHeight; yCutoffGuest == 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy * or the label cuts off a portion of the guest screen (mTopOffset == 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy * yCutoffGuest >= 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy dstRect.x = x + mCenterXOffset;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl#ifdef VBOX_SECURELABEL
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl dstRect.y = RT_MAX(mLabelHeight, y + yCutoffGuest + mTopOffset) + mCenterYOffset;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl#else
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl dstRect.y = y + yCutoffGuest + mTopOffset + mCenterYOffset;
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy dstRect.w = w;
c869993e79c1eafbec61a56bf6cea848fe754c71xy dstRect.h = RT_MAX(0, h - yCutoffGuest);
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Now we just blit
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_BlitSurface(mSurfVRAM, &srcRect, mScreen, &dstRect);
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* hardware surfaces don't need update notifications */
c869993e79c1eafbec61a56bf6cea848fe754c71xy#if defined(VBOX_WITH_SDL13)
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertRelease(mScreen->flags & SDL_PREALLOC);
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_SelectRenderer(mWindow);
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_DirtyTexture(mTexture, 1, &dstRect);
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertRelease(mRenderInfo.flags & SDL_RENDERER_PRESENTCOPY);
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_RenderCopy(mTexture, &dstRect, &dstRect);
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_RenderPresent();
c869993e79c1eafbec61a56bf6cea848fe754c71xy#else
c869993e79c1eafbec61a56bf6cea848fe754c71xy if ((mScreen->flags & SDL_HWSURFACE) == 0)
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_UpdateRect(mScreen, dstRect.x, dstRect.y, dstRect.w, dstRect.h);
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (fPaintLabel)
c869993e79c1eafbec61a56bf6cea848fe754c71xy paintSecureLabel(0, 0, 0, 0, false);
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl#endif
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl RTCritSectLeave(&mUpdateLock);
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl}
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl/**
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl * Repaint the whole framebuffer
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl *
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl * @remarks Must be called from the SDL thread!
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::repaint()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFB::repaint\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy update(0, 0, mScreen->w, mScreen->h, false /* fGuestRelative */);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Toggle fullscreen mode
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @remarks Must be called from the SDL thread!
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::setFullscreen(bool fFullscreen)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl LogFlow(("VBoxSDLFB::SetFullscreen: fullscreen: %d\n", fFullscreen));
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl mfFullscreen = fFullscreen;
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* only change the SDL resolution, do not touch the guest framebuffer */
c869993e79c1eafbec61a56bf6cea848fe754c71xy resizeSDL();
c869993e79c1eafbec61a56bf6cea848fe754c71xy repaint();
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Return the geometry of the host. This isn't very well tested but it seems
c869993e79c1eafbec61a56bf6cea848fe754c71xy * to work at least on Linux hosts.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::getFullscreenGeometry(uint32_t *width, uint32_t *height)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Rect **modes;
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* Get available fullscreen/hardware modes */
c869993e79c1eafbec61a56bf6cea848fe754c71xy modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
c869993e79c1eafbec61a56bf6cea848fe754c71xy Assert(modes != NULL);
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* -1 means that any mode is possible (usually non fullscreen) */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (modes != (SDL_Rect **)-1)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy /*
c869993e79c1eafbec61a56bf6cea848fe754c71xy * According to the SDL documentation, the API guarantees that the modes
c869993e79c1eafbec61a56bf6cea848fe754c71xy * are sorted from larger to smaller, so we just take the first entry as
c869993e79c1eafbec61a56bf6cea848fe754c71xy * the maximum.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * XXX Crude Xinerama hack :-/
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if ( modes[0]->w > (16*modes[0]->h/9)
c869993e79c1eafbec61a56bf6cea848fe754c71xy && modes[1]
c869993e79c1eafbec61a56bf6cea848fe754c71xy && modes[1]->h == modes[0]->h)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy *width = modes[1]->w;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *height = modes[1]->h;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy *width = modes[0]->w;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *height = modes[0]->w;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOX_SECURELABEL
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Setup the secure labeling parameters
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns VBox status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param height height of the secure label area in pixels
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param font file path fo the TrueType font file
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param pointsize font size in points
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyint VBoxSDLFB::initSecureLabel(uint32_t height, char *font, uint32_t pointsize, uint32_t labeloffs)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFB:initSecureLabel: new offset: %d pixels, new font: %s, new pointsize: %d\n",
c869993e79c1eafbec61a56bf6cea848fe754c71xy height, font, pointsize));
c869993e79c1eafbec61a56bf6cea848fe754c71xy mLabelHeight = height;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mLabelOffs = labeloffs;
c869993e79c1eafbec61a56bf6cea848fe754c71xy Assert(font);
c869993e79c1eafbec61a56bf6cea848fe754c71xy pTTF_Init();
c869993e79c1eafbec61a56bf6cea848fe754c71xy mLabelFont = pTTF_OpenFont(font, pointsize);
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!mLabelFont)
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsgFailed(("Failed to open TTF font file %s\n", font));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return VERR_OPEN_FAILED;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSecureLabelColorFG = 0x0000FF00;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSecureLabelColorBG = 0x00FFFF00;
c869993e79c1eafbec61a56bf6cea848fe754c71xy repaint();
c869993e79c1eafbec61a56bf6cea848fe754c71xy return VINF_SUCCESS;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Set the secure label text and repaint the label
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param text UTF-8 string of new label
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @remarks must be called from the SDL thread!
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::setSecureLabelText(const char *text)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSecureLabelText = text;
c869993e79c1eafbec61a56bf6cea848fe754c71xy paintSecureLabel(0, 0, 0, 0, true);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Sets the secure label background color.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param colorFG encoded RGB value for text
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param colorBG encored RGB value for background
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @remarks must be called from the SDL thread!
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::setSecureLabelColor(uint32_t colorFG, uint32_t colorBG)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSecureLabelColorFG = colorFG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSecureLabelColorBG = colorBG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy paintSecureLabel(0, 0, 0, 0, true);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Paint the secure label if required
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param fForce Force the repaint
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @remarks must be called from the SDL thread!
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyvoid VBoxSDLFB::paintSecureLabel(int x, int y, int w, int h, bool fForce)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy#ifdef VBOXSDL_WITH_X11
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsg(gSdlNativeThread == RTThreadNativeSelf(), ("Wrong thread! SDL is not threadsafe!\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* only when the function is present */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!pTTF_RenderUTF8_Solid)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return;
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* check if we can skip the paint */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!fForce && ((uint32_t)y > mLabelHeight))
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy return;
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* first fill the background */
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Rect rect = {0, 0, (Uint16)mScreen->w, (Uint16)mLabelHeight};
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_FillRect(mScreen, &rect, SDL_MapRGB(mScreen->format,
c869993e79c1eafbec61a56bf6cea848fe754c71xy (mSecureLabelColorBG & 0x00FF0000) >> 16, /* red */
c869993e79c1eafbec61a56bf6cea848fe754c71xy (mSecureLabelColorBG & 0x0000FF00) >> 8, /* green */
c869993e79c1eafbec61a56bf6cea848fe754c71xy mSecureLabelColorBG & 0x000000FF)); /* blue */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* now the text */
c869993e79c1eafbec61a56bf6cea848fe754c71xy if ( mLabelFont != NULL
c869993e79c1eafbec61a56bf6cea848fe754c71xy && !mSecureLabelText.isEmpty()
c869993e79c1eafbec61a56bf6cea848fe754c71xy )
c869993e79c1eafbec61a56bf6cea848fe754c71xy {
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Color clrFg = {(uint8_t)((mSecureLabelColorFG & 0x00FF0000) >> 16),
c869993e79c1eafbec61a56bf6cea848fe754c71xy (uint8_t)((mSecureLabelColorFG & 0x0000FF00) >> 8),
c869993e79c1eafbec61a56bf6cea848fe754c71xy (uint8_t)( mSecureLabelColorFG & 0x000000FF ), 0};
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_Surface *sText = (pTTF_RenderUTF8_Blended != NULL)
c869993e79c1eafbec61a56bf6cea848fe754c71xy ? pTTF_RenderUTF8_Blended(mLabelFont, mSecureLabelText.c_str(), clrFg)
c869993e79c1eafbec61a56bf6cea848fe754c71xy : pTTF_RenderUTF8_Solid(mLabelFont, mSecureLabelText.c_str(), clrFg);
c869993e79c1eafbec61a56bf6cea848fe754c71xy rect.x = 10;
c869993e79c1eafbec61a56bf6cea848fe754c71xy rect.y = mLabelOffs;
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_BlitSurface(sText, NULL, mScreen, &rect);
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_FreeSurface(sText);
c869993e79c1eafbec61a56bf6cea848fe754c71xy }
c869993e79c1eafbec61a56bf6cea848fe754c71xy /* make sure to update the screen */
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_UpdateRect(mScreen, 0, 0, mScreen->w, mLabelHeight);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy#endif /* VBOX_SECURELABEL */
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy// IFramebufferOverlay
c869993e79c1eafbec61a56bf6cea848fe754c71xy///////////////////////////////////////////////////////////////////////////////////
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl/**
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl * Constructor for the VBoxSDLFBOverlay class (IFramebufferOverlay implementation)
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param x Initial X offset for the overlay
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param y Initial Y offset for the overlay
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param width Initial width for the overlay
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param height Initial height for the overlay
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param visible Whether the overlay is initially visible
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param alpha Initial alpha channel value for the overlay
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyVBoxSDLFBOverlay::VBoxSDLFBOverlay(ULONG x, ULONG y, ULONG width, ULONG height,
c869993e79c1eafbec61a56bf6cea848fe754c71xy BOOL visible, VBoxSDLFB *aParent) :
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayX(x), mOverlayY(y), mOverlayWidth(width),
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayHeight(height), mOverlayVisible(visible),
c869993e79c1eafbec61a56bf6cea848fe754c71xy mParent(aParent)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Destructor for the VBoxSDLFBOverlay class.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyVBoxSDLFBOverlay::~VBoxSDLFBOverlay()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_FreeSurface(mBlendedBits);
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_FreeSurface(mOverlayBits);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Perform any initialisation of the overlay that can potentially fail
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns S_OK on success or the reason for the failure
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xyHRESULT VBoxSDLFBOverlay::init()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy mBlendedBits = SDL_CreateRGBSurface(SDL_ANYFORMAT, mOverlayWidth, mOverlayHeight, 32,
c869993e79c1eafbec61a56bf6cea848fe754c71xy 0x00ff0000, 0x0000ff00, 0x000000ff, 0);
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsgReturn(mBlendedBits != NULL, ("Failed to create an SDL surface\n"),
c869993e79c1eafbec61a56bf6cea848fe754c71xy E_OUTOFMEMORY);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayBits = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, mOverlayWidth,
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayHeight, 32, 0x00ff0000, 0x0000ff00,
c869993e79c1eafbec61a56bf6cea848fe754c71xy 0x000000ff, 0xff000000);
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsgReturn(mOverlayBits != NULL, ("Failed to create an SDL surface\n"),
c869993e79c1eafbec61a56bf6cea848fe754c71xy E_OUTOFMEMORY);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the current overlay X offset in pixels.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param x Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(X)(ULONG *x)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetX\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!x)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl *x = mOverlayX;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the current overlay height in pixels.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param height Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(Y)(ULONG *y)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetY\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!y)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl *y = mOverlayY;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl return S_OK;
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl}
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl/**
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl * Returns the current overlay width in pixels. In fact, this returns the line size.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param width Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(Width)(ULONG *width)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetWidth\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!width)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *width = mOverlayBits->pitch;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the current overlay line size in pixels.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl * @param lineSize Address of result buffer.
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(BytesPerLine)(ULONG *bytesPerLine)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetBytesPerLine\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!bytesPerLine)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *bytesPerLine = mOverlayBits->pitch;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the current overlay height in pixels.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param height Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(Height)(ULONG *height)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetHeight\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!height)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *height = mOverlayHeight;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns whether the overlay is currently visible.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param visible Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(Visible)(BOOL *visible)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetVisible\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!visible)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *visible = mOverlayVisible;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Sets whether the overlay is currently visible.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param visible New value.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMSETTER(Visible)(BOOL visible)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::SetVisible\n"));
fa25784ca4b51c206177d891a654f1d36a25d41fxy mOverlayVisible = visible;
fa25784ca4b51c206177d891a654f1d36a25d41fxy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
fa25784ca4b51c206177d891a654f1d36a25d41fxy * Returns the value of the global alpha channel.
fa25784ca4b51c206177d891a654f1d36a25d41fxy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param alpha Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(Alpha)(ULONG *alpha)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetAlpha\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_NOTIMPL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Sets whether the overlay is currently visible.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param alpha new value.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMSETTER(Alpha)(ULONG alpha)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::SetAlpha\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_NOTIMPL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the address of the framebuffer bits for writing to.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param alpha Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(Address)(ULONG *address)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetAddress\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!address)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *address = (uintptr_t) mOverlayBits->pixels;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the current colour depth. In fact, this is always 32bpp.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param bitsPerPixel Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(BitsPerPixel)(ULONG *bitsPerPixel)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetBitsPerPixel\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!bitsPerPixel)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *bitsPerPixel = 32;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the current pixel format. In fact, this is always RGB.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param pixelFormat Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(PixelFormat)(ULONG *pixelFormat)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetPixelFormat\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!pixelFormat)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *pixelFormat = FramebufferPixelFormat_FOURCC_RGB;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns whether the guest VRAM is used directly. In fact, this is always FALSE.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param usesGuestVRAM Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(UsesGuestVRAM)(BOOL *usesGuestVRAM)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetUsesGuestVRAM\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!usesGuestVRAM)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *usesGuestVRAM = FALSE;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the height reduction. In fact, this is always 0.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param heightReduction Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(HeightReduction)(ULONG *heightReduction)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetHeightReduction\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!heightReduction)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *heightReduction = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns the overlay for this framebuffer. Obviously, we return NULL here.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param overlay Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(Overlay)(IFramebufferOverlay **aOverlay)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetOverlay\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!aOverlay)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *aOverlay = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns associated window handle. We return NULL here.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param winId Address of result buffer.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::COMGETTER(WinId)(LONG64 *winId)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::GetWinId\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!winId)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_INVALIDARG;
c869993e79c1eafbec61a56bf6cea848fe754c71xy *winId = 0;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl/**
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl * Lock the overlay. This should not be used - lock the parent IFramebuffer instead.
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl *
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::Lock()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::Lock\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsgFailed(("You should not attempt to lock an IFramebufferOverlay object -\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy "lock the parent IFramebuffer object instead.\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_NOTIMPL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Unlock the overlay.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl */
8bb4b220fdb894543e41a5f9037898cf3c3f312bglSTDMETHODIMP VBoxSDLFBOverlay::Unlock()
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy LogFlow(("VBoxSDLFBOverlay::Unlock\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsgFailed(("You should not attempt to lock an IFramebufferOverlay object -\n"
c869993e79c1eafbec61a56bf6cea848fe754c71xy "lock the parent IFramebuffer object instead.\n"));
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_NOTIMPL;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Change the X and Y co-ordinates of the overlay area.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param x New X co-ordinate.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param y New Y co-ordinate.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::Move(ULONG x, ULONG y)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayX = x;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayY = y;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Notify the overlay that a section of the framebuffer has been redrawn.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param x X co-ordinate of upper left corner of modified area.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param y Y co-ordinate of upper left corner of modified area.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param w Width of modified area.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param h Height of modified area.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @retval finished Set if the operation has completed.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * All we do here is to send a request to the parent to update the affected area,
c869993e79c1eafbec61a56bf6cea848fe754c71xy * translating between our co-ordinate system and the parent's. It would be have
c869993e79c1eafbec61a56bf6cea848fe754c71xy * been better to call the parent directly, but such is life. We leave bounds
c869993e79c1eafbec61a56bf6cea848fe754c71xy * checking to the parent.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::NotifyUpdate(ULONG x, ULONG y,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG w, ULONG h)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy return mParent->NotifyUpdate(x + mOverlayX, y + mOverlayY, w, h);
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl/**
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl * Change the dimensions of the overlay.
8bb4b220fdb894543e41a5f9037898cf3c3f312bgl *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param pixelFormat Must be FramebufferPixelFormat_PixelFormatRGB32.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param vram Must be NULL.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param lineSize Ignored.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param w New overlay width.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param h New overlay height.
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @retval finished Set if the operation has completed.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::RequestResize(ULONG aScreenId, ULONG pixelFormat, ULONG vram,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG bitsPerPixel, ULONG bytesPerLine,
c869993e79c1eafbec61a56bf6cea848fe754c71xy ULONG w, ULONG h, BOOL *finished)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertReturn(pixelFormat == FramebufferPixelFormat_FOURCC_RGB, E_INVALIDARG);
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertReturn(vram == 0, E_INVALIDARG);
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertReturn(bitsPerPixel == 32, E_INVALIDARG);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayWidth = w;
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayHeight = h;
c869993e79c1eafbec61a56bf6cea848fe754c71xy SDL_FreeSurface(mOverlayBits);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mBlendedBits = SDL_CreateRGBSurface(SDL_ANYFORMAT, mOverlayWidth, mOverlayHeight, 32,
c869993e79c1eafbec61a56bf6cea848fe754c71xy 0x00ff0000, 0x0000ff00, 0x000000ff, 0);
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsgReturn(mBlendedBits != NULL, ("Failed to create an SDL surface\n"),
c869993e79c1eafbec61a56bf6cea848fe754c71xy E_OUTOFMEMORY);
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayBits = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, mOverlayWidth,
c869993e79c1eafbec61a56bf6cea848fe754c71xy mOverlayHeight, 32, 0x00ff0000, 0x0000ff00,
c869993e79c1eafbec61a56bf6cea848fe754c71xy 0x000000ff, 0xff000000);
c869993e79c1eafbec61a56bf6cea848fe754c71xy AssertMsgReturn(mOverlayBits != NULL, ("Failed to create an SDL surface\n"),
c869993e79c1eafbec61a56bf6cea848fe754c71xy E_OUTOFMEMORY);
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy
c869993e79c1eafbec61a56bf6cea848fe754c71xy/**
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Returns whether we like the given video mode.
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @returns COM status code
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param width video mode width in pixels
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param height video mode height in pixels
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @param bpp video mode bit depth in bits per pixel
c869993e79c1eafbec61a56bf6cea848fe754c71xy * @retval supported pointer to result variable
c869993e79c1eafbec61a56bf6cea848fe754c71xy *
c869993e79c1eafbec61a56bf6cea848fe754c71xy * Basically, we support anything with 32bpp.
c869993e79c1eafbec61a56bf6cea848fe754c71xy */
c869993e79c1eafbec61a56bf6cea848fe754c71xySTDMETHODIMP VBoxSDLFBOverlay::VideoModeSupported(ULONG width, ULONG height, ULONG bpp,
c869993e79c1eafbec61a56bf6cea848fe754c71xy BOOL *supported)
c869993e79c1eafbec61a56bf6cea848fe754c71xy{
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (!supported)
c869993e79c1eafbec61a56bf6cea848fe754c71xy return E_POINTER;
c869993e79c1eafbec61a56bf6cea848fe754c71xy if (bpp == 32)
c869993e79c1eafbec61a56bf6cea848fe754c71xy *supported = true;
c869993e79c1eafbec61a56bf6cea848fe754c71xy else
c869993e79c1eafbec61a56bf6cea848fe754c71xy *supported = false;
c869993e79c1eafbec61a56bf6cea848fe754c71xy return S_OK;
c869993e79c1eafbec61a56bf6cea848fe754c71xy}
c869993e79c1eafbec61a56bf6cea848fe754c71xy