Changeset 38804 in vbox for trunk/src/VBox/Devices/Graphics
- Timestamp:
- Sep 20, 2011 2:34:02 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA.cpp
r38803 r38804 4112 4112 } 4113 4113 4114 4115 /** 4116 * Prints a separator line. 4117 * 4118 * @param pHlp Callback functions for doing output. 4119 * @param cCols The number of columns. 4120 * @param pszTitle The title text, NULL if none. 4121 */ 4122 static void vgaInfoTextPrintSeparatorLine(PCDBGFINFOHLP pHlp, uint32_t cCols, const char *pszTitle) 4123 { 4124 if (pszTitle) 4125 { 4126 size_t cchTitle = strlen(pszTitle); 4127 if (cchTitle + 6 >= cCols) 4128 { 4129 pHlp->pfnPrintf(pHlp, "-- %s --", pszTitle); 4130 cCols = 0; 4131 } 4132 else 4133 { 4134 uint32_t cchLeft = (cCols - cchTitle - 2) / 2; 4135 cCols -= cchLeft + cchTitle + 2; 4136 while (cchLeft-- > 0) 4137 pHlp->pfnPrintf(pHlp, "-"); 4138 pHlp->pfnPrintf(pHlp, " %s ", pszTitle); 4139 } 4140 } 4141 4142 while (cCols-- > 0) 4143 pHlp->pfnPrintf(pHlp, "-"); 4144 pHlp->pfnPrintf(pHlp, "\n"); 4145 } 4146 4147 4148 /** 4149 * Worker for vgaInfoText. 4150 * 4151 * @param pThis The vga state. 4152 * @param pHlp Callback functions for doing output. 4153 * @param offStart Where to start dumping (relative to the VRAM). 4154 * @param cbLine The source line length (aka line_offset). 4155 * @param cCols The number of columns on the screen. 4156 * @param cRows The number of rows to dump. 4157 * @param iScrBegin The row at which the current screen output starts. 4158 * @param iScrEnd The row at which the current screen output end 4159 * (exclusive). 4160 */ 4161 static void vgaInfoTextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, 4162 uint32_t offStart, uint32_t cbLine, 4163 uint32_t cCols, uint32_t cRows, 4164 uint32_t iScrBegin, uint32_t iScrEnd) 4165 { 4166 /* Title, */ 4167 char szTitle[32]; 4168 if (iScrBegin || iScrEnd < cRows) 4169 RTStrPrintf(szTitle, sizeof(szTitle), "%ux%u (+%u before, +%u after)", 4170 cCols, iScrEnd - iScrBegin, iScrBegin, cRows - iScrEnd); 4171 else 4172 RTStrPrintf(szTitle, sizeof(szTitle), "%ux%u", cCols, iScrEnd - iScrBegin); 4173 4174 /* Do the dumping. */ 4175 uint8_t const *pbSrcOuter = pThis->CTX_SUFF(vram_ptr) + offStart; 4176 uint32_t iRow; 4177 for (iRow = 0; iRow < cRows; iRow++, pbSrcOuter += cbLine) 4178 { 4179 if ((uintptr_t)(pbSrcOuter + cbLine - pThis->CTX_SUFF(vram_ptr)) > pThis->vram_size) { 4180 pHlp->pfnPrintf(pHlp, "The last %u row/rows is/are outside the VRAM.\n", cRows - iRow); 4181 break; 4182 } 4183 4184 if (iRow == 0) 4185 vgaInfoTextPrintSeparatorLine(pHlp, cCols, szTitle); 4186 else if (iRow == iScrBegin) 4187 vgaInfoTextPrintSeparatorLine(pHlp, cCols, "screen start"); 4188 else if (iRow == iScrEnd) 4189 vgaInfoTextPrintSeparatorLine(pHlp, cCols, "screen end"); 4190 4191 uint8_t const *pbSrc = pbSrcOuter; 4192 for (uint32_t iCol = 0; iCol < cCols; ++iCol) 4193 { 4194 if (RT_C_IS_PRINT(*pbSrc)) 4195 pHlp->pfnPrintf(pHlp, "%c", *pbSrc); 4196 else 4197 pHlp->pfnPrintf(pHlp, "."); 4198 pbSrc += 8; /* chars are spaced 8 bytes apart */ 4199 } 4200 pHlp->pfnPrintf(pHlp, "\n"); 4201 } 4202 4203 /* Final separator. */ 4204 vgaInfoTextPrintSeparatorLine(pHlp, cCols, NULL); 4205 } 4206 4207 4114 4208 /** 4115 4209 * Info handler, device version. Dumps VGA memory formatted as … … 4123 4217 { 4124 4218 PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE); 4219 4220 /* 4221 * Parse args. 4222 */ 4223 bool fAll = true; 4224 if (pszArgs && *pszArgs) 4225 { 4226 if (!strcmp(pszArgs, "all")) 4227 fAll = true; 4228 else if (!strcmp(pszArgs, "scr") || !strcmp(pszArgs, "screen")) 4229 fAll = false; 4230 else 4231 { 4232 pHlp->pfnPrintf(pHlp, "Invalid argument: '%s'\n", pszArgs); 4233 return; 4234 } 4235 } 4236 4237 /* 4238 * Check that we're in text mode and that the VRAM is accessible. 4239 */ 4125 4240 if (!(pThis->gr[6] & 1)) 4126 4241 { … … 4139 4254 uint32_t offStart; 4140 4255 uint32_t uLineCompareIgn; 4141 uint32_t uVDisp;4142 uint32_t uCharHeight;4143 uint32_t uLines;4144 uint32_t uDblScan;4145 4146 4256 vga_get_offsets(pThis, &cbLine, &offStart, &uLineCompareIgn); 4147 4257 if (!cbLine) 4148 4258 cbLine = 80 * 8; 4149 4150 uVDisp = pThis->cr[0x12] + ((pThis->cr[7] & 2) << 7) + ((pThis->cr[7] & 0x40) << 4) + 1; 4151 uCharHeight = (pThis->cr[9] & 0x1f) + 1; 4152 uDblScan = pThis->cr[9] >> 7; 4153 uLines = uVDisp / (uCharHeight << uDblScan); 4154 if (uLines < 25) 4155 uLines = 25; 4156 4157 uint32_t cRows = offStart / cbLine + uLines; 4158 uint32_t cCols = cbLine / 8; 4159 if (cRows * cCols * 8 <= pThis->vram_size) 4160 { 4161 /* 4162 * Do the dumping. 4163 */ 4164 uint32_t row, col; 4165 for (col = 0; col < cCols; ++col) 4166 pHlp->pfnPrintf(pHlp, "-"); 4167 pHlp->pfnPrintf(pHlp, "\n"); 4168 for (row = 0; row < cRows; ++row) 4169 { 4170 if (offStart != 0 && pbSrc == pThis->vram_ptrR3 + offStart) 4171 for (col = 0; col < cCols; ++col) 4172 pHlp->pfnPrintf(pHlp, "-"); 4173 for (col = 0; col < cCols; ++col) 4174 { 4175 if (RT_C_IS_PRINT(*pbSrc)) 4176 pHlp->pfnPrintf(pHlp, "%c", *pbSrc); 4177 else 4178 pHlp->pfnPrintf(pHlp, "."); 4179 pbSrc += 8; /* chars are spaced 8 bytes apart */ 4180 } 4181 pbSrc += cbLine & 7; 4182 pHlp->pfnPrintf(pHlp, "\n"); 4183 } 4184 for (col = 0; col < cCols; ++col) 4185 pHlp->pfnPrintf(pHlp, "-"); 4186 pHlp->pfnPrintf(pHlp, "\n"); 4259 offStart *= 8; 4260 4261 uint32_t uVDisp = pThis->cr[0x12] + ((pThis->cr[7] & 2) << 7) + ((pThis->cr[7] & 0x40) << 4) + 1; 4262 uint32_t uCharHeight = (pThis->cr[9] & 0x1f) + 1; 4263 uint32_t uDblScan = pThis->cr[9] >> 7; 4264 uint32_t cScrRows = uVDisp / (uCharHeight << uDblScan); 4265 if (cScrRows < 25) 4266 cScrRows = 25; 4267 uint32_t iScrBegin = offStart / cbLine; 4268 uint32_t cRows = iScrBegin + cScrRows; 4269 uint32_t cCols = cbLine / 8; 4270 4271 if (fAll) { 4272 vgaInfoTextWorker(pThis, pHlp, offStart - iScrBegin * cbLine, cbLine, 4273 cCols, cRows, iScrBegin, iScrBegin + cScrRows); 4274 } else { 4275 vgaInfoTextWorker(pThis, pHlp, offStart, cbLine, cCols, cScrRows, 0, cScrRows); 4187 4276 } 4188 else4189 pHlp->pfnPrintf(pHlp, "Outside VRAM! (%ux%u)\n", cRows, cCols);4190 4277 } 4191 4278 else … … 4195 4282 pHlp->pfnPrintf(pHlp, "Not in text mode!\n"); 4196 4283 } 4284 4197 4285 4198 4286 /** … … 4211 4299 Assert(sizeof(s->sr) >= 8); 4212 4300 for (i = 0; i < 5; ++i) 4213 {4214 4301 pHlp->pfnPrintf(pHlp, " SR%02X:%02X", i, s->sr[i]); 4215 }4216 4302 pHlp->pfnPrintf(pHlp, "\n"); 4217 4303 } 4304 4218 4305 4219 4306 /** … … 4248 4335 } 4249 4336 4337 4250 4338 /** 4251 4339 * Info handler, device version. Dumps VGA Graphics Controller registers. … … 4268 4356 pHlp->pfnPrintf(pHlp, "\n"); 4269 4357 } 4358 4270 4359 4271 4360 /** … … 4316 4405 } 4317 4406 } 4407 4318 4408 4319 4409 /** … … 4347 4437 } 4348 4438 4439 4349 4440 /* -=-=-=-=-=- Ring 3: IBase -=-=-=-=-=- */ 4350 4441 … … 4468 4559 } 4469 4560 4470 /* Internal worker called under pThis->lock. */ 4561 4562 /** 4563 * Internal vgaPortUpdateDisplayAll worker called under pThis->lock. 4564 */ 4471 4565 static int updateDisplayAll(PVGASTATE pThis) 4472 4566 { … … 4475 4569 /* The dirty bits array has been just cleared, reset handlers as well. */ 4476 4570 if (pThis->GCPhysVRAM && pThis->GCPhysVRAM != NIL_RTGCPHYS32) 4477 {4478 4571 PGMHandlerPhysicalReset(PDMDevHlpGetVM(pDevIns), pThis->GCPhysVRAM); 4479 }4480 4572 if (pThis->fRemappedVGA) 4481 4573 { … … 4547 4639 return VINF_SUCCESS; 4548 4640 } 4641 4549 4642 4550 4643 /** … … 4580 4673 4581 4674 /* 4582 * The display connector interface is temporarily replaced with the fake one. 4583 */ 4584 PDMIDISPLAYCONNECTOR Connector; 4585 memset(&Connector, 0, sizeof (PDMIDISPLAYCONNECTOR)); 4586 4587 /* 4588 * Allocate the buffer for 32 bits per pixel bitmap. 4675 * Allocate the buffer for 32 bits per pixel bitmap 4676 * 4677 * Note! The size can't be zero or greater than the size of the VRAM. 4678 * Inconsistent VGA device state can cause the incorrect size values. 4589 4679 */ 4590 4680 size_t cbRequired = pThis->last_scr_width * 4 * pThis->last_scr_height; 4591 4592 /* The size can't be zero or greater than the size of the VRAM.4593 * Inconsistent VGA device state can cause the incorrect size values.4594 */4595 4681 if (cbRequired && cbRequired <= pThis->vram_size) 4596 4682 { 4597 4683 uint8_t *pu8Data = (uint8_t *)RTMemAlloc(cbRequired); 4598 4599 if (pu8Data == NULL) 4600 { 4601 rc = VERR_NO_MEMORY; 4602 } 4603 else 4684 if (pu8Data != NULL) 4604 4685 { 4605 4686 /* … … 4607 4688 * All other are already set to NULL. 4608 4689 */ 4609 4690 /* The display connector interface is temporarily replaced with the fake one. */ 4691 PDMIDISPLAYCONNECTOR Connector; 4692 RT_ZERO(Connector); 4610 4693 Connector.pu8Data = pu8Data; 4611 4694 Connector.cBits = 32; … … 4626 4709 pThis->fRenderVRAM = 1; /* force the guest VRAM rendering to the given buffer. */ 4627 4710 4628 /* Make the screenshot. 4711 /* 4712 * Make the screenshot. 4629 4713 * 4630 4714 * The second parameter is 'false' because the current display state is being rendered to an … … 4654 4738 /* If we do not return a success, then the data buffer must be freed. */ 4655 4739 RTMemFree(pu8Data); 4740 if (RT_SUCCESS_NP(rc)) 4741 { 4742 AssertMsgFailed(("%Rrc\n", rc)); 4743 rc = VERR_INTERNAL_ERROR_5; 4744 } 4656 4745 } 4657 4746 } 4747 else 4748 rc = VERR_NO_MEMORY; 4658 4749 } 4659 4750 else
Note:
See TracChangeset
for help on using the changeset viewer.