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 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 1256 * Text mode update
1228 1257 * Missing:
... ... @@ -1275,24 +1304,8 @@ static void vga_draw_text(VGAState *s, int full_update)
1275 1304 line_offset = s->line_offset;
1276 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 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 1309 if ((height * width) > CH_ATTR_SIZE) {
1297 1310 /* better than nothing: exit if transient size is too big */
1298 1311 return;
... ... @@ -2542,11 +2555,29 @@ int ppm_save(const char *filename, uint8_t *data,
2542 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 2581 DisplayState *saved_ds, ds1, *ds = &ds1;
2551 2582  
2552 2583 /* XXX: this is a little hackish */
... ... @@ -2559,14 +2590,42 @@ static void vga_screen_dump(void *opaque, const char *filename)
2559 2590 ds->dpy_refresh = vga_save_dpy_refresh;
2560 2591 ds->depth = 32;
2561 2592  
  2593 + ds->linesize = w * sizeof(uint32_t);
  2594 + ds->data = qemu_mallocz(h * ds->linesize);
2562 2595 s->ds = ds;
2563 2596 s->graphic_mode = -1;
2564 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 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 +}
... ...