9ae3a8
From b0abe7c2c3873172eee6020c49ca3a44567bb645 Mon Sep 17 00:00:00 2001
9ae3a8
From: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Date: Wed, 7 Aug 2013 09:12:44 +0200
9ae3a8
Subject: add qxl_screendump monitor command
9ae3a8
9ae3a8
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Message-id: <1375866764-17766-2-git-send-email-kraxel@redhat.com>
9ae3a8
Patchwork-id: 53033
9ae3a8
O-Subject: [RHEL-7 qemu-kvm PATCH 1/1] add qxl_screendump monitor command
9ae3a8
Bugzilla: 903910
9ae3a8
RH-Acked-by: Hans de Goede <hdegoede@redhat.com>
9ae3a8
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
RH-Acked-by: Michal Novotny <minovotn@redhat.com>
9ae3a8
9ae3a8
This patch ports the rhel-6 specific qxl_screendump command to rhel-7.
9ae3a8
qxl_screendump takes the device id as additional argument and thus can
9ae3a8
be used to take screenshots from non-primary displays.
9ae3a8
9ae3a8
The plan to get that functionality upstream in time failed, so we go for
9ae3a8
plan b and carry forward the rhel-6 specific qxl_screendump command.
9ae3a8
Thanks to the major console subsystem cleanups which made it upstream
9ae3a8
the implementation is (a) alot less hackier than the rhel-6 one and (b)
9ae3a8
not qxl-specific any more.  Given that qxl is the only graphic device
9ae3a8
which can work as secondary vga card the later is only a theoretical
9ae3a8
benefit though ;)
9ae3a8
9ae3a8
RHEL-6 commit: 1c6074d107dff93c7c7b0edfb5da871504802946
9ae3a8
9ae3a8
bugzilla: #903910 - RHEL7 does not have equivalent functionality for
9ae3a8
                    __com.redhat_qxl_screendump
9ae3a8
9ae3a8
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
9ae3a8
diff --git a/hmp-commands.hx b/hmp-commands.hx
9ae3a8
index 4f5a3fd..5cd6368 100644
9ae3a8
--- a/hmp-commands.hx
9ae3a8
+++ b/hmp-commands.hx
9ae3a8
@@ -242,6 +242,13 @@ ETEXI
9ae3a8
         .help       = "save screen into PPM image 'filename'",
9ae3a8
         .mhandler.cmd = hmp_screen_dump,
9ae3a8
     },
9ae3a8
+    {
9ae3a8
+        .name       = "__com.redhat_qxl_screendump",
9ae3a8
+        .args_type  = "id:s,filename:F",
9ae3a8
+        .params     = "id filename",
9ae3a8
+        .help       = "save screen from qxl device 'id' into PPM image 'filename'",
9ae3a8
+        .mhandler.cmd = hmp___com_redhat_qxl_screen_dump,
9ae3a8
+    },
9ae3a8
 
9ae3a8
 STEXI
9ae3a8
 @item screendump @var{filename}
9ae3a8
diff --git a/hmp.c b/hmp.c
9ae3a8
index 4fb76ec..3b3e7c7 100644
9ae3a8
--- a/hmp.c
9ae3a8
+++ b/hmp.c
9ae3a8
@@ -1328,6 +1328,16 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict)
9ae3a8
     hmp_handle_error(mon, &err);
9ae3a8
 }
9ae3a8
 
9ae3a8
+void hmp___com_redhat_qxl_screen_dump(Monitor *mon, const QDict *qdict)
9ae3a8
+{
9ae3a8
+    const char *id = qdict_get_str(qdict, "id");
9ae3a8
+    const char *filename = qdict_get_str(qdict, "filename");
9ae3a8
+    Error *err = NULL;
9ae3a8
+
9ae3a8
+    qmp___com_redhat_qxl_screendump(id, filename, &err);
9ae3a8
+    hmp_handle_error(mon, &err);
9ae3a8
+}
9ae3a8
+
9ae3a8
 void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
