Commit 4c5e8c5ce8a874880bc403ef153285f54dbbd960

Authored by blueswir1
1 parent 6fa724a3

Fix VGA screen dump

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6159 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 86 additions and 27 deletions
hw/vga.c
@@ -1223,6 +1223,35 @@ static const uint8_t cursor_glyph[32 * 4] = { @@ -1223,6 +1223,35 @@ static const uint8_t cursor_glyph[32 * 4] = {
1223 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1223 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1224 }; 1224 };
1225 1225
  1226 +static void vga_get_text_resolution(VGAState *s, int *pwidth, int *pheight,
  1227 + int *pcwidth, int *pcheight)
  1228 +{
  1229 + int width, cwidth, height, cheight;
  1230 +
  1231 + /* total width & height */
  1232 + cheight = (s->cr[9] & 0x1f) + 1;
  1233 + cwidth = 8;
  1234 + if (!(s->sr[1] & 0x01))
  1235 + cwidth = 9;
  1236 + if (s->sr[1] & 0x08)
  1237 + cwidth = 16; /* NOTE: no 18 pixel wide */
  1238 + width = (s->cr[0x01] + 1);
  1239 + if (s->cr[0x06] == 100) {
  1240 + /* ugly hack for CGA 160x100x16 - explain me the logic */
  1241 + height = 100;
  1242 + } else {
  1243 + height = s->cr[0x12] |
  1244 + ((s->cr[0x07] & 0x02) << 7) |
  1245 + ((s->cr[0x07] & 0x40) << 3);
  1246 + height = (height + 1) / cheight;
  1247 + }
  1248 +
  1249 + *pwidth = width;
  1250 + *pheight = height;
  1251 + *pcwidth = cwidth;
  1252 + *pcheight = cheight;
  1253 +}
  1254 +
1226 /* 1255 /*
1227 * Text mode update 1256 * Text mode update
1228 * Missing: 1257 * Missing:
@@ -1275,24 +1304,8 @@ static void vga_draw_text(VGAState *s, int full_update) @@ -1275,24 +1304,8 @@ static void vga_draw_text(VGAState *s, int full_update)
1275 line_offset = s->line_offset; 1304 line_offset = s->line_offset;
1276 s1 = s->vram_ptr + (s->start_addr * 4); 1305 s1 = s->vram_ptr + (s->start_addr * 4);
1277 1306
1278 - /* total width & height */  
1279 - cheight = (s->cr[9] & 0x1f) + 1;  
1280 - cw = 8;  
1281 - if (!(s->sr[1] & 0x01))  
1282 - cw = 9;  
1283 - if (s->sr[1] & 0x08)  
1284 - cw = 16; /* NOTE: no 18 pixel wide */ 1307 + vga_get_text_resolution(s, &width, &height, &cw, &cheight);
1285 x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3); 1308 x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
1286 - width = (s->cr[0x01] + 1);  
1287 - if (s->cr[0x06] == 100) {  
1288 - /* ugly hack for CGA 160x100x16 - explain me the logic */  
1289 - height = 100;  
1290 - } else {  
1291 - height = s->cr[0x12] |  
1292 - ((s->cr[0x07] & 0x02) << 7) |  
1293 - ((s->cr[0x07] & 0x40) << 3);  
1294 - height = (height + 1) / cheight;  
1295 - }  
1296 if ((height * width) > CH_ATTR_SIZE) { 1309 if ((height * width) > CH_ATTR_SIZE) {
1297 /* better than nothing: exit if transient size is too big */ 1310 /* better than nothing: exit if transient size is too big */
1298 return; 1311 return;
@@ -2542,11 +2555,29 @@ int ppm_save(const char *filename, uint8_t *data, @@ -2542,11 +2555,29 @@ int ppm_save(const char *filename, uint8_t *data,
2542 return 0; 2555 return 0;
2543 } 2556 }
2544 2557
2545 -/* save the vga display in a PPM image even if no display is  
2546 - available */  
2547 -static void vga_screen_dump(void *opaque, const char *filename) 2558 +static void vga_screen_dump_blank(VGAState *s, const char *filename)
  2559 +{
  2560 + FILE *f;
  2561 + unsigned int y, x, w, h;
  2562 +
  2563 + w = s->last_scr_width * sizeof(uint32_t);
  2564 + h = s->last_scr_height;
  2565 +
  2566 + f = fopen(filename, "wb");
  2567 + if (!f)
  2568 + return;
  2569 + fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
  2570 + for (y = 0; y < h; y++) {
  2571 + for (x = 0; x < w; x++) {
  2572 + fputc(0, f);
  2573 + }
  2574 + }
  2575 + fclose(f);
  2576 +}
  2577 +
  2578 +static void vga_screen_dump_common(VGAState *s, const char *filename,
  2579 + int w, int h)
2548 { 2580 {
2549 - VGAState *s = (VGAState *)opaque;  
2550 DisplayState *saved_ds, ds1, *ds = &ds1; 2581 DisplayState *saved_ds, ds1, *ds = &ds1;
2551 2582
2552 /* XXX: this is a little hackish */ 2583 /* XXX: this is a little hackish */
@@ -2559,14 +2590,42 @@ static void vga_screen_dump(void *opaque, const char *filename) @@ -2559,14 +2590,42 @@ static void vga_screen_dump(void *opaque, const char *filename)
2559 ds->dpy_refresh = vga_save_dpy_refresh; 2590 ds->dpy_refresh = vga_save_dpy_refresh;
2560 ds->depth = 32; 2591 ds->depth = 32;
2561 2592
  2593 + ds->linesize = w * sizeof(uint32_t);
  2594 + ds->data = qemu_mallocz(h * ds->linesize);
2562 s->ds = ds; 2595 s->ds = ds;
2563 s->graphic_mode = -1; 2596 s->graphic_mode = -1;
2564 vga_update_display(s); 2597 vga_update_display(s);
2565 -  
2566 - if (ds_get_data(ds)) {  
2567 - ppm_save(filename, ds_get_data(ds), vga_save_w, vga_save_h,  
2568 - ds_get_linesize(s->ds));  
2569 - qemu_free(ds_get_data(ds));  
2570 - } 2598 + ppm_save(filename, ds->data, w, h, ds->linesize);
  2599 + qemu_free(ds->data);
2571 s->ds = saved_ds; 2600 s->ds = saved_ds;
2572 } 2601 }
  2602 +
  2603 +static void vga_screen_dump_graphic(VGAState *s, const char *filename)
  2604 +{
  2605 + int w, h;
  2606 +
  2607 + s->get_resolution(s, &w, &h);
  2608 + vga_screen_dump_common(s, filename, w, h);
  2609 +}
  2610 +
  2611 +static void vga_screen_dump_text(VGAState *s, const char *filename)
  2612 +{
  2613 + int w, h, cwidth, cheight;
  2614 +
  2615 + vga_get_text_resolution(s, &w, &h, &cwidth, &cheight);
  2616 + vga_screen_dump_common(s, filename, w * cwidth, h * cheight);
  2617 +}
  2618 +
  2619 +/* save the vga display in a PPM image even if no display is
  2620 + available */
  2621 +static void vga_screen_dump(void *opaque, const char *filename)
  2622 +{
  2623 + VGAState *s = (VGAState *)opaque;
  2624 +
  2625 + if (!(s->ar_index & 0x20))
  2626 + vga_screen_dump_blank(s, filename);
  2627 + else if (s->gr[6] & 1)
  2628 + vga_screen_dump_graphic(s, filename);
  2629 + else
  2630 + vga_screen_dump_text(s, filename);
  2631 +}