VirtualBox

source: vbox/trunk/src/VBox/Main/src-all/DisplayUtils.cpp

Last change on this file was 106061, checked in by vboxsync, 8 weeks ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
Line 
1/* $Id: DisplayUtils.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * Implementation of IDisplay helpers, currently only used in VBoxSVC.
4 */
5
6/*
7 * Copyright (C) 2010-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include <DisplayUtils.h>
29
30#include <iprt/log.h>
31#include <VBox/err.h>
32#include <VBox/vmm/ssm.h>
33#include <VBoxVideo.h>
34
35int readSavedDisplayScreenshot(SsmStream &ssmStream, const Utf8Str &strStateFilePath,
36 uint32_t u32Type, uint8_t **ppu8Data, uint32_t *pcbData,
37 uint32_t *pu32Width, uint32_t *pu32Height)
38{
39 LogFlowFunc(("u32Type = %d [%s]\n", u32Type, strStateFilePath.c_str()));
40
41 /** @todo cache read data */
42 if (strStateFilePath.isEmpty())
43 {
44 /* No saved state data. */
45 return VERR_NOT_SUPPORTED;
46 }
47
48 uint8_t *pu8Data = NULL;
49 uint32_t cbData = 0;
50 uint32_t u32Width = 0;
51 uint32_t u32Height = 0;
52
53 PSSMHANDLE pSSM;
54 int vrc = ssmStream.open(strStateFilePath.c_str(), false /*fWrite*/, &pSSM);
55 if (RT_SUCCESS(vrc))
56 {
57 uint32_t uVersion;
58 vrc = SSMR3Seek(pSSM, "DisplayScreenshot", 1100 /*iInstance*/, &uVersion);
59 if (RT_SUCCESS(vrc))
60 {
61 if (uVersion == sSSMDisplayScreenshotVer)
62 {
63 uint32_t cBlocks;
64 vrc = SSMR3GetU32(pSSM, &cBlocks);
65 AssertRCReturn(vrc, vrc);
66
67 for (uint32_t i = 0; i < cBlocks; i++)
68 {
69 uint32_t cbBlock;
70 vrc = SSMR3GetU32(pSSM, &cbBlock);
71 AssertRCBreak(vrc);
72
73 uint32_t typeOfBlock;
74 vrc = SSMR3GetU32(pSSM, &typeOfBlock);
75 AssertRCBreak(vrc);
76
77 LogFlowFunc(("[%d] type %d, size %d bytes\n", i, typeOfBlock, cbBlock));
78
79 if (typeOfBlock == u32Type)
80 {
81 if (cbBlock > 2 * sizeof(uint32_t))
82 {
83 cbData = (uint32_t)(cbBlock - 2 * sizeof(uint32_t));
84 pu8Data = (uint8_t *)RTMemAlloc(cbData);
85 if (pu8Data == NULL)
86 {
87 vrc = VERR_NO_MEMORY;
88 break;
89 }
90
91 vrc = SSMR3GetU32(pSSM, &u32Width);
92 AssertRCBreak(vrc);
93 vrc = SSMR3GetU32(pSSM, &u32Height);
94 AssertRCBreak(vrc);
95 vrc = SSMR3GetMem(pSSM, pu8Data, cbData);
96 AssertRCBreak(vrc);
97 }
98 else
99 {
100 /* No saved state data. */
101 vrc = VERR_NOT_SUPPORTED;
102 }
103
104 break;
105 }
106 else
107 {
108 /* displaySSMSaveScreenshot did not write any data, if
109 * cbBlock was == 2 * sizeof (uint32_t).
110 */
111 if (cbBlock > 2 * sizeof (uint32_t))
112 {
113 vrc = SSMR3Skip(pSSM, cbBlock);
114 AssertRCBreak(vrc);
115 }
116 }
117 }
118 }
119 else
120 {
121 vrc = VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
122 }
123 }
124
125 ssmStream.close();
126 }
127
128 if (RT_SUCCESS(vrc))
129 {
130 if (u32Type == 0 && cbData % 4 != 0)
131 {
132 /* Bitmap is 32bpp, so data is invalid. */
133 vrc = VERR_SSM_UNEXPECTED_DATA;
134 }
135 }
136
137 if (RT_SUCCESS(vrc))
138 {
139 *ppu8Data = pu8Data;
140 *pcbData = cbData;
141 *pu32Width = u32Width;
142 *pu32Height = u32Height;
143 LogFlowFunc(("cbData %d, u32Width %d, u32Height %d\n", cbData, u32Width, u32Height));
144 }
145
146 LogFlowFunc(("vrc %Rrc\n", vrc));
147 return vrc;
148}
149
150void freeSavedDisplayScreenshot(uint8_t *pu8Data)
151{
152 /** @todo not necessary when caching is implemented. */
153 RTMemFree(pu8Data);
154}
155
156int readSavedGuestScreenInfo(SsmStream &ssmStream, const Utf8Str &strStateFilePath,
157 uint32_t u32ScreenId, uint32_t *pu32OriginX, uint32_t *pu32OriginY,
158 uint32_t *pu32Width, uint32_t *pu32Height, uint16_t *pu16Flags)
159{
160 LogFlowFunc(("u32ScreenId = %d [%s]\n", u32ScreenId, strStateFilePath.c_str()));
161
162 /** @todo cache read data */
163 if (strStateFilePath.isEmpty())
164 {
165 /* No saved state data. */
166 return VERR_NOT_SUPPORTED;
167 }
168
169 PSSMHANDLE pSSM;
170 int vrc = ssmStream.open(strStateFilePath.c_str(), false /*fWrite*/, &pSSM);
171 if (RT_SUCCESS(vrc))
172 {
173 uint32_t uVersion;
174 vrc = SSMR3Seek(pSSM, "DisplayData", 0 /*iInstance*/, &uVersion);
175 if (RT_SUCCESS(vrc))
176 {
177 /* Starting from sSSMDisplayVer2 we have pu32Width and pu32Height.
178 * Starting from sSSMDisplayVer3 we have all the rest of parameters we need. */
179 if (uVersion >= sSSMDisplayVer2)
180 {
181 uint32_t cMonitors;
182 SSMR3GetU32(pSSM, &cMonitors);
183 if (u32ScreenId > cMonitors)
184 {
185 vrc = VERR_INVALID_PARAMETER;
186 }
187 else
188 {
189 if (uVersion == sSSMDisplayVer2)
190 {
191 /* Skip all previous monitors, each 5 uint32_t, and the first 3 uint32_t entries. */
192 SSMR3Skip(pSSM, u32ScreenId * 5 * sizeof(uint32_t) + 3 * sizeof(uint32_t));
193 SSMR3GetU32(pSSM, pu32Width);
194 SSMR3GetU32(pSSM, pu32Height);
195 *pu32OriginX = 0;
196 *pu32OriginY = 0;
197 *pu16Flags = VBVA_SCREEN_F_ACTIVE;
198 }
199 else
200 {
201 /* Skip all previous monitors, each 8 uint32_t, and the first 3 uint32_t entries. */
202 SSMR3Skip(pSSM, u32ScreenId * 8 * sizeof(uint32_t) + 3 * sizeof(uint32_t));
203 SSMR3GetU32(pSSM, pu32Width);
204 SSMR3GetU32(pSSM, pu32Height);
205 SSMR3GetU32(pSSM, pu32OriginX);
206 SSMR3GetU32(pSSM, pu32OriginY);
207 uint32_t u32Flags = 0;
208 SSMR3GetU32(pSSM, &u32Flags);
209 *pu16Flags = (uint16_t)u32Flags;
210 }
211 }
212 }
213 else
214 {
215 vrc = VERR_NOT_SUPPORTED;
216 }
217 }
218
219 ssmStream.close();
220 }
221
222 LogFlowFunc(("vrc %Rrc\n", vrc));
223 return vrc;
224}
225
Note: See TracBrowser for help on using the repository browser.

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