9ae3a8
 {
9ae3a8
     const char *uri = qdict_get_str(qdict, "uri");
9ae3a8
diff --git a/hmp.h b/hmp.h
9ae3a8
index 95fe76e..9b2c9ce 100644
9ae3a8
--- a/hmp.h
9ae3a8
+++ b/hmp.h
9ae3a8
@@ -80,6 +80,7 @@ void hmp_getfd(Monitor *mon, const QDict *qdict);
9ae3a8
 void hmp_closefd(Monitor *mon, const QDict *qdict);
9ae3a8
 void hmp_send_key(Monitor *mon, const QDict *qdict);
9ae3a8
 void hmp_screen_dump(Monitor *mon, const QDict *qdict);
9ae3a8
+void hmp___com_redhat_qxl_screen_dump(Monitor *mon, const QDict *qdict);
9ae3a8
 void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
9ae3a8
 void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
9ae3a8
 void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
9ae3a8
diff --git a/qapi-schema.json b/qapi-schema.json
9ae3a8
index 537f1d1..54a802d 100644
9ae3a8
--- a/qapi-schema.json
9ae3a8
+++ b/qapi-schema.json
9ae3a8
@@ -3123,6 +3123,21 @@
9ae3a8
 { 'command': 'screendump', 'data': {'filename': 'str'} }
9ae3a8
 
9ae3a8
 ##
9ae3a8
+# @__com.redhat_qxl_screendump:
9ae3a8
+#
9ae3a8
+# Write a PPM of secondary qxl devices to a file.
9ae3a8
+#
9ae3a8
+# @id: qxl device id
9ae3a8
+# @filename: the path of a new PPM file to store the image
9ae3a8
+#
9ae3a8
+# Returns: Nothing on success
9ae3a8
+#
9ae3a8
+# Since: never (rhel-only, not upstream)
9ae3a8
+##
9ae3a8
+{ 'command': '__com.redhat_qxl_screendump', 'data': { 'id' : 'str',
9ae3a8
+                                                      'filename': 'str' } }
9ae3a8
+
9ae3a8
+##
9ae3a8
 # @nbd-server-start:
9ae3a8
 #
9ae3a8
 # Start an NBD server listening on the given host and port.  Block
9ae3a8
diff --git a/qmp-commands.hx b/qmp-commands.hx
9ae3a8
index ffd130e..de5f394 100644
9ae3a8
--- a/qmp-commands.hx
9ae3a8
+++ b/qmp-commands.hx
9ae3a8
@@ -148,6 +148,11 @@ EQMP
9ae3a8
         .args_type  = "filename:F",
9ae3a8
         .mhandler.cmd_new = qmp_marshal_input_screendump,
9ae3a8
     },
9ae3a8
+    {
9ae3a8
+        .name       = "__com.redhat_qxl_screendump",
9ae3a8
+        .args_type  = "id:s,filename:F",
9ae3a8
+        .mhandler.cmd_new = qmp_marshal_input___com_redhat_qxl_screendump,
9ae3a8
+    },
9ae3a8
 
9ae3a8
 SQMP
9ae3a8
 screendump
9ae3a8
diff --git a/ui/console.c b/ui/console.c
9ae3a8
index 28bba6d..d422083 100644
9ae3a8
--- a/ui/console.c
9ae3a8
+++ b/ui/console.c
9ae3a8
@@ -328,6 +328,29 @@ void qmp_screendump(const char *filename, Error **errp)
9ae3a8
     ppm_save(filename, surface, errp);
9ae3a8
 }
9ae3a8
 
9ae3a8
+void qmp___com_redhat_qxl_screendump(const char *id, const char *filename, Error **errp)
9ae3a8
+{
9ae3a8
+    DeviceState *dev;
9ae3a8
+    QemuConsole *con;
9ae3a8
+    DisplaySurface *surface;
9ae3a8
+
9ae3a8
+    dev = qdev_find_recursive(sysbus_get_default(), id);
9ae3a8
+    if (NULL == dev) {
9ae3a8
+        error_set(errp, QERR_DEVICE_NOT_FOUND, id);
9ae3a8
+        return;
9ae3a8
+    }
9ae3a8
+
9ae3a8
+    con = qemu_console_lookup_by_device(dev);
9ae3a8
+    if (con == NULL) {
9ae3a8
+        error_setg(errp, "Device %s has no QemuConsole attached to it.", id);
9ae3a8
+        return;
9ae3a8
+    }
9ae3a8
+
9ae3a8
+    graphic_hw_update(con);
9ae3a8
+    surface = qemu_console_surface(con);
9ae3a8
+    ppm_save(filename, surface, errp);
9ae3a8
+}
9ae3a8
+
9ae3a8
 void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
9ae3a8
 {
9ae3a8
     if (!con) {