Revision 2c62f08d ui/console.c

b/ui/console.c
121 121
    /* Graphic console state.  */
122 122
    graphic_hw_update_ptr hw_update;
123 123
    graphic_hw_invalidate_ptr hw_invalidate;
124
    graphic_hw_screen_dump_ptr hw_screen_dump;
125 124
    graphic_hw_text_update_ptr hw_text_update;
126 125
    void *hw;
127 126
    int g_width, g_height;
......
188 187
    }
189 188
}
190 189

  
191
void qmp_screendump(const char *filename, Error **errp)
190
static void ppm_save(const char *filename, struct DisplaySurface *ds,
191
                     Error **errp)
192 192
{
193
    QemuConsole *previous_active_console;
194
    bool cswitch;
195

  
196
    previous_active_console = active_console;
197
    cswitch = previous_active_console && previous_active_console->index != 0;
193
    int width = pixman_image_get_width(ds->image);
194
    int height = pixman_image_get_height(ds->image);
195
    FILE *f;
196
    int y;
197
    int ret;
198
    pixman_image_t *linebuf;
198 199

  
199
    /* There is currently no way of specifying which screen we want to dump,
200
       so always dump the first one.  */
201
    if (cswitch) {
202
        console_select(0);
200
    trace_ppm_save(filename, ds);
201
    f = fopen(filename, "wb");
202
    if (!f) {
203
        error_setg(errp, "failed to open file '%s': %s", filename,
204
                   strerror(errno));
205
        return;
203 206
    }
204
    if (consoles[0] && consoles[0]->hw_screen_dump) {
205
        consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, errp);
206
    } else {
207
        error_setg(errp, "device doesn't support screendump");
207
    ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
208
    if (ret < 0) {
209
        linebuf = NULL;
210
        goto write_err;
211
    }
212
    linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
213
    for (y = 0; y < height; y++) {
214
        qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
215
        clearerr(f);
216
        ret = fwrite(pixman_image_get_data(linebuf), 1,
217
                     pixman_image_get_stride(linebuf), f);
218
        (void)ret;
219
        if (ferror(f)) {
220
            goto write_err;
221
        }
208 222
    }
209 223

  
210
    if (cswitch) {
211
        console_select(previous_active_console->index);
224
out:
225
    qemu_pixman_image_unref(linebuf);
226
    fclose(f);
227
    return;
228

  
229
write_err:
230
    error_setg(errp, "failed to write to file '%s': %s", filename,
231
               strerror(errno));
232
    unlink(filename);
233
    goto out;
234
}
235

  
236
void qmp_screendump(const char *filename, Error **errp)
237
{
238
    QemuConsole *con = consoles[0];
239
    DisplaySurface *surface;
240

  
241
    if (con == NULL) {
242
        error_setg(errp, "There is no QemuConsole I can screendump from.");
243
        return;
212 244
    }
245

  
246
    graphic_hw_update(con);
247
    surface = qemu_console_surface(con);
248
    ppm_save(filename, surface, errp);
213 249
}
214 250

  
215 251
void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
......
1411 1447

  
1412 1448
QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
1413 1449
                                  graphic_hw_invalidate_ptr invalidate,
1414
                                  graphic_hw_screen_dump_ptr screen_dump,
1415 1450
                                  graphic_hw_text_update_ptr text_update,
1416 1451
                                  void *opaque)
1417 1452
{
......
1425 1460
    s = new_console(ds, GRAPHIC_CONSOLE);
1426 1461
    s->hw_update = update;
1427 1462
    s->hw_invalidate = invalidate;
1428
    s->hw_screen_dump = screen_dump;
1429 1463
    s->hw_text_update = text_update;
1430 1464
    s->hw = opaque;
1431 1465

  

Also available in: Unified diff