VirtualBox

Changeset 24528 in vbox


Ignore:
Timestamp:
Nov 9, 2009 8:40:18 PM (15 years ago)
Author:
vboxsync
Message:

Saved state screenshot Main API prototype (xTracker 4364).

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/MachineImpl.cpp

    r24524 r24528  
    7373#include <VBox/param.h>
    7474#include <VBox/settings.h>
     75#include <VBox/ssm.h>
    7576
    7677#ifdef VBOX_WITH_GUEST_PROPS
     
    39173918}
    39183919
     3920/* @todo where is the right place for this? */
     3921#define sSSMDisplayScreenshotVer 0x00010001
     3922
     3923static int readSavedDisplayScreenshot(Utf8Str *pStateFilePath, uint32_t u32Type, uint8_t **ppu8Data, uint32_t *pcbData, uint32_t *pu32Width, uint32_t *pu32Height)
     3924{
     3925    /* @todo cache read data */
     3926    if (pStateFilePath->isEmpty())
     3927    {
     3928        /* No saved state data. */
     3929        return VERR_NOT_SUPPORTED;
     3930    }
     3931
     3932    uint8_t *pu8Data = NULL;
     3933    uint32_t cbData = 0;
     3934    uint32_t u32Width = 0;
     3935    uint32_t u32Height = 0;
     3936
     3937    PSSMHANDLE pSSM;
     3938    int rc = SSMR3Open(pStateFilePath->raw(), 0 /*fFlags*/, &pSSM);
     3939    if (RT_SUCCESS(rc))
     3940    {
     3941        uint32_t uVersion;
     3942        rc = SSMR3Seek(pSSM, "DisplayScreenshot", 1100 /*iInstance*/, &uVersion);
     3943        if (RT_SUCCESS(rc))
     3944        {
     3945            if (uVersion == sSSMDisplayScreenshotVer)
     3946            {
     3947                uint32_t cBlocks;
     3948                int rc = SSMR3GetU32(pSSM, &cBlocks);
     3949                AssertRCReturn(rc, rc);
     3950
     3951                for (uint32_t i = 0; i < cBlocks; i++)
     3952                {
     3953                    uint32_t cbBlock;
     3954                    rc = SSMR3GetU32(pSSM, &cbBlock);
     3955                    AssertRCBreak(rc);
     3956
     3957                    uint32_t typeOfBlock;
     3958                    rc = SSMR3GetU32(pSSM, &typeOfBlock);
     3959                    AssertRCBreak(rc);
     3960
     3961                    LogFlowFunc(("[%d] type %d, size %d bytes\n", i, typeOfBlock, cbBlock));
     3962
     3963                    if (typeOfBlock == u32Type)
     3964                    {
     3965                        if (cbBlock != 0)
     3966                        {
     3967                            pu8Data = (uint8_t *)RTMemAlloc(cbBlock);
     3968                            if (pu8Data == NULL)
     3969                            {
     3970                                rc = VERR_NO_MEMORY;
     3971                                break;
     3972                            }
     3973
     3974                            rc = SSMR3GetU32(pSSM, &u32Width);
     3975                            AssertRCBreak(rc);
     3976                            rc = SSMR3GetU32(pSSM, &u32Height);
     3977                            AssertRCBreak(rc);
     3978                            rc = SSMR3GetMem(pSSM, pu8Data, cbBlock);
     3979                            AssertRCBreak(rc);
     3980                            cbData = cbBlock;
     3981                        }
     3982                        else
     3983                        {
     3984                            /* No saved state data. */
     3985                            rc = VERR_NOT_SUPPORTED;
     3986                            break;
     3987                        }
     3988                    }
     3989                    else
     3990                    {
     3991                        if (cbBlock != 0)
     3992                        {
     3993                            rc = SSMR3Skip(pSSM, cbBlock);
     3994                            AssertRCBreak(rc);
     3995                        }
     3996                    }
     3997                }
     3998            }
     3999            else
     4000            {
     4001                rc = VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     4002            }
     4003        }
     4004
     4005        SSMR3Close(pSSM);
     4006    }
     4007
     4008    if (RT_SUCCESS(rc))
     4009    {
     4010        if (u32Type == 0 && cbData % 4 != 0)
     4011        {
     4012            /* Bitmap is 32bpp, so data is invalid. */
     4013            rc = VERR_SSM_UNEXPECTED_DATA;
     4014        }
     4015    }
     4016
     4017    if (RT_SUCCESS(rc))
     4018    {
     4019        *ppu8Data = pu8Data;
     4020        *pcbData = cbData;
     4021        *pu32Width = u32Width;
     4022        *pu32Height = u32Height;
     4023    }
     4024
     4025    return rc;
     4026}
     4027
     4028static void freeSavedDisplayScreenshot(uint8_t *pu8Data)
     4029{
     4030    /* @todo not necessary when caching is implemented. */
     4031    RTMemFree(pu8Data);
     4032}
     4033
    39194034STDMETHODIMP Machine::QuerySavedThumbnailSize(ULONG *aSize, ULONG *aWidth, ULONG *aHeight)
    39204035{
    3921     return setError (E_NOTIMPL, tr ("This feature is not implemented"));
     4036    LogFlowThisFunc(("\n"));
     4037
     4038    CheckComArgNotNull(aSize);
     4039    CheckComArgNotNull(aWidth);
     4040    CheckComArgNotNull(aHeight);
     4041
     4042    AutoCaller autoCaller(this);
     4043    CheckComRCReturnRC(autoCaller.rc());
     4044
     4045    AutoReadLock alock(this);
     4046
     4047    uint8_t *pu8Data = NULL;
     4048    uint32_t cbData = 0;
     4049    uint32_t u32Width = 0;
     4050    uint32_t u32Height = 0;
     4051
     4052    int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
     4053
     4054    if (RT_FAILURE(vrc))
     4055        return setError (VBOX_E_IPRT_ERROR,
     4056                         tr("Saved screenshot data is not available (%Rrc)"), vrc);
     4057
     4058    freeSavedDisplayScreenshot(pu8Data);
     4059
     4060    return S_OK;
    39224061}
    39234062
    39244063STDMETHODIMP Machine::ReadSavedThumbnail(BYTE *aAddress, ULONG aSize)
    39254064{
    3926     return setError (E_NOTIMPL, tr ("This feature is not implemented"));
     4065    LogFlowThisFunc(("\n"));
     4066
     4067    CheckComArgNotNull(aAddress);
     4068
     4069    AutoCaller autoCaller(this);
     4070    CheckComRCReturnRC(autoCaller.rc());
     4071
     4072    AutoReadLock alock(this);
     4073
     4074    uint8_t *pu8Data = NULL;
     4075    uint32_t cbData = 0;
     4076    uint32_t u32Width = 0;
     4077    uint32_t u32Height = 0;
     4078
     4079    int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
     4080
     4081    if (RT_FAILURE(vrc))
     4082        return setError (VBOX_E_IPRT_ERROR,
     4083                         tr("Saved screenshot data is not available (%Rrc)"), vrc);
     4084    if (aSize != cbData)
     4085        return setError (E_INVALIDARG,
     4086                         tr("Invalid size of data buffer: %d"), aSize);
     4087
     4088    memcpy(aAddress, pu8Data, cbData);
     4089
     4090    freeSavedDisplayScreenshot(pu8Data);
     4091
     4092    return S_OK;
    39274093}
    39284094
    39294095STDMETHODIMP Machine::ReadSavedThumbnailToArray(ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData))
    39304096{
    3931     return setError (E_NOTIMPL, tr ("This feature is not implemented"));
     4097    LogFlowThisFunc(("\n"));
     4098
     4099    CheckComArgNotNull(aWidth);
     4100    CheckComArgNotNull(aHeight);
     4101    CheckComArgSafeArrayNotNull(aData);
     4102
     4103    AutoCaller autoCaller(this);
     4104    CheckComRCReturnRC(autoCaller.rc());
     4105
     4106    AutoReadLock alock(this);
     4107
     4108    uint8_t *pu8Data = NULL;
     4109    uint32_t cbData = 0;
     4110    uint32_t u32Width = 0;
     4111    uint32_t u32Height = 0;
     4112
     4113    int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
     4114
     4115    if (RT_FAILURE(vrc))
     4116        return setError (VBOX_E_IPRT_ERROR,
     4117                         tr("Saved screenshot data is not available (%Rrc)"), vrc);
     4118
     4119    *aWidth = u32Width;
     4120    *aHeight = u32Height;
     4121
     4122    com::SafeArray<BYTE> bitmap(cbData);
     4123    /* Convert pixels to format expected by the API caller: [0] R, [1] G, [2] B, [3] A. */
     4124    for (unsigned i = 0; i < cbData; i += 4)
     4125    {
     4126        bitmap[i]     = pu8Data[i + 2];
     4127        bitmap[i + 1] = pu8Data[i + 1];
     4128        bitmap[i + 2] = pu8Data[i];
     4129        bitmap[i + 3] = 0xff;
     4130    }
     4131    bitmap.detachTo(ComSafeArrayOutArg(aData));
     4132
     4133    freeSavedDisplayScreenshot(pu8Data);
     4134
     4135    return S_OK;
    39324136}
    39334137
    39344138STDMETHODIMP Machine::QuerySavedScreenshotPNGSize(ULONG *aSize, ULONG *aWidth, ULONG *aHeight)
    39354139{
    3936     return setError (E_NOTIMPL, tr ("This feature is not implemented"));
     4140    LogFlowThisFunc(("\n"));
     4141
     4142    CheckComArgNotNull(aSize);
     4143    CheckComArgNotNull(aWidth);
     4144    CheckComArgNotNull(aHeight);
     4145
     4146    AutoCaller autoCaller(this);
     4147    CheckComRCReturnRC(autoCaller.rc());
     4148
     4149    AutoReadLock alock(this);
     4150
     4151    uint8_t *pu8Data = NULL;
     4152    uint32_t cbData = 0;
     4153    uint32_t u32Width = 0;
     4154    uint32_t u32Height = 0;
     4155
     4156    int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
     4157
     4158    if (RT_FAILURE(vrc))
     4159        return setError (VBOX_E_IPRT_ERROR,
     4160                         tr("Saved screenshot data is not available (%Rrc)"), vrc);
     4161
     4162    freeSavedDisplayScreenshot(pu8Data);
     4163
     4164    return S_OK;
    39374165}
    39384166
    39394167STDMETHODIMP Machine::ReadSavedScreenshotPNG(BYTE *aAddress, ULONG aSize)
    39404168{
    3941     return setError (E_NOTIMPL, tr ("This feature is not implemented"));
     4169    LogFlowThisFunc(("\n"));
     4170
     4171    CheckComArgNotNull(aAddress);
     4172
     4173    AutoCaller autoCaller(this);
     4174    CheckComRCReturnRC(autoCaller.rc());
     4175
     4176    AutoReadLock alock(this);
     4177
     4178    uint8_t *pu8Data = NULL;
     4179    uint32_t cbData = 0;
     4180    uint32_t u32Width = 0;
     4181    uint32_t u32Height = 0;
     4182
     4183    int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
     4184
     4185    if (RT_FAILURE(vrc))
     4186        return setError (VBOX_E_IPRT_ERROR,
     4187                         tr("Saved screenshot data is not available (%Rrc)"), vrc);
     4188    if (aSize != cbData)
     4189        return setError (E_INVALIDARG,
     4190                         tr("Invalid size of data buffer: %d"), aSize);
     4191
     4192    memcpy(aAddress, pu8Data, cbData);
     4193
     4194    freeSavedDisplayScreenshot(pu8Data);
     4195
     4196    return S_OK;
    39424197}
    39434198
    39444199STDMETHODIMP Machine::ReadSavedScreenshotPNGToArray(ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData))
    39454200{
    3946     return setError (E_NOTIMPL, tr ("This feature is not implemented"));
     4201    LogFlowThisFunc(("\n"));
     4202
     4203    CheckComArgNotNull(aWidth);
     4204    CheckComArgNotNull(aHeight);
     4205    CheckComArgSafeArrayNotNull(aData);
     4206
     4207    AutoCaller autoCaller(this);
     4208    CheckComRCReturnRC(autoCaller.rc());
     4209
     4210    AutoReadLock alock(this);
     4211
     4212    uint8_t *pu8Data = NULL;
     4213    uint32_t cbData = 0;
     4214    uint32_t u32Width = 0;
     4215    uint32_t u32Height = 0;
     4216
     4217    int vrc = readSavedDisplayScreenshot(&mSSData->mStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
     4218
     4219    if (RT_FAILURE(vrc))
     4220        return setError (VBOX_E_IPRT_ERROR,
     4221                         tr("Saved screenshot data is not available (%Rrc)"), vrc);
     4222
     4223    *aWidth = u32Width;
     4224    *aHeight = u32Height;
     4225
     4226    com::SafeArray<BYTE> png(cbData);
     4227    for (unsigned i = 0; i < cbData; i++)
     4228        png[i] = pu8Data[i];
     4229    png.detachTo(ComSafeArrayOutArg(aData));
     4230
     4231    freeSavedDisplayScreenshot(pu8Data);
     4232
     4233    return S_OK;
    39474234}
    39484235
  • trunk/src/VBox/Main/Makefile.kmk

    r24457 r24528  
    257257
    258258VBoxSVC_LIBS += \
     259        $(LIB_VMM) \
    259260        $(LIB_DDU)
    260261VBoxSVC_LIBS.darwin = \
    261         $(LIB_VMM) \
    262262        $(LIB_REM)
    263263VBoxSVC_LIBS.solaris = \
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette