All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/19]: QMP queue
@ 2012-09-05 18:58 Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 01/19] Add support for pretty-printing response in qmp-shell Luiz Capitulino
                   ` (19 more replies)
  0 siblings, 20 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

Let's get the ball rolling for QMP in 1.3 :)

This pull request contains the send-key command conversion, screendump qapi
conversion and a few fixes.

The changes (since f45ddd14209a4d1b95a4096d50a561b7f6270118) are available
in the following repository:

    git://repo.or.cz/qemu/qmp-unstable.git queue/qmp

Amos Kong (7):
      fix doc of using raw values with sendkey
      monitor: rename keyname '<' to 'less'
      hmp: rename arguments
      qapi: generate list struct and visit_list for enum
      qapi: add the QKeyCode enum
      monitor: move key_defs[] table and introduce two help functions
      qapi: convert sendkey

Daniel P. Berrange (1):
      Add support for pretty-printing response in qmp-shell

Luiz Capitulino (9):
      error: add error_setg()
      console: vga_hw_screen_dump_ptr: take Error argument
      qapi: convert screendump
      vga: ppm_save(): add error handling
      omap_lcdc: rename ppm_save() to omap_ppm_save()
      omap_lcdc: omap_ppm_save(): add error handling
      g364fb: g364fb_screen_dump(): add error handling
      tcx: tcx24_screen_dump(): add error handling
      tcx: tcx_screen_dump(): add error handling

Stefan Weil (2):
      qapi: Fix potential NULL pointer segfault
      json-parser: Fix potential NULL pointer segfault

 QMP/qmp-shell         |  46 ++++++---
 console.c             |   7 +-
 console.h             |  10 +-
 error.h               |   6 ++
 hmp-commands.hx       |  13 ++-
 hmp.c                 |  64 +++++++++++++
 hmp.h                 |   2 +
 hw/blizzard.c         |   4 +-
 hw/g364fb.c           |  55 ++++++++---
 hw/omap_lcdc.c        |  66 +++++++++----
 hw/qxl.c              |   7 +-
 hw/tcx.c              |  97 +++++++++++++++----
 hw/vga.c              |  38 ++++++--
 hw/vga_int.h          |   3 +-
 hw/vmware_vga.c       |   7 +-
 input.c               | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++
 monitor.c             | 251 +-------------------------------------------------
 qapi-schema.json      |  59 ++++++++++++
 qmp-commands.hx       |  33 ++++++-
 qobject.h             |   2 +-
 scripts/qapi-types.py |  16 +++-
 scripts/qapi-visit.py |  16 +++-
 22 files changed, 704 insertions(+), 349 deletions(-)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 01/19] Add support for pretty-printing response in qmp-shell
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 02/19] fix doc of using raw values with sendkey Luiz Capitulino
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

From: "Daniel P. Berrange" <berrange@redhat.com>

Add a '-p' arg to the QMP/qmp-shell test program, which uses
the python pprint module to pretty-print the dictionary
returned from a command

  $ qmp-shell -p /tmp/qemu
  Welcome to the QMP low-level shell!
  Connected to QEMU 1.1.50

  (QEMU) query-cpus
  {   u'return': [   {   u'CPU': 0,
                         u'current': True,
                         u'halted': True,
                         u'pc': 1048556,
                         u'thread_id': 7108}]}

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 QMP/qmp-shell | 46 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 33 insertions(+), 13 deletions(-)

diff --git a/QMP/qmp-shell b/QMP/qmp-shell
index 42dabc8..24b665c 100755
--- a/QMP/qmp-shell
+++ b/QMP/qmp-shell
@@ -33,6 +33,7 @@
 import qmp
 import readline
 import sys
+import pprint
 
 class QMPCompleter(list):
     def complete(self, text, state):
@@ -52,10 +53,11 @@ class QMPShellBadPort(QMPShellError):
 # TODO: QMPShell's interface is a bit ugly (eg. _fill_completion() and
 #       _execute_cmd()). Let's design a better one.
 class QMPShell(qmp.QEMUMonitorProtocol):
-    def __init__(self, address):
+    def __init__(self, address, pp=None):
         qmp.QEMUMonitorProtocol.__init__(self, self.__get_address(address))
         self._greeting = None
         self._completer = None
+        self._pp = pp
 
     def __get_address(self, arg):
         """
@@ -114,7 +116,11 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         if resp is None:
             print 'Disconnected'
             return False
-        print resp
+
+        if self._pp is not None:
+            self._pp.pprint(resp)
+        else:
+            print resp
         return True
 
     def connect(self):
@@ -222,22 +228,36 @@ def die(msg):
 def fail_cmdline(option=None):
     if option:
         sys.stderr.write('ERROR: bad command-line option \'%s\'\n' % option)
-    sys.stderr.write('qemu-shell [ -H ] < UNIX socket path> | < TCP address:port >\n')
+    sys.stderr.write('qemu-shell [ -p ] [ -H ] < UNIX socket path> | < TCP address:port >\n')
     sys.exit(1)
 
 def main():
     addr = ''
+    qemu = None
+    hmp = False
+    pp = None
+
     try:
-        if len(sys.argv) == 2:
-            qemu = QMPShell(sys.argv[1])
-            addr = sys.argv[1]
-        elif len(sys.argv) == 3:
-            if sys.argv[1] != '-H':
-                fail_cmdline(sys.argv[1])
-            qemu = HMPShell(sys.argv[2])
-            addr = sys.argv[2]
-        else:
-                fail_cmdline()
+        for arg in sys.argv[1:]:
+            if arg == "-H":
+                if qemu is not None:
+                    fail_cmdline(arg)
+                hmp = True
+            elif arg == "-p":
+                if pp is not None:
+                    fail_cmdline(arg)
+                pp = pprint.PrettyPrinter(indent=4)
+            else:
+                if qemu is not None:
+                    fail_cmdline(arg)
+                if hmp:
+                    qemu = HMPShell(arg)
+                else:
+                    qemu = QMPShell(arg, pp)
+                addr = arg
+
+        if qemu is None:
+            fail_cmdline()
     except QMPShellBadPort:
         die('bad port number in command-line')
 
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 02/19] fix doc of using raw values with sendkey
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 01/19] Add support for pretty-printing response in qmp-shell Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 03/19] monitor: rename keyname '<' to 'less' Luiz Capitulino
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: Amos Kong, qemu-devel

From: Amos Kong <akong@redhat.com>

(qemu) sendkey a
(qemu) sendkey 0x1e
(qemu) sendkey #0x1e
 unknown key: '#0x1e'

The last command doesn't work, '#' is not requested before
raw values, and the raw value in decimal format is not supported.

Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hmp-commands.hx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index f6104b0..6a70a9c 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -512,9 +512,9 @@ STEXI
 @item sendkey @var{keys}
 @findex sendkey
 
-Send @var{keys} to the emulator. @var{keys} could be the name of the
-key or @code{#} followed by the raw value in either decimal or hexadecimal
-format. Use @code{-} to press several keys simultaneously. Example:
+Send @var{keys} to the guest. @var{keys} could be the name of the
+key or the raw value in hexadecimal format. Use @code{-} to press
+several keys simultaneously. Example:
 @example
 sendkey ctrl-alt-f1
 @end example
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 03/19] monitor: rename keyname '<' to 'less'
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 01/19] Add support for pretty-printing response in qmp-shell Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 02/19] fix doc of using raw values with sendkey Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 04/19] hmp: rename arguments Luiz Capitulino
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: Amos Kong, qemu-devel

From: Amos Kong <akong@redhat.com>

There are many maps of keycode 0x56 in pc-bios/keymaps/*
  pc-bios/keymaps/common:less 0x56
  pc-bios/keymaps/common:greater 0x56 shift
  pc-bios/keymaps/common:bar 0x56 altgr
  pc-bios/keymaps/common:brokenbar 0x56 shift altgr

This patch just renamed '<' to 'less', QAPI might add new
variable by adding a prefix to keyname, '$PREFIX_<' is not
available, '$PREFIX_less' is ok.

For compatibility, convert user inputted '<' to 'less'.

Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 monitor.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/monitor.c b/monitor.c
index b17b1bb..c97c120 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1400,7 +1400,7 @@ static const KeyDef key_defs[] = {
     { 0x48, "kp_8" },
     { 0x49, "kp_9" },
 
-    { 0x56, "<" },
+    { 0x56, "less" },
 
     { 0x57, "f11" },
     { 0x58, "f12" },
@@ -1504,6 +1504,13 @@ static void do_sendkey(Monitor *mon, const QDict *qdict)
                 monitor_printf(mon, "too many keys\n");
                 return;
             }
+
+            /* Be compatible with old interface, convert user inputted "<" */
+            if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
+                pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
+                keyname_len = 4;
+            }
+
             keyname_buf[keyname_len] = 0;
             keycode = get_keycode(keyname_buf);
             if (keycode < 0) {
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 04/19] hmp: rename arguments
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (2 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 03/19] monitor: rename keyname '<' to 'less' Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 05/19] qapi: generate list struct and visit_list for enum Luiz Capitulino
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: Amos Kong, qemu-devel

From: Amos Kong <akong@redhat.com>

Rename 'string' to 'keys', rename 'hold_time' to 'hold-time'.

Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hmp-commands.hx |  2 +-
 monitor.c       | 14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 6a70a9c..bd0c6c9 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -502,7 +502,7 @@ ETEXI
 
     {
         .name       = "sendkey",
-        .args_type  = "string:s,hold_time:i?",
+        .args_type  = "keys:s,hold-time:i?",
         .params     = "keys [hold_ms]",
         .help       = "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)",
         .mhandler.cmd = do_sendkey,
diff --git a/monitor.c b/monitor.c
index c97c120..84176eb 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1480,9 +1480,9 @@ static void do_sendkey(Monitor *mon, const QDict *qdict)
     char keyname_buf[16];
     char *separator;
     int keyname_len, keycode, i;
-    const char *string = qdict_get_str(qdict, "string");
-    int has_hold_time = qdict_haskey(qdict, "hold_time");
-    int hold_time = qdict_get_try_int(qdict, "hold_time", -1);
+    const char *keys = qdict_get_str(qdict, "keys");
+    int has_hold_time = qdict_haskey(qdict, "hold-time");
+    int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
 
     if (nb_pending_keycodes > 0) {
         qemu_del_timer(key_timer);
@@ -1492,10 +1492,10 @@ static void do_sendkey(Monitor *mon, const QDict *qdict)
         hold_time = 100;
     i = 0;
     while (1) {
-        separator = strchr(string, '-');
-        keyname_len = separator ? separator - string : strlen(string);
+        separator = strchr(keys, '-');
+        keyname_len = separator ? separator - keys : strlen(keys);
         if (keyname_len > 0) {
-            pstrcpy(keyname_buf, sizeof(keyname_buf), string);
+            pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
             if (keyname_len > sizeof(keyname_buf) - 1) {
                 monitor_printf(mon, "invalid key: '%s...'\n", keyname_buf);
                 return;
@@ -1521,7 +1521,7 @@ static void do_sendkey(Monitor *mon, const QDict *qdict)
         }
         if (!separator)
             break;
-        string = separator + 1;
+        keys = separator + 1;
     }
     nb_pending_keycodes = i;
     /* key down events */
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 05/19] qapi: generate list struct and visit_list for enum
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (3 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 04/19] hmp: rename arguments Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 06/19] qapi: add the QKeyCode enum Luiz Capitulino
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: Amos Kong, qemu-devel

From: Amos Kong <akong@redhat.com>

Currently, if we define an 'enum' and use it in one command's
data, list struct for enum could not be generated, but it's
used in qmp function.

For example: KeyCodesList could not be generated.
>>> qapi-schema.json:
{ 'enum': 'KeyCodes',
  'data': [ 'shift', 'alt' ... ] }
{ 'command': 'sendkey',
  'data': { 'keys': ['KeyCodes'], '*hold-time': 'int' } }

>>> qmp-command.h:
void qmp_sendkey(KeyCodesList * keys, bool has_hold_time, int64_t
hold_time, Error **errp);

This patch lets qapi generate list struct and visit_list for enum.

Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 scripts/qapi-types.py | 16 +++++++++++++++-
 scripts/qapi-visit.py | 14 +++++++++++++-
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index cf601ae..49ef569 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -28,6 +28,16 @@ typedef struct %(name)sList
 ''',
                  name=name)
 
+def generate_fwd_enum_struct(name, members):
+    return mcgen('''
+typedef struct %(name)sList
+{
+    %(name)s value;
+    struct %(name)sList *next;
+} %(name)sList;
+''',
+                 name=name)
+
 def generate_struct(structname, fieldname, members):
     ret = mcgen('''
 struct %(name)s
@@ -276,7 +286,8 @@ for expr in exprs:
     if expr.has_key('type'):
         ret += generate_fwd_struct(expr['type'], expr['data'])
     elif expr.has_key('enum'):
-        ret += generate_enum(expr['enum'], expr['data'])
+        ret += generate_enum(expr['enum'], expr['data']) + "\n"
+        ret += generate_fwd_enum_struct(expr['enum'], expr['data'])
         fdef.write(generate_enum_lookup(expr['enum'], expr['data']))
     elif expr.has_key('union'):
         ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
@@ -300,6 +311,9 @@ for expr in exprs:
         fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n")
         ret += generate_type_cleanup_decl(expr['union'])
         fdef.write(generate_type_cleanup(expr['union']) + "\n")
+    elif expr.has_key('enum'):
+        ret += generate_type_cleanup_decl(expr['enum'] + "List")
+        fdef.write(generate_type_cleanup(expr['enum'] + "List") + "\n")
     else:
         continue
     fdecl.write(ret)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 04ef7c4..cbec24d 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -217,6 +217,16 @@ void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name,
 
     return ret
 
+def generate_enum_declaration(name, members, genlist=True):
+    ret = ""
+    if genlist:
+        ret += mcgen('''
+void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp);
+''',
+                     name=name)
+
+    return ret
+
 def generate_decl_enum(name, members, genlist=True):
     return mcgen('''
 
@@ -335,10 +345,12 @@ for expr in exprs:
         ret += generate_declaration(expr['union'], expr['data'])
         fdecl.write(ret)
     elif expr.has_key('enum'):
-        ret = generate_visit_enum(expr['enum'], expr['data'])
+        ret = generate_visit_list(expr['enum'], expr['data'])
+        ret += generate_visit_enum(expr['enum'], expr['data'])
         fdef.write(ret)
 
         ret = generate_decl_enum(expr['enum'], expr['data'])
+        ret += generate_enum_declaration(expr['enum'], expr['data'])
         fdecl.write(ret)
 
 fdecl.write('''
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 06/19] qapi: add the QKeyCode enum
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (4 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 05/19] qapi: generate list struct and visit_list for enum Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 07/19] monitor: move key_defs[] table and introduce two help functions Luiz Capitulino
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: Amos Kong, qemu-devel

From: Amos Kong <akong@redhat.com>

key_defs[] in monitor.c is a mapping table of keys and keycodes,
this patch added a QKeyCode enum. Key's index in the enmu is same
as keycode's index in key_defs[].

Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 qapi-schema.json | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/qapi-schema.json b/qapi-schema.json
index bd8ad74..856e11a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2493,3 +2493,29 @@
 # Since: 1.2.0
 ##
 { 'command': 'query-target', 'returns': 'TargetInfo' }
+
+##
+# @QKeyCode:
+#
+# An enumeration of key name.
+#
+# This is used by the send-key command.
+#
+# Since: 1.3.0
+##
+{ 'enum': 'QKeyCode',
+  'data': [ 'shift', 'shift_r', 'alt', 'alt_r', 'altgr', 'altgr_r', 'ctrl',
+            'ctrl_r', 'menu', 'esc', '1', '2', '3', '4', '5', '6', '7', '8',
+            '9', '0', 'minus', 'equal', 'backspace', 'tab', 'q', 'w', 'e',
+            'r', 't', 'y', 'u', 'i', 'o', 'p', 'bracket_left', 'bracket_right',
+            'ret', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'semicolon',
+            'apostrophe', 'grave_accent', 'backslash', 'z', 'x', 'c', 'v', 'b',
+            'n', 'm', 'comma', 'dot', 'slash', 'asterisk', 'spc', 'caps_lock',
+            'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10',
+            'num_lock', 'scroll_lock', 'kp_divide', 'kp_multiply',
+            'kp_subtract', 'kp_add', 'kp_enter', 'kp_decimal', 'sysrq', 'kp_0',
+            'kp_1', 'kp_2', 'kp_3', 'kp_4', 'kp_5', 'kp_6', 'kp_7', 'kp_8',
+            'kp_9', 'less', 'f11', 'f12', 'print', 'home', 'pgup', 'pgdn', 'end',
+            'left', 'up', 'down', 'right', 'insert', 'delete', 'stop', 'again',
+            'props', 'undo', 'front', 'copy', 'open', 'paste', 'find', 'cut',
+             'lf', 'help', 'meta_l', 'meta_r', 'compose' ] }
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 07/19] monitor: move key_defs[] table and introduce two help functions
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (5 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 06/19] qapi: add the QKeyCode enum Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 08/19] qapi: convert sendkey Luiz Capitulino
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: Amos Kong, qemu-devel

From: Amos Kong <akong@redhat.com>

This patch added two help functions to convert key/code to index of
mapping table, those functions will return Q_KEY_CODE_MAX if the
code/key is invalid.

Patch also moved key_defs[] to input.c, and removed useless KeyDef struct.
Key's index in QKeyCode enmu is same as keycode's index in new key_defs[].
Monitor functions were changed to access key_defs[] directly.

key_defs[] is used in do_send_key(), so export key_defs[]. It will be
changed to static in next patch.

Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 console.h |   6 ++
 input.c   | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 monitor.c | 183 ++++---------------------------------------------------------
 3 files changed, 203 insertions(+), 172 deletions(-)

diff --git a/console.h b/console.h
index 4334db5..7934b11 100644
--- a/console.h
+++ b/console.h
@@ -6,6 +6,7 @@
 #include "notify.h"
 #include "monitor.h"
 #include "trace.h"
+#include "qapi-types.h"
 
 /* keyboard/mouse support */
 
@@ -397,4 +398,9 @@ static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires)
 /* curses.c */
 void curses_display_init(DisplayState *ds, int full_screen);
 
+/* input.c */
+extern const int key_defs[];
+int index_from_key(const char *key);
+int index_from_keycode(int code);
+
 #endif
diff --git a/input.c b/input.c
index 6968b31..5630cb1 100644
--- a/input.c
+++ b/input.c
@@ -37,6 +37,192 @@ static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
 static NotifierList mouse_mode_notifiers = 
     NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
 
+const int key_defs[] = {
+    [Q_KEY_CODE_SHIFT] = 0x2a,
+    [Q_KEY_CODE_SHIFT_R] = 0x36,
+
+    [Q_KEY_CODE_ALT] = 0x38,
+    [Q_KEY_CODE_ALT_R] = 0xb8,
+    [Q_KEY_CODE_ALTGR] = 0x64,
+    [Q_KEY_CODE_ALTGR_R] = 0xe4,
+    [Q_KEY_CODE_CTRL] = 0x1d,
+    [Q_KEY_CODE_CTRL_R] = 0x9d,
+
+    [Q_KEY_CODE_MENU] = 0xdd,
+
+    [Q_KEY_CODE_ESC] = 0x01,
+
+    [Q_KEY_CODE_1] = 0x02,
+    [Q_KEY_CODE_2] = 0x03,
+    [Q_KEY_CODE_3] = 0x04,
+    [Q_KEY_CODE_4] = 0x05,
+    [Q_KEY_CODE_5] = 0x06,
+    [Q_KEY_CODE_6] = 0x07,
+    [Q_KEY_CODE_7] = 0x08,
+    [Q_KEY_CODE_8] = 0x09,
+    [Q_KEY_CODE_9] = 0x0a,
+    [Q_KEY_CODE_0] = 0x0b,
+    [Q_KEY_CODE_MINUS] = 0x0c,
+    [Q_KEY_CODE_EQUAL] = 0x0d,
+    [Q_KEY_CODE_BACKSPACE] = 0x0e,
+
+    [Q_KEY_CODE_TAB] = 0x0f,
+    [Q_KEY_CODE_Q] = 0x10,
+    [Q_KEY_CODE_W] = 0x11,
+    [Q_KEY_CODE_E] = 0x12,
+    [Q_KEY_CODE_R] = 0x13,
+    [Q_KEY_CODE_T] = 0x14,
+    [Q_KEY_CODE_Y] = 0x15,
+    [Q_KEY_CODE_U] = 0x16,
+    [Q_KEY_CODE_I] = 0x17,
+    [Q_KEY_CODE_O] = 0x18,
+    [Q_KEY_CODE_P] = 0x19,
+    [Q_KEY_CODE_BRACKET_LEFT] = 0x1a,
+    [Q_KEY_CODE_BRACKET_RIGHT] = 0x1b,
+    [Q_KEY_CODE_RET] = 0x1c,
+
+    [Q_KEY_CODE_A] = 0x1e,
+    [Q_KEY_CODE_S] = 0x1f,
+    [Q_KEY_CODE_D] = 0x20,
+    [Q_KEY_CODE_F] = 0x21,
+    [Q_KEY_CODE_G] = 0x22,
+    [Q_KEY_CODE_H] = 0x23,
+    [Q_KEY_CODE_J] = 0x24,
+    [Q_KEY_CODE_K] = 0x25,
+    [Q_KEY_CODE_L] = 0x26,
+    [Q_KEY_CODE_SEMICOLON] = 0x27,
+    [Q_KEY_CODE_APOSTROPHE] = 0x28,
+    [Q_KEY_CODE_GRAVE_ACCENT] = 0x29,
+
+    [Q_KEY_CODE_BACKSLASH] = 0x2b,
+    [Q_KEY_CODE_Z] = 0x2c,
+    [Q_KEY_CODE_X] = 0x2d,
+    [Q_KEY_CODE_C] = 0x2e,
+    [Q_KEY_CODE_V] = 0x2f,
+    [Q_KEY_CODE_B] = 0x30,
+    [Q_KEY_CODE_N] = 0x31,
+    [Q_KEY_CODE_M] = 0x32,
+    [Q_KEY_CODE_COMMA] = 0x33,
+    [Q_KEY_CODE_DOT] = 0x34,
+    [Q_KEY_CODE_SLASH] = 0x35,
+
+    [Q_KEY_CODE_ASTERISK] = 0x37,
+
+    [Q_KEY_CODE_SPC] = 0x39,
+    [Q_KEY_CODE_CAPS_LOCK] = 0x3a,
+    [Q_KEY_CODE_F1] = 0x3b,
+    [Q_KEY_CODE_F2] = 0x3c,
+    [Q_KEY_CODE_F3] = 0x3d,
+    [Q_KEY_CODE_F4] = 0x3e,
+    [Q_KEY_CODE_F5] = 0x3f,
+    [Q_KEY_CODE_F6] = 0x40,
+    [Q_KEY_CODE_F7] = 0x41,
+    [Q_KEY_CODE_F8] = 0x42,
+    [Q_KEY_CODE_F9] = 0x43,
+    [Q_KEY_CODE_F10] = 0x44,
+    [Q_KEY_CODE_NUM_LOCK] = 0x45,
+    [Q_KEY_CODE_SCROLL_LOCK] = 0x46,
+
+    [Q_KEY_CODE_KP_DIVIDE] = 0xb5,
+    [Q_KEY_CODE_KP_MULTIPLY] = 0x37,
+    [Q_KEY_CODE_KP_SUBTRACT] = 0x4a,
+    [Q_KEY_CODE_KP_ADD] = 0x4e,
+    [Q_KEY_CODE_KP_ENTER] = 0x9c,
+    [Q_KEY_CODE_KP_DECIMAL] = 0x53,
+    [Q_KEY_CODE_SYSRQ] = 0x54,
+
+    [Q_KEY_CODE_KP_0] = 0x52,
+    [Q_KEY_CODE_KP_1] = 0x4f,
+    [Q_KEY_CODE_KP_2] = 0x50,
+    [Q_KEY_CODE_KP_3] = 0x51,
+    [Q_KEY_CODE_KP_4] = 0x4b,
+    [Q_KEY_CODE_KP_5] = 0x4c,
+    [Q_KEY_CODE_KP_6] = 0x4d,
+    [Q_KEY_CODE_KP_7] = 0x47,
+    [Q_KEY_CODE_KP_8] = 0x48,
+    [Q_KEY_CODE_KP_9] = 0x49,
+
+    [Q_KEY_CODE_LESS] = 0x56,
+
+    [Q_KEY_CODE_F11] = 0x57,
+    [Q_KEY_CODE_F12] = 0x58,
+
+    [Q_KEY_CODE_PRINT] = 0xb7,
+
+    [Q_KEY_CODE_HOME] = 0xc7,
+    [Q_KEY_CODE_PGUP] = 0xc9,
+    [Q_KEY_CODE_PGDN] = 0xd1,
+    [Q_KEY_CODE_END] = 0xcf,
+
+    [Q_KEY_CODE_LEFT] = 0xcb,
+    [Q_KEY_CODE_UP] = 0xc8,
+    [Q_KEY_CODE_DOWN] = 0xd0,
+    [Q_KEY_CODE_RIGHT] = 0xcd,
+
+    [Q_KEY_CODE_INSERT] = 0xd2,
+    [Q_KEY_CODE_DELETE] = 0xd3,
+#ifdef NEED_CPU_H
+#if defined(TARGET_SPARC) && !defined(TARGET_SPARC64)
+    [Q_KEY_CODE_STOP] = 0xf0,
+    [Q_KEY_CODE_AGAIN] = 0xf1,
+    [Q_KEY_CODE_PROPS] = 0xf2,
+    [Q_KEY_CODE_UNDO] = 0xf3,
+    [Q_KEY_CODE_FRONT] = 0xf4,
+    [Q_KEY_CODE_COPY] = 0xf5,
+    [Q_KEY_CODE_OPEN] = 0xf6,
+    [Q_KEY_CODE_PASTE] = 0xf7,
+    [Q_KEY_CODE_FIND] = 0xf8,
+    [Q_KEY_CODE_CUT] = 0xf9,
+    [Q_KEY_CODE_LF] = 0xfa,
+    [Q_KEY_CODE_HELP] = 0xfb,
+    [Q_KEY_CODE_META_L] = 0xfc,
+    [Q_KEY_CODE_META_R] = 0xfd,
+    [Q_KEY_CODE_COMPOSE] = 0xfe,
+#endif
+#endif
+    [Q_KEY_CODE_MAX] = 0,
+};
+
+int index_from_key(const char *key)
+{
+    int i, keycode;
+    char *endp;
+
+    for (i = 0; QKeyCode_lookup[i] != NULL; i++) {
+        if (!strcmp(key, QKeyCode_lookup[i])) {
+            break;
+        }
+    }
+
+    if (strstart(key, "0x", NULL)) {
+        keycode = strtoul(key, &endp, 0);
+        if (*endp == '\0' && keycode >= 0x01 && keycode <= 0xff) {
+            for (i = 0; i < Q_KEY_CODE_MAX; i++) {
+                if (keycode == key_defs[i]) {
+                    break;
+                }
+            }
+        }
+    }
+
+    /* Return Q_KEY_CODE_MAX if the key is invalid */
+    return i;
+}
+
+int index_from_keycode(int code)
+{
+    int i;
+
+    for (i = 0; i < Q_KEY_CODE_MAX; i++) {
+        if (key_defs[i] == code) {
+            break;
+        }
+    }
+
+    /* Return Q_KEY_CODE_MAX if the code is invalid */
+    return i;
+}
+
 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
 {
     qemu_put_kbd_event_opaque = opaque;
diff --git a/monitor.c b/monitor.c
index 84176eb..0c4f86f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1290,173 +1290,6 @@ static void do_sum(Monitor *mon, const QDict *qdict)
     monitor_printf(mon, "%05d\n", sum);
 }
 
-typedef struct {
-    int keycode;
-    const char *name;
-} KeyDef;
-
-static const KeyDef key_defs[] = {
-    { 0x2a, "shift" },
-    { 0x36, "shift_r" },
-
-    { 0x38, "alt" },
-    { 0xb8, "alt_r" },
-    { 0x64, "altgr" },
-    { 0xe4, "altgr_r" },
-    { 0x1d, "ctrl" },
-    { 0x9d, "ctrl_r" },
-
-    { 0xdd, "menu" },
-
-    { 0x01, "esc" },
-
-    { 0x02, "1" },
-    { 0x03, "2" },
-    { 0x04, "3" },
-    { 0x05, "4" },
-    { 0x06, "5" },
-    { 0x07, "6" },
-    { 0x08, "7" },
-    { 0x09, "8" },
-    { 0x0a, "9" },
-    { 0x0b, "0" },
-    { 0x0c, "minus" },
-    { 0x0d, "equal" },
-    { 0x0e, "backspace" },
-
-    { 0x0f, "tab" },
-    { 0x10, "q" },
-    { 0x11, "w" },
-    { 0x12, "e" },
-    { 0x13, "r" },
-    { 0x14, "t" },
-    { 0x15, "y" },
-    { 0x16, "u" },
-    { 0x17, "i" },
-    { 0x18, "o" },
-    { 0x19, "p" },
-    { 0x1a, "bracket_left" },
-    { 0x1b, "bracket_right" },
-    { 0x1c, "ret" },
-
-    { 0x1e, "a" },
-    { 0x1f, "s" },
-    { 0x20, "d" },
-    { 0x21, "f" },
-    { 0x22, "g" },
-    { 0x23, "h" },
-    { 0x24, "j" },
-    { 0x25, "k" },
-    { 0x26, "l" },
-    { 0x27, "semicolon" },
-    { 0x28, "apostrophe" },
-    { 0x29, "grave_accent" },
-
-    { 0x2b, "backslash" },
-    { 0x2c, "z" },
-    { 0x2d, "x" },
-    { 0x2e, "c" },
-    { 0x2f, "v" },
-    { 0x30, "b" },
-    { 0x31, "n" },
-    { 0x32, "m" },
-    { 0x33, "comma" },
-    { 0x34, "dot" },
-    { 0x35, "slash" },
-
-    { 0x37, "asterisk" },
-
-    { 0x39, "spc" },
-    { 0x3a, "caps_lock" },
-    { 0x3b, "f1" },
-    { 0x3c, "f2" },
-    { 0x3d, "f3" },
-    { 0x3e, "f4" },
-    { 0x3f, "f5" },
-    { 0x40, "f6" },
-    { 0x41, "f7" },
-    { 0x42, "f8" },
-    { 0x43, "f9" },
-    { 0x44, "f10" },
-    { 0x45, "num_lock" },
-    { 0x46, "scroll_lock" },
-
-    { 0xb5, "kp_divide" },
-    { 0x37, "kp_multiply" },
-    { 0x4a, "kp_subtract" },
-    { 0x4e, "kp_add" },
-    { 0x9c, "kp_enter" },
-    { 0x53, "kp_decimal" },
-    { 0x54, "sysrq" },
-
-    { 0x52, "kp_0" },
-    { 0x4f, "kp_1" },
-    { 0x50, "kp_2" },
-    { 0x51, "kp_3" },
-    { 0x4b, "kp_4" },
-    { 0x4c, "kp_5" },
-    { 0x4d, "kp_6" },
-    { 0x47, "kp_7" },
-    { 0x48, "kp_8" },
-    { 0x49, "kp_9" },
-
-    { 0x56, "less" },
-
-    { 0x57, "f11" },
-    { 0x58, "f12" },
-
-    { 0xb7, "print" },
-
-    { 0xc7, "home" },
-    { 0xc9, "pgup" },
-    { 0xd1, "pgdn" },
-    { 0xcf, "end" },
-
-    { 0xcb, "left" },
-    { 0xc8, "up" },
-    { 0xd0, "down" },
-    { 0xcd, "right" },
-
-    { 0xd2, "insert" },
-    { 0xd3, "delete" },
-#if defined(TARGET_SPARC) && !defined(TARGET_SPARC64)
-    { 0xf0, "stop" },
-    { 0xf1, "again" },
-    { 0xf2, "props" },
-    { 0xf3, "undo" },
-    { 0xf4, "front" },
-    { 0xf5, "copy" },
-    { 0xf6, "open" },
-    { 0xf7, "paste" },
-    { 0xf8, "find" },
-    { 0xf9, "cut" },
-    { 0xfa, "lf" },
-    { 0xfb, "help" },
-    { 0xfc, "meta_l" },
-    { 0xfd, "meta_r" },
-    { 0xfe, "compose" },
-#endif
-    { 0, NULL },
-};
-
-static int get_keycode(const char *key)
-{
-    const KeyDef *p;
-    char *endp;
-    int ret;
-
-    for(p = key_defs; p->name != NULL; p++) {
-        if (!strcmp(key, p->name))
-            return p->keycode;
-    }
-    if (strstart(key, "0x", NULL)) {
-        ret = strtoul(key, &endp, 0);
-        if (*endp == '\0' && ret >= 0x01 && ret <= 0xff)
-            return ret;
-    }
-    return -1;
-}
-
 #define MAX_KEYCODES 16
 static uint8_t keycodes[MAX_KEYCODES];
 static int nb_pending_keycodes;
@@ -1479,7 +1312,7 @@ static void do_sendkey(Monitor *mon, const QDict *qdict)
 {
     char keyname_buf[16];
     char *separator;
-    int keyname_len, keycode, i;
+    int keyname_len, keycode, i, idx;
     const char *keys = qdict_get_str(qdict, "keys");
     int has_hold_time = qdict_haskey(qdict, "hold-time");
     int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
@@ -1512,7 +1345,14 @@ static void do_sendkey(Monitor *mon, const QDict *qdict)
             }
 
             keyname_buf[keyname_len] = 0;
-            keycode = get_keycode(keyname_buf);
+
+            idx = index_from_key(keyname_buf);
+            if (idx == Q_KEY_CODE_MAX) {
+                monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
+                return;
+            }
+
+            keycode = key_defs[idx];
             if (keycode < 0) {
                 monitor_printf(mon, "unknown key: '%s'\n", keyname_buf);
                 return;
@@ -4322,7 +4162,6 @@ static void monitor_find_completion(const char *cmdline)
     int nb_args, i, len;
     const char *ptype, *str;
     const mon_cmd_t *cmd;
-    const KeyDef *key;
 
     parse_cmdline(cmdline, &nb_args, args);
 #ifdef DEBUG_COMPLETION
@@ -4396,8 +4235,8 @@ static void monitor_find_completion(const char *cmdline)
                 if (sep)
                     str = sep + 1;
                 readline_set_completion_index(cur_mon->rs, strlen(str));
-                for(key = key_defs; key->name != NULL; key++) {
-                    cmd_completion(str, key->name);
+                for (i = 0; i < Q_KEY_CODE_MAX; i++) {
+                    cmd_completion(str, QKeyCode_lookup[i]);
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
                 readline_set_completion_index(cur_mon->rs, strlen(str));
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 08/19] qapi: convert sendkey
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (6 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 07/19] monitor: move key_defs[] table and introduce two help functions Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 09/19] qapi: Fix potential NULL pointer segfault Luiz Capitulino
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: Amos Kong, qemu-devel

From: Amos Kong <akong@redhat.com>

Convert 'sendkey' to use QAPI.

QAPI passes key's index of mapping table to qmp_send_key(),
not keycode. So we use help functions to convert key/code to
index of key_defs, and 'index' will be converted to 'keycode'
inside qmp_send_key().

For qmp, QAPI would check invalid key and raise error.
For hmp, invalid key is checked in hmp_send_key().

'send-key' of QMP doesn't support key in hexadecimal format.

Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 console.h        |  1 -
 hmp-commands.hx  |  2 +-
 hmp.c            | 55 +++++++++++++++++++++++++++++++++++
 hmp.h            |  1 +
 input.c          | 67 ++++++++++++++++++++++++++++++++++++++++++-
 monitor.c        | 87 --------------------------------------------------------
 qapi-schema.json | 20 +++++++++++++
 qmp-commands.hx  | 28 ++++++++++++++++++
 8 files changed, 171 insertions(+), 90 deletions(-)

diff --git a/console.h b/console.h
index 7934b11..c702b23 100644
--- a/console.h
+++ b/console.h
@@ -399,7 +399,6 @@ static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires)
 void curses_display_init(DisplayState *ds, int full_screen);
 
 /* input.c */
-extern const int key_defs[];
 int index_from_key(const char *key);
 int index_from_keycode(int code);
 
diff --git a/hmp-commands.hx b/hmp-commands.hx
index bd0c6c9..5cee131 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -505,7 +505,7 @@ ETEXI
         .args_type  = "keys:s,hold-time:i?",
         .params     = "keys [hold_ms]",
         .help       = "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)",
-        .mhandler.cmd = do_sendkey,
+        .mhandler.cmd = hmp_send_key,
     },
 
 STEXI
diff --git a/hmp.c b/hmp.c
index 81c8acb..ba99b2f 100644
--- a/hmp.c
+++ b/hmp.c
@@ -19,6 +19,7 @@
 #include "qemu-timer.h"
 #include "qmp-commands.h"
 #include "monitor.h"
+#include "console.h"
 
 static void hmp_handle_error(Monitor *mon, Error **errp)
 {
@@ -1102,3 +1103,57 @@ void hmp_closefd(Monitor *mon, const QDict *qdict)
     qmp_closefd(fdname, &errp);
     hmp_handle_error(mon, &errp);
 }
+
+void hmp_send_key(Monitor *mon, const QDict *qdict)
+{
+    const char *keys = qdict_get_str(qdict, "keys");
+    QKeyCodeList *keylist, *head = NULL, *tmp = NULL;
+    int has_hold_time = qdict_haskey(qdict, "hold-time");
+    int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
+    Error *err = NULL;
+    char keyname_buf[16];
+    char *separator;
+    int keyname_len, idx;
+
+    while (1) {
+        separator = strchr(keys, '-');
+        keyname_len = separator ? separator - keys : strlen(keys);
+        pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
+
+        /* Be compatible with old interface, convert user inputted "<" */
+        if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
+            pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
+            keyname_len = 4;
+        }
+        keyname_buf[keyname_len] = 0;
+
+        idx = index_from_key(keyname_buf);
+        if (idx == Q_KEY_CODE_MAX) {
+            monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
+            break;
+        }
+
+        keylist = g_malloc0(sizeof(*keylist));
+        keylist->value = idx;
+        keylist->next = NULL;
+
+        if (!head) {
+            head = keylist;
+        }
+        if (tmp) {
+            tmp->next = keylist;
+        }
+        tmp = keylist;
+
+        if (!separator) {
+            break;
+        }
+        keys = separator + 1;
+    }
+
+    if (idx != Q_KEY_CODE_MAX) {
+        qmp_send_key(head, has_hold_time, hold_time, &err);
+    }
+    hmp_handle_error(mon, &err);
+    qapi_free_QKeyCodeList(head);
+}
diff --git a/hmp.h b/hmp.h
index 7dd93bf..8e7838c 100644
--- a/hmp.h
+++ b/hmp.h
@@ -71,5 +71,6 @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict);
 void hmp_netdev_del(Monitor *mon, const QDict *qdict);
 void hmp_getfd(Monitor *mon, const QDict *qdict);
 void hmp_closefd(Monitor *mon, const QDict *qdict);
+void hmp_send_key(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/input.c b/input.c
index 5630cb1..c4b0619 100644
--- a/input.c
+++ b/input.c
@@ -28,6 +28,7 @@
 #include "console.h"
 #include "error.h"
 #include "qmp-commands.h"
+#include "qapi-types.h"
 
 static QEMUPutKBDEvent *qemu_put_kbd_event;
 static void *qemu_put_kbd_event_opaque;
@@ -37,7 +38,7 @@ static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
 static NotifierList mouse_mode_notifiers = 
     NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
 
-const int key_defs[] = {
+static const int key_defs[] = {
     [Q_KEY_CODE_SHIFT] = 0x2a,
     [Q_KEY_CODE_SHIFT_R] = 0x36,
 
@@ -223,6 +224,70 @@ int index_from_keycode(int code)
     return i;
 }
 
+static QKeyCodeList *keycodes;
+static QEMUTimer *key_timer;
+
+static void release_keys(void *opaque)
+{
+    int keycode;
+    QKeyCodeList *p;
+
+    for (p = keycodes; p != NULL; p = p->next) {
+        keycode = key_defs[p->value];
+        if (keycode & 0x80) {
+            kbd_put_keycode(0xe0);
+        }
+        kbd_put_keycode(keycode | 0x80);
+    }
+    qapi_free_QKeyCodeList(keycodes);
+    keycodes = NULL;
+}
+
+void qmp_send_key(QKeyCodeList *keys, bool has_hold_time, int64_t hold_time,
+                  Error **errp)
+{
+    int keycode;
+    QKeyCodeList *p, *keylist, *head = NULL, *tmp = NULL;
+
+    if (!key_timer) {
+        key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL);
+    }
+
+    if (keycodes != NULL) {
+        qemu_del_timer(key_timer);
+        release_keys(NULL);
+    }
+    if (!has_hold_time) {
+        hold_time = 100;
+    }
+
+    for (p = keys; p != NULL; p = p->next) {
+        keylist = g_malloc0(sizeof(*keylist));
+        keylist->value = p->value;
+        keylist->next = NULL;
+
+        if (!head) {
+            head = keylist;
+        }
+        if (tmp) {
+            tmp->next = keylist;
+        }
+        tmp = keylist;
+
+        /* key down events */
+        keycode = key_defs[p->value];
+        if (keycode & 0x80) {
+            kbd_put_keycode(0xe0);
+        }
+        kbd_put_keycode(keycode & 0x7f);
+    }
+    keycodes = head;
+
+    /* delayed key up events */
+    qemu_mod_timer(key_timer, qemu_get_clock_ns(vm_clock) +
+                   muldiv64(get_ticks_per_sec(), hold_time, 1000));
+}
+
 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
 {
     qemu_put_kbd_event_opaque = opaque;
diff --git a/monitor.c b/monitor.c
index 0c4f86f..d73bad8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1290,92 +1290,6 @@ static void do_sum(Monitor *mon, const QDict *qdict)
     monitor_printf(mon, "%05d\n", sum);
 }
 
-#define MAX_KEYCODES 16
-static uint8_t keycodes[MAX_KEYCODES];
-static int nb_pending_keycodes;
-static QEMUTimer *key_timer;
-
-static void release_keys(void *opaque)
-{
-    int keycode;
-
-    while (nb_pending_keycodes > 0) {
-        nb_pending_keycodes--;
-        keycode = keycodes[nb_pending_keycodes];
-        if (keycode & 0x80)
-            kbd_put_keycode(0xe0);
-        kbd_put_keycode(keycode | 0x80);
-    }
-}
-
-static void do_sendkey(Monitor *mon, const QDict *qdict)
-{
-    char keyname_buf[16];
-    char *separator;
-    int keyname_len, keycode, i, idx;
-    const char *keys = qdict_get_str(qdict, "keys");
-    int has_hold_time = qdict_haskey(qdict, "hold-time");
-    int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
-
-    if (nb_pending_keycodes > 0) {
-        qemu_del_timer(key_timer);
-        release_keys(NULL);
-    }
-    if (!has_hold_time)
-        hold_time = 100;
-    i = 0;
-    while (1) {
-        separator = strchr(keys, '-');
-        keyname_len = separator ? separator - keys : strlen(keys);
-        if (keyname_len > 0) {
-            pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
-            if (keyname_len > sizeof(keyname_buf) - 1) {
-                monitor_printf(mon, "invalid key: '%s...'\n", keyname_buf);
-                return;
-            }
-            if (i == MAX_KEYCODES) {
-                monitor_printf(mon, "too many keys\n");
-                return;
-            }
-
-            /* Be compatible with old interface, convert user inputted "<" */
-            if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
-                pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
-                keyname_len = 4;
-            }
-
-            keyname_buf[keyname_len] = 0;
-
-            idx = index_from_key(keyname_buf);
-            if (idx == Q_KEY_CODE_MAX) {
-                monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
-                return;
-            }
-
-            keycode = key_defs[idx];
-            if (keycode < 0) {
-                monitor_printf(mon, "unknown key: '%s'\n", keyname_buf);
-                return;
-            }
-            keycodes[i++] = keycode;
-        }
-        if (!separator)
-            break;
-        keys = separator + 1;
-    }
-    nb_pending_keycodes = i;
-    /* key down events */
-    for (i = 0; i < nb_pending_keycodes; i++) {
-        keycode = keycodes[i];
-        if (keycode & 0x80)
-            kbd_put_keycode(0xe0);
-        kbd_put_keycode(keycode & 0x7f);
-    }
-    /* delayed key up events */
-    qemu_mod_timer(key_timer, qemu_get_clock_ns(vm_clock) +
-                   muldiv64(get_ticks_per_sec(), hold_time, 1000));
-}
-
 static int mouse_button_state;
 
 static void do_mouse_move(Monitor *mon, const QDict *qdict)
@@ -4772,7 +4686,6 @@ void monitor_init(CharDriverState *chr, int flags)
     Monitor *mon;
 
     if (is_first_init) {
-        key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL);
         monitor_protocol_event_init();
         is_first_init = 0;
     }
diff --git a/qapi-schema.json b/qapi-schema.json
index 856e11a..5421382 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2519,3 +2519,23 @@
             'left', 'up', 'down', 'right', 'insert', 'delete', 'stop', 'again',
             'props', 'undo', 'front', 'copy', 'open', 'paste', 'find', 'cut',
              'lf', 'help', 'meta_l', 'meta_r', 'compose' ] }
+
+##
+# @send-key:
+#
+# Send keys to guest.
+#
+# @keys: key sequence. 'keys' is the name of the key. Use a JSON array to
+#        press several keys simultaneously.
+#
+# @hold-time: #optional time to delay key up events, milliseconds. Defaults
+#             to 100
+#
+# Returns: Nothing on success
+#          If key is unknown or redundant, InvalidParameter
+#
+# Since: 1.3.0
+#
+##
+{ 'command': 'send-key',
+  'data': { 'keys': ['QKeyCode'], '*hold-time': 'int' } }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 3745a21..470f08e 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -335,6 +335,34 @@ Example:
 EQMP
 
     {
+        .name       = "send-key",
+        .args_type  = "keys:O,hold-time:i?",
+        .mhandler.cmd_new = qmp_marshal_input_send_key,
+    },
+
+SQMP
+send-key
+----------
+
+Send keys to VM.
+
+Arguments:
+
+keys array:
+    - "key": key sequence (a json-array of key enum values)
+
+- hold-time: time to delay key up events, milliseconds. Defaults to 100
+             (json-int, optional)
+
+Example:
+
+-> { "execute": "send-key",
+     "arguments": { 'keys': [ 'ctrl', 'alt', 'delete' ] } }
+<- { "return": {} }
+
+EQMP
+
+    {
         .name       = "cpu",
         .args_type  = "index:i",
         .mhandler.cmd_new = qmp_marshal_input_cpu,
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 09/19] qapi: Fix potential NULL pointer segfault
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (7 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 08/19] qapi: convert sendkey Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 10/19] json-parser: " Luiz Capitulino
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: Stefan Weil, qemu-devel

From: Stefan Weil <sw@weilnetz.de>

Report from smatch:

qapi-visit.c:1640 visit_type_BlockdevAction(8) error:
 we previously assumed 'obj' could be null (see line 1639)
qapi-visit.c:2432 visit_type_NetClientOptions(8) error:
 we previously assumed 'obj' could be null (see line 2431)

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 scripts/qapi-visit.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index cbec24d..e2093e8 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -157,7 +157,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
     if (!error_is_set(errp)) {
         visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
         if (!err) {
-            if (!obj || *obj) {
+            if (obj && *obj) {
                 visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err);
                 if (!err) {
                     switch ((*obj)->kind) {
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 10/19] json-parser: Fix potential NULL pointer segfault
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (8 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 09/19] qapi: Fix potential NULL pointer segfault Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 11/19] error: add error_setg() Luiz Capitulino
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: Stefan Weil, qemu-devel

From: Stefan Weil <sw@weilnetz.de>

Report from smatch:
json-parser.c:474 parse_object(62) error: potential null derefence 'dict'.
json-parser.c:553 parse_array(75) error: potential null derefence 'list'.

Label 'out' in json-parser.c can be called with list == NULL
which is passed to QDECREF.

Modify QDECREF to handle a NULL argument (inline function qobject_decref
already handles them, too).

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 qobject.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qobject.h b/qobject.h
index d42386d..9124649 100644
--- a/qobject.h
+++ b/qobject.h
@@ -71,7 +71,7 @@ typedef struct QObject {
 
 /* High-level interface for qobject_decref() */
 #define QDECREF(obj)              \
-    qobject_decref(QOBJECT(obj))
+    qobject_decref(obj ? QOBJECT(obj) : NULL)
 
 /* Initialize an object to default values */
 #define QOBJECT_INIT(obj, qtype_type)   \
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 11/19] error: add error_setg()
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (9 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 10/19] json-parser: " Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 12/19] console: vga_hw_screen_dump_ptr: take Error argument Luiz Capitulino
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 error.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/error.h b/error.h
index 96fc203..da7fed3 100644
--- a/error.h
+++ b/error.h
@@ -30,6 +30,12 @@ typedef struct Error Error;
 void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(3, 4);
 
 /**
+ * Same as error_set(), but sets a generic error
+ */
+#define error_setg(err, fmt, ...) \
+    error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
+
+/**
  * Returns true if an indirect pointer to an error is pointing to a valid
  * error object.
  */
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 12/19] console: vga_hw_screen_dump_ptr: take Error argument
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (10 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 11/19] error: add error_setg() Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 13/19] qapi: convert screendump Luiz Capitulino
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

All devices that register a screen dump callback via
graphic_console_init() are updated.

The new argument is not used in this commit. Error handling will
be added to each device individually later.

This change is a preparation to convert the screendump command
to the QAPI.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 console.c       |  2 +-
 console.h       |  4 +++-
 hw/blizzard.c   |  2 +-
 hw/g364fb.c     |  3 ++-
 hw/omap_lcdc.c  |  3 ++-
 hw/qxl.c        |  5 +++--
 hw/tcx.c        | 12 ++++++++----
 hw/vga.c        |  6 ++++--
 hw/vmware_vga.c |  5 +++--
 9 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/console.c b/console.c
index 3b5cabb..8228773 100644
--- a/console.c
+++ b/console.c
@@ -190,7 +190,7 @@ void vga_hw_screen_dump(const char *filename)
         console_select(0);
     }
     if (consoles[0] && consoles[0]->hw_screen_dump) {
-        consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch);
+        consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, NULL);
     } else {
         error_report("screen dump not implemented");
     }
diff --git a/console.h b/console.h
index c702b23..fd68ecc 100644
--- a/console.h
+++ b/console.h
@@ -7,6 +7,7 @@
 #include "monitor.h"
 #include "trace.h"
 #include "qapi-types.h"
+#include "error.h"
 
 /* keyboard/mouse support */
 
@@ -344,7 +345,8 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
 
 typedef void (*vga_hw_update_ptr)(void *);
 typedef void (*vga_hw_invalidate_ptr)(void *);
-typedef void (*vga_hw_screen_dump_ptr)(void *, const char *, bool cswitch);
+typedef void (*vga_hw_screen_dump_ptr)(void *, const char *, bool cswitch,
+                                       Error **errp);
 typedef void (*vga_hw_text_update_ptr)(void *, console_ch_t *);
 
 DisplayState *graphic_console_init(vga_hw_update_ptr update,
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 29074c4..a2b9053 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -933,7 +933,7 @@ static void blizzard_update_display(void *opaque)
 }
 
 static void blizzard_screen_dump(void *opaque, const char *filename,
-                                 bool cswitch)
+                                 bool cswitch, Error **errp)
 {
     BlizzardState *s = (BlizzardState *) opaque;
 
diff --git a/hw/g364fb.c b/hw/g364fb.c
index 3a0b68f..498154b 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -289,7 +289,8 @@ static void g364fb_reset(G364State *s)
     g364fb_invalidate_display(s);
 }
 
-static void g364fb_screen_dump(void *opaque, const char *filename, bool cswitch)
+static void g364fb_screen_dump(void *opaque, const char *filename, bool cswitch,
+                               Error **errp)
 {
     G364State *s = opaque;
     int y, x;
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 4a08e9d..39b78cd 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -264,7 +264,8 @@ static int ppm_save(const char *filename, uint8_t *data,
     return 0;
 }
 
-static void omap_screen_dump(void *opaque, const char *filename, bool cswitch)
+static void omap_screen_dump(void *opaque, const char *filename, bool cswitch,
+                             Error **errp)
 {
     struct omap_lcd_panel_s *omap_lcd = opaque;
 
diff --git a/hw/qxl.c b/hw/qxl.c
index c2dd3b4..46a929d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1595,7 +1595,8 @@ static void qxl_hw_invalidate(void *opaque)
     vga->invalidate(vga);
 }
 
-static void qxl_hw_screen_dump(void *opaque, const char *filename, bool cswitch)
+static void qxl_hw_screen_dump(void *opaque, const char *filename, bool cswitch,
+                               Error **errp)
 {
     PCIQXLDevice *qxl = opaque;
     VGACommonState *vga = &qxl->vga;
@@ -1607,7 +1608,7 @@ static void qxl_hw_screen_dump(void *opaque, const char *filename, bool cswitch)
         ppm_save(filename, qxl->ssd.ds->surface);
         break;
     case QXL_MODE_VGA:
-        vga->screen_dump(vga, filename, cswitch);
+        vga->screen_dump(vga, filename, cswitch, errp);
         break;
     default:
         break;
diff --git a/hw/tcx.c b/hw/tcx.c
index ac7dcb4..74a7085 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -56,8 +56,10 @@ typedef struct TCXState {
     uint8_t dac_index, dac_state;
 } TCXState;
 
-static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch);
-static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch);
+static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
+                            Error **errp);
+static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
+                            Error **errp);
 
 static void tcx_set_dirty(TCXState *s)
 {
@@ -574,7 +576,8 @@ static int tcx_init1(SysBusDevice *dev)
     return 0;
 }
 
-static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch)
+static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
+                            Error **errp)
 {
     TCXState *s = opaque;
     FILE *f;
@@ -601,7 +604,8 @@ static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch)
     return;
 }
 
-static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch)
+static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
+                              Error **errp)
 {
     TCXState *s = opaque;
     FILE *f;
diff --git a/hw/vga.c b/hw/vga.c
index f82ced8..dd703cf 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -166,7 +166,8 @@ static uint32_t expand4[256];
 static uint16_t expand2[256];
 static uint8_t expand4to8[16];
 
-static void vga_screen_dump(void *opaque, const char *filename, bool cswitch);
+static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
+                            Error **errp);
 
 static void vga_update_memory_access(VGACommonState *s)
 {
@@ -2435,7 +2436,8 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
 
 /* save the vga display in a PPM image even if no display is
    available */
-static void vga_screen_dump(void *opaque, const char *filename, bool cswitch)
+static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
+                            Error **errp)
 {
     VGACommonState *s = opaque;
 
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index f5e4f44..29750e1 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1003,11 +1003,12 @@ static void vmsvga_invalidate_display(void *opaque)
 
 /* save the vga display in a PPM image even if no display is
    available */
-static void vmsvga_screen_dump(void *opaque, const char *filename, bool cswitch)
+static void vmsvga_screen_dump(void *opaque, const char *filename, bool cswitch,
+                               Error **errp)
 {
     struct vmsvga_state_s *s = opaque;
     if (!s->enable) {
-        s->vga.screen_dump(&s->vga, filename, cswitch);
+        s->vga.screen_dump(&s->vga, filename, cswitch, errp);
         return;
     }
 
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 13/19] qapi: convert screendump
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (11 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 12/19] console: vga_hw_screen_dump_ptr: take Error argument Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 14/19] vga: ppm_save(): add error handling Luiz Capitulino
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

Next commits will update devices to propagate errors.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 console.c        |  7 ++++---
 console.h        |  1 -
 hmp-commands.hx  |  3 +--
 hmp.c            |  9 +++++++++
 hmp.h            |  1 +
 monitor.c        |  6 ------
 qapi-schema.json | 13 +++++++++++++
 qmp-commands.hx  |  5 +----
 8 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/console.c b/console.c
index 8228773..c1ed5e0 100644
--- a/console.c
+++ b/console.c
@@ -24,6 +24,7 @@
 #include "qemu-common.h"
 #include "console.h"
 #include "qemu-timer.h"
+#include "qmp-commands.h"
 
 //#define DEBUG_CONSOLE
 #define DEFAULT_BACKSCROLL 512
@@ -176,7 +177,7 @@ void vga_hw_invalidate(void)
         active_console->hw_invalidate(active_console->hw);
 }
 
-void vga_hw_screen_dump(const char *filename)
+void qmp_screendump(const char *filename, Error **errp)
 {
     TextConsole *previous_active_console;
     bool cswitch;
@@ -190,9 +191,9 @@ void vga_hw_screen_dump(const char *filename)
         console_select(0);
     }
     if (consoles[0] && consoles[0]->hw_screen_dump) {
-        consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, NULL);
+        consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, errp);
     } else {
-        error_report("screen dump not implemented");
+        error_setg(errp, "device doesn't support screendump\n");
     }
 
     if (cswitch) {
diff --git a/console.h b/console.h
index fd68ecc..f990684 100644
--- a/console.h
+++ b/console.h
@@ -357,7 +357,6 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update,
 
 void vga_hw_update(void);
 void vga_hw_invalidate(void);
-void vga_hw_screen_dump(const char *filename);
 void vga_hw_text_update(console_ch_t *chardata);
 
 int is_graphic_console(void);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 5cee131..ed67e99 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -194,8 +194,7 @@ ETEXI
         .args_type  = "filename:F",
         .params     = "filename",
         .help       = "save screen into PPM image 'filename'",
-        .user_print = monitor_user_noop,
-        .mhandler.cmd_new = do_screen_dump,
+        .mhandler.cmd = hmp_screen_dump,
     },
 
 STEXI
diff --git a/hmp.c b/hmp.c
index ba99b2f..1bdab22 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1157,3 +1157,12 @@ void hmp_send_key(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, &err);
     qapi_free_QKeyCodeList(head);
 }
+
+void hmp_screen_dump(Monitor *mon, const QDict *qdict)
+{
+    const char *filename = qdict_get_str(qdict, "filename");
+    Error *err = NULL;
+
+    qmp_screendump(filename, &err);
+    hmp_handle_error(mon, &err);
+}
diff --git a/hmp.h b/hmp.h
index 8e7838c..48b9c59 100644
--- a/hmp.h
+++ b/hmp.h
@@ -72,5 +72,6 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict);
 void hmp_getfd(Monitor *mon, const QDict *qdict);
 void hmp_closefd(Monitor *mon, const QDict *qdict);
 void hmp_send_key(Monitor *mon, const QDict *qdict);
+void hmp_screen_dump(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/monitor.c b/monitor.c
index d73bad8..e315b27 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1016,12 +1016,6 @@ static int client_migrate_info(Monitor *mon, const QDict *qdict,
     return -1;
 }
 
-static int do_screen_dump(Monitor *mon, const QDict *qdict, QObject **ret_data)
-{
-    vga_hw_screen_dump(qdict_get_str(qdict, "filename"));
-    return 0;
-}
-
 static void do_logfile(Monitor *mon, const QDict *qdict)
 {
     cpu_set_log_filename(qdict_get_str(qdict, "filename"));
diff --git a/qapi-schema.json b/qapi-schema.json
index 5421382..df47fce 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2539,3 +2539,16 @@
 ##
 { 'command': 'send-key',
   'data': { 'keys': ['QKeyCode'], '*hold-time': 'int' } }
+
+##
+# @screendump:
+#
+# Write a PPM of the VGA screen to a file.
+#
+# @filename: the path of a new PPM file to store the image
+#
+# Returns: Nothing on success
+#
+# Since: 0.14.0
+##
+{ 'command': 'screendump', 'data': {'filename': 'str'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 470f08e..6e21ddb 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -146,10 +146,7 @@ EQMP
     {
         .name       = "screendump",
         .args_type  = "filename:F",
-        .params     = "filename",
-        .help       = "save screen into PPM image 'filename'",
-        .user_print = monitor_user_noop,
-        .mhandler.cmd_new = do_screen_dump,
+        .mhandler.cmd_new = qmp_marshal_input_screendump,
     },
 
 SQMP
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 14/19] vga: ppm_save(): add error handling
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (12 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 13/19] qapi: convert screendump Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 15/19] omap_lcdc: rename ppm_save() to omap_ppm_save() Luiz Capitulino
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hw/blizzard.c   |  2 +-
 hw/qxl.c        |  2 +-
 hw/vga.c        | 32 +++++++++++++++++++++++++-------
 hw/vga_int.h    |  3 ++-
 hw/vmware_vga.c |  2 +-
 5 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/hw/blizzard.c b/hw/blizzard.c
index a2b9053..d1c9d81 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -939,7 +939,7 @@ static void blizzard_screen_dump(void *opaque, const char *filename,
 
     blizzard_update_display(opaque);
     if (s && ds_get_data(s->state))
-        ppm_save(filename, s->state->surface);
+        ppm_save(filename, s->state->surface, errp);
 }
 
 #define DEPTH 8
diff --git a/hw/qxl.c b/hw/qxl.c
index 46a929d..bae5758 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1605,7 +1605,7 @@ static void qxl_hw_screen_dump(void *opaque, const char *filename, bool cswitch,
     case QXL_MODE_COMPAT:
     case QXL_MODE_NATIVE:
         qxl_render_update(qxl);
-        ppm_save(filename, qxl->ssd.ds->surface);
+        ppm_save(filename, qxl->ssd.ds->surface, errp);
         break;
     case QXL_MODE_VGA:
         vga->screen_dump(vga, filename, cswitch, errp);
diff --git a/hw/vga.c b/hw/vga.c
index dd703cf..80299ea 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2390,7 +2390,7 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
 /********************************************************/
 /* vga screen dump */
 
-int ppm_save(const char *filename, struct DisplaySurface *ds)
+void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
 {
     FILE *f;
     uint8_t *d, *d1;
@@ -2402,10 +2402,16 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
 
     trace_ppm_save(filename, ds);
     f = fopen(filename, "wb");
-    if (!f)
-        return -1;
-    fprintf(f, "P6\n%d %d\n%d\n",
-            ds->width, ds->height, 255);
+    if (!f) {
+        error_setg(errp, "failed to open file '%s': %s", filename,
+                   strerror(errno));
+        return;
+    }
+    ret = fprintf(f, "P6\n%d %d\n%d\n", ds->width, ds->height, 255);
+    if (ret < 0) {
+        linebuf = NULL;
+        goto write_err;
+    }
     linebuf = g_malloc(ds->width * 3);
     d1 = ds->data;
     for(y = 0; y < ds->height; y++) {
@@ -2426,12 +2432,24 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
             d += ds->pf.bytes_per_pixel;
         }
         d1 += ds->linesize;
+        clearerr(f);
         ret = fwrite(linebuf, 1, pbuf - linebuf, f);
         (void)ret;
+        if (ferror(f)) {
+            goto write_err;
+        }
     }
+
+out:
     g_free(linebuf);
     fclose(f);
-    return 0;
+    return;
+
+write_err:
+    error_setg(errp, "failed to write to file '%s': %s", filename,
+               strerror(errno));
+    unlink(filename);
+    goto out;
 }
 
 /* save the vga display in a PPM image even if no display is
@@ -2445,5 +2463,5 @@ static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
         vga_invalidate_display(s);
     }
     vga_hw_update();
-    ppm_save(filename, s->ds->surface);
+    ppm_save(filename, s->ds->surface, errp);
 }
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 8938093..330a32f 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -23,6 +23,7 @@
  */
 
 #include <hw/hw.h>
+#include "error.h"
 #include "memory.h"
 
 #define ST01_V_RETRACE      0x08
@@ -204,7 +205,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
 uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr);
 void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val);
 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
-int ppm_save(const char *filename, struct DisplaySurface *ds);
+void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp);
 
 int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
 void vga_init_vbe(VGACommonState *s, MemoryRegion *address_space);
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 29750e1..b68e883 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1015,7 +1015,7 @@ static void vmsvga_screen_dump(void *opaque, const char *filename, bool cswitch,
     if (s->depth == 32) {
         DisplaySurface *ds = qemu_create_displaysurface_from(s->width,
                 s->height, 32, ds_get_linesize(s->vga.ds), s->vga.vram_ptr);
-        ppm_save(filename, ds);
+        ppm_save(filename, ds, errp);
         g_free(ds);
     }
 }
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 15/19] omap_lcdc: rename ppm_save() to omap_ppm_save()
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (13 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 14/19] vga: ppm_save(): add error handling Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 16/19] omap_lcdc: omap_ppm_save(): add error handling Luiz Capitulino
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

Avoids confusion with the global ppm_save() defined in hw/vga.c.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/omap_lcdc.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 39b78cd..3d6328f 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -224,8 +224,8 @@ static void omap_update_display(void *opaque)
     omap_lcd->invalidate = 0;
 }
 
-static int ppm_save(const char *filename, uint8_t *data,
-                int w, int h, int linesize)
+static int omap_ppm_save(const char *filename, uint8_t *data,
+                    int w, int h, int linesize)
 {
     FILE *f;
     uint8_t *d, *d1;
@@ -271,9 +271,9 @@ static void omap_screen_dump(void *opaque, const char *filename, bool cswitch,
 
     omap_update_display(opaque);
     if (omap_lcd && ds_get_data(omap_lcd->state))
-        ppm_save(filename, ds_get_data(omap_lcd->state),
-                omap_lcd->width, omap_lcd->height,
-                ds_get_linesize(omap_lcd->state));
+        omap_ppm_save(filename, ds_get_data(omap_lcd->state),
+                    omap_lcd->width, omap_lcd->height,
+                    ds_get_linesize(omap_lcd->state));
 }
 
 static void omap_invalidate_display(void *opaque) {
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 16/19] omap_lcdc: omap_ppm_save(): add error handling
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (14 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 15/19] omap_lcdc: rename ppm_save() to omap_ppm_save() Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 17/19] g364fb: g364fb_screen_dump(): " Luiz Capitulino
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hw/omap_lcdc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 45 insertions(+), 14 deletions(-)

diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 3d6328f..e2ba108 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -224,18 +224,24 @@ static void omap_update_display(void *opaque)
     omap_lcd->invalidate = 0;
 }
 
-static int omap_ppm_save(const char *filename, uint8_t *data,
-                    int w, int h, int linesize)
+static void omap_ppm_save(const char *filename, uint8_t *data,
+                    int w, int h, int linesize, Error **errp)
 {
     FILE *f;
     uint8_t *d, *d1;
     unsigned int v;
-    int y, x, bpp;
+    int ret, y, x, bpp;
 
     f = fopen(filename, "wb");
-    if (!f)
-        return -1;
-    fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
+    if (!f) {
+        error_setg(errp, "failed to open file '%s': %s", filename,
+                   strerror(errno));
+        return;
+    }
+    ret = fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
+    if (ret < 0) {
+        goto write_err;
+    }
     d1 = data;
     bpp = linesize / w;
     for (y = 0; y < h; y ++) {
@@ -244,24 +250,49 @@ static int omap_ppm_save(const char *filename, uint8_t *data,
             v = *(uint32_t *) d;
             switch (bpp) {
             case 2:
-                fputc((v >> 8) & 0xf8, f);
-                fputc((v >> 3) & 0xfc, f);
-                fputc((v << 3) & 0xf8, f);
+                ret = fputc((v >> 8) & 0xf8, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc((v >> 3) & 0xfc, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc((v << 3) & 0xf8, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
                 break;
             case 3:
             case 4:
             default:
-                fputc((v >> 16) & 0xff, f);
-                fputc((v >> 8) & 0xff, f);
-                fputc((v) & 0xff, f);
+                ret = fputc((v >> 16) & 0xff, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc((v >> 8) & 0xff, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc((v) & 0xff, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
                 break;
             }
             d += bpp;
         }
         d1 += linesize;
     }
+out:
     fclose(f);
-    return 0;
+    return;
+
+write_err:
+    error_setg(errp, "failed to write to file '%s': %s", filename,
+               strerror(errno));
+    unlink(filename);
+    goto out;
 }
 
 static void omap_screen_dump(void *opaque, const char *filename, bool cswitch,
@@ -273,7 +304,7 @@ static void omap_screen_dump(void *opaque, const char *filename, bool cswitch,
     if (omap_lcd && ds_get_data(omap_lcd->state))
         omap_ppm_save(filename, ds_get_data(omap_lcd->state),
                     omap_lcd->width, omap_lcd->height,
-                    ds_get_linesize(omap_lcd->state));
+                    ds_get_linesize(omap_lcd->state), errp);
 }
 
 static void omap_invalidate_display(void *opaque) {
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 17/19] g364fb: g364fb_screen_dump(): add error handling
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (15 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 16/19] omap_lcdc: omap_ppm_save(): add error handling Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 18/19] tcx: tcx24_screen_dump(): " Luiz Capitulino
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hw/g364fb.c | 52 ++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/hw/g364fb.c b/hw/g364fb.c
index 498154b..059e622 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -293,7 +293,7 @@ static void g364fb_screen_dump(void *opaque, const char *filename, bool cswitch,
                                Error **errp)
 {
     G364State *s = opaque;
-    int y, x;
+    int ret, y, x;
     uint8_t index;
     uint8_t *data_buffer;
     FILE *f;
@@ -301,35 +301,63 @@ static void g364fb_screen_dump(void *opaque, const char *filename, bool cswitch,
     qemu_flush_coalesced_mmio_buffer();
 
     if (s->depth != 8) {
-        error_report("g364: unknown guest depth %d", s->depth);
+        error_setg(errp, "g364: unknown guest depth %d", s->depth);
         return;
     }
 
     f = fopen(filename, "wb");
-    if (!f)
+    if (!f) {
+        error_setg(errp, "failed to open file '%s': %s", filename,
+                   strerror(errno));
         return;
+    }
 
     if (s->ctla & CTLA_FORCE_BLANK) {
         /* blank screen */
-        fprintf(f, "P4\n%d %d\n",
-            s->width, s->height);
+        ret = fprintf(f, "P4\n%d %d\n", s->width, s->height);
+        if (ret < 0) {
+            goto write_err;
+        }
         for (y = 0; y < s->height; y++)
-            for (x = 0; x < s->width; x++)
-                fputc(0, f);
+            for (x = 0; x < s->width; x++) {
+                ret = fputc(0, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+            }
     } else {
         data_buffer = s->vram + s->top_of_screen;
-        fprintf(f, "P6\n%d %d\n%d\n",
-            s->width, s->height, 255);
+        ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
+        if (ret < 0) {
+            goto write_err;
+        }
         for (y = 0; y < s->height; y++)
             for (x = 0; x < s->width; x++, data_buffer++) {
                 index = *data_buffer;
-                fputc(s->color_palette[index][0], f);
-                fputc(s->color_palette[index][1], f);
-                fputc(s->color_palette[index][2], f);
+                ret = fputc(s->color_palette[index][0], f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc(s->color_palette[index][1], f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc(s->color_palette[index][2], f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
         }
     }
 
+out:
     fclose(f);
+    return;
+
+write_err:
+    error_setg(errp, "failed to write to file '%s': %s", filename,
+               strerror(errno));
+    unlink(filename);
+    goto out;
 }
 
 /* called for accesses to io ports */
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 18/19] tcx: tcx24_screen_dump(): add error handling
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (16 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 17/19] g364fb: g364fb_screen_dump(): " Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 19/19] tcx: tcx_screen_dump(): " Luiz Capitulino
  2012-09-10 13:18 ` [Qemu-devel] [PULL 00/19]: QMP queue Aurelien Jarno
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hw/tcx.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/hw/tcx.c b/hw/tcx.c
index 74a7085..428649e 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -611,12 +611,18 @@ static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
     FILE *f;
     uint8_t *d, *d1, v;
     uint32_t *s24, *cptr, dval;
-    int y, x;
+    int ret, y, x;
 
     f = fopen(filename, "wb");
-    if (!f)
+    if (!f) {
+        error_setg(errp, "failed to open file '%s': %s", filename,
+                   strerror(errno));
         return;
-    fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
+    }
+    ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
+    if (ret < 0) {
+        goto write_err;
+    }
     d1 = s->vram;
     s24 = s->vram24;
     cptr = s->cplane;
@@ -625,20 +631,46 @@ static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
         for(x = 0; x < s->width; x++, d++, s24++) {
             if ((*cptr++ & 0xff000000) == 0x03000000) { // 24-bit direct
                 dval = *s24 & 0x00ffffff;
-                fputc((dval >> 16) & 0xff, f);
-                fputc((dval >> 8) & 0xff, f);
-                fputc(dval & 0xff, f);
+                ret = fputc((dval >> 16) & 0xff, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc((dval >> 8) & 0xff, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc(dval & 0xff, f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
             } else {
                 v = *d;
-                fputc(s->r[v], f);
-                fputc(s->g[v], f);
-                fputc(s->b[v], f);
+                ret = fputc(s->r[v], f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc(s->g[v], f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
+                ret = fputc(s->b[v], f);
+                if (ret == EOF) {
+                    goto write_err;
+                }
             }
         }
         d1 += MAXX;
     }
+
+out:
     fclose(f);
     return;
+
+write_err:
+    error_setg(errp, "failed to write to file '%s': %s", filename,
+               strerror(errno));
+    unlink(filename);
+    goto out;
 }
 
 static Property tcx_properties[] = {
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PATCH 19/19] tcx: tcx_screen_dump(): add error handling
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (17 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 18/19] tcx: tcx24_screen_dump(): " Luiz Capitulino
@ 2012-09-05 18:58 ` Luiz Capitulino
  2012-09-10 13:18 ` [Qemu-devel] [PULL 00/19]: QMP queue Aurelien Jarno
  19 siblings, 0 replies; 23+ messages in thread
From: Luiz Capitulino @ 2012-09-05 18:58 UTC (permalink / raw)
  To: aliguori; +Cc: qemu-devel

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hw/tcx.c | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/hw/tcx.c b/hw/tcx.c
index 428649e..93994d6 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -582,26 +582,49 @@ static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
     TCXState *s = opaque;
     FILE *f;
     uint8_t *d, *d1, v;
-    int y, x;
+    int ret, y, x;
 
     f = fopen(filename, "wb");
-    if (!f)
+    if (!f) {
+        error_setg(errp, "failed to open file '%s': %s", filename,
+                   strerror(errno));
         return;
-    fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
+    }
+    ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
+    if (ret < 0) {
+        goto write_err;
+    }
     d1 = s->vram;
     for(y = 0; y < s->height; y++) {
         d = d1;
         for(x = 0; x < s->width; x++) {
             v = *d;
-            fputc(s->r[v], f);
-            fputc(s->g[v], f);
-            fputc(s->b[v], f);
+            ret = fputc(s->r[v], f);
+            if (ret == EOF) {
+                goto write_err;
+            }
+            ret = fputc(s->g[v], f);
+            if (ret == EOF) {
+                goto write_err;
+            }
+            ret = fputc(s->b[v], f);
+            if (ret == EOF) {
+                goto write_err;
+            }
             d++;
         }
         d1 += MAXX;
     }
+
+out:
     fclose(f);
     return;
+
+write_err:
+    error_setg(errp, "failed to write to file '%s': %s", filename,
+               strerror(errno));
+    unlink(filename);
+    goto out;
 }
 
 static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
-- 
1.7.11.2.249.g31c7954.dirty

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PULL 00/19]: QMP queue
  2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
                   ` (18 preceding siblings ...)
  2012-09-05 18:58 ` [Qemu-devel] [PATCH 19/19] tcx: tcx_screen_dump(): " Luiz Capitulino
@ 2012-09-10 13:18 ` Aurelien Jarno
  19 siblings, 0 replies; 23+ messages in thread
From: Aurelien Jarno @ 2012-09-10 13:18 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: aliguori, qemu-devel

On Wed, Sep 05, 2012 at 03:58:27PM -0300, Luiz Capitulino wrote:
> Let's get the ball rolling for QMP in 1.3 :)
> 
> This pull request contains the send-key command conversion, screendump qapi
> conversion and a few fixes.
> 
> The changes (since f45ddd14209a4d1b95a4096d50a561b7f6270118) are available
> in the following repository:
> 
>     git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
> 
> Amos Kong (7):
>       fix doc of using raw values with sendkey
>       monitor: rename keyname '<' to 'less'
>       hmp: rename arguments
>       qapi: generate list struct and visit_list for enum
>       qapi: add the QKeyCode enum
>       monitor: move key_defs[] table and introduce two help functions
>       qapi: convert sendkey
> 
> Daniel P. Berrange (1):
>       Add support for pretty-printing response in qmp-shell
> 
> Luiz Capitulino (9):
>       error: add error_setg()
>       console: vga_hw_screen_dump_ptr: take Error argument
>       qapi: convert screendump
>       vga: ppm_save(): add error handling
>       omap_lcdc: rename ppm_save() to omap_ppm_save()
>       omap_lcdc: omap_ppm_save(): add error handling
>       g364fb: g364fb_screen_dump(): add error handling
>       tcx: tcx24_screen_dump(): add error handling
>       tcx: tcx_screen_dump(): add error handling
> 
> Stefan Weil (2):
>       qapi: Fix potential NULL pointer segfault
>       json-parser: Fix potential NULL pointer segfault
> 
>  QMP/qmp-shell         |  46 ++++++---
>  console.c             |   7 +-
>  console.h             |  10 +-
>  error.h               |   6 ++
>  hmp-commands.hx       |  13 ++-
>  hmp.c                 |  64 +++++++++++++
>  hmp.h                 |   2 +
>  hw/blizzard.c         |   4 +-
>  hw/g364fb.c           |  55 ++++++++---
>  hw/omap_lcdc.c        |  66 +++++++++----
>  hw/qxl.c              |   7 +-
>  hw/tcx.c              |  97 +++++++++++++++----
>  hw/vga.c              |  38 ++++++--
>  hw/vga_int.h          |   3 +-
>  hw/vmware_vga.c       |   7 +-
>  input.c               | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  monitor.c             | 251 +-------------------------------------------------
>  qapi-schema.json      |  59 ++++++++++++
>  qmp-commands.hx       |  33 ++++++-
>  qobject.h             |   2 +-
>  scripts/qapi-types.py |  16 +++-
>  scripts/qapi-visit.py |  16 +++-
>  22 files changed, 704 insertions(+), 349 deletions(-)
> 

Thanks, pulled.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PULL 00/19]: QMP queue
  2011-10-27 19:01 Luiz Capitulino
@ 2011-10-31 16:52 ` Anthony Liguori
  0 siblings, 0 replies; 23+ messages in thread
From: Anthony Liguori @ 2011-10-31 16:52 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: mdroth, qemu-devel

On 10/27/2011 02:01 PM, Luiz Capitulino wrote:
> Anthony,
>
> This pull request contains only my "QAPI conversions round 2" series (which
> got no review comments... last chance!).
>
> The changes (since 9f60639b848944200c3d33a89233d808de0b5a43) are available
> in the following repository:
>
>      git://repo.or.cz/qemu/qmp-unstable.git queue/qmp

Pulled.  Thanks.

Regards,

Anthony Liguori

>
> Luiz Capitulino (19):
>        qapi-commands.py: Don't call the output marshal on error
>        qapi: Convert query-mice
>        qapi: Convert query-migrate
>        Monitor: Make mon_set_cpu() public
>        Monitor: Introduce monitor_get_cpu_index()
>        qapi: Convert the cpu command
>        qapi: Convert query-cpus
>        block: iostatus: Drop BDRV_IOS_INVAL
>        block: Rename the BlockIOStatus enum values
>        qapi: Convert query-block
>        qapi: Convert query-blockstats
>        qerror: Add a user string for QERR_FEATURE_DISABLED
>        qapi: Convert query-vnc
>        qapi: Convert query-spice
>        qapi: Convert query-balloon
>        qapi: Convert query-pci
>        QMP: Drop the query commands dispatch table
>        Monitor: do_info(): Drop QMP command handling code
>        Drop qemu-objects.h from modules that don't require it
>
>   balloon.c                |   72 +-----
>   balloon.h                |    6 +-
>   block.c                  |  234 ++++++------------
>   block.h                  |    5 -
>   block_int.h              |    4 +-
>   console.h                |    9 -
>   cpus.c                   |   45 ++++
>   error.c                  |    3 +-
>   hmp-commands.hx          |    3 +-
>   hmp.c                    |  407 ++++++++++++++++++++++++++++++
>   hmp.h                    |   10 +
>   hw/pci-stub.c            |   15 +-
>   hw/pci.c                 |  322 +++++++++---------------
>   hw/pci.h                 |    4 -
>   hw/virtio-balloon.c      |   78 +-----
>   input.c                  |   64 ++----
>   migration.c              |   82 ++-----
>   monitor.c                |  313 ++----------------------
>   monitor.h                |    2 +
>   qapi-schema.json         |  616 ++++++++++++++++++++++++++++++++++++++++++++++
>   qerror.c                 |    4 +
>   qmp-commands.hx          |   60 +++++-
>   qmp.c                    |   27 ++
>   scripts/qapi-commands.py |    4 +-
>   ui/spice-core.c          |  139 +++++------
>   ui/vnc.c                 |  135 +++++++----
>   vl.c                     |    2 +-
>   27 files changed, 1611 insertions(+), 1054 deletions(-)
>
>
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] [PULL 00/19]: QMP queue
@ 2011-10-27 19:01 Luiz Capitulino
  2011-10-31 16:52 ` Anthony Liguori
  0 siblings, 1 reply; 23+ messages in thread
From: Luiz Capitulino @ 2011-10-27 19:01 UTC (permalink / raw)
  To: aliguori; +Cc: mdroth, qemu-devel

Anthony,

This pull request contains only my "QAPI conversions round 2" series (which
got no review comments... last chance!).

The changes (since 9f60639b848944200c3d33a89233d808de0b5a43) are available
in the following repository:

    git://repo.or.cz/qemu/qmp-unstable.git queue/qmp

Luiz Capitulino (19):
      qapi-commands.py: Don't call the output marshal on error
      qapi: Convert query-mice
      qapi: Convert query-migrate
      Monitor: Make mon_set_cpu() public
      Monitor: Introduce monitor_get_cpu_index()
      qapi: Convert the cpu command
      qapi: Convert query-cpus
      block: iostatus: Drop BDRV_IOS_INVAL
      block: Rename the BlockIOStatus enum values
      qapi: Convert query-block
      qapi: Convert query-blockstats
      qerror: Add a user string for QERR_FEATURE_DISABLED
      qapi: Convert query-vnc
      qapi: Convert query-spice
      qapi: Convert query-balloon
      qapi: Convert query-pci
      QMP: Drop the query commands dispatch table
      Monitor: do_info(): Drop QMP command handling code
      Drop qemu-objects.h from modules that don't require it

 balloon.c                |   72 +-----
 balloon.h                |    6 +-
 block.c                  |  234 ++++++------------
 block.h                  |    5 -
 block_int.h              |    4 +-
 console.h                |    9 -
 cpus.c                   |   45 ++++
 error.c                  |    3 +-
 hmp-commands.hx          |    3 +-
 hmp.c                    |  407 ++++++++++++++++++++++++++++++
 hmp.h                    |   10 +
 hw/pci-stub.c            |   15 +-
 hw/pci.c                 |  322 +++++++++---------------
 hw/pci.h                 |    4 -
 hw/virtio-balloon.c      |   78 +-----
 input.c                  |   64 ++----
 migration.c              |   82 ++-----
 monitor.c                |  313 ++----------------------
 monitor.h                |    2 +
 qapi-schema.json         |  616 ++++++++++++++++++++++++++++++++++++++++++++++
 qerror.c                 |    4 +
 qmp-commands.hx          |   60 +++++-
 qmp.c                    |   27 ++
 scripts/qapi-commands.py |    4 +-
 ui/spice-core.c          |  139 +++++------
 ui/vnc.c                 |  135 +++++++----
 vl.c                     |    2 +-
 27 files changed, 1611 insertions(+), 1054 deletions(-)

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2012-09-10 13:18 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-05 18:58 [Qemu-devel] [PULL 00/19]: QMP queue Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 01/19] Add support for pretty-printing response in qmp-shell Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 02/19] fix doc of using raw values with sendkey Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 03/19] monitor: rename keyname '<' to 'less' Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 04/19] hmp: rename arguments Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 05/19] qapi: generate list struct and visit_list for enum Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 06/19] qapi: add the QKeyCode enum Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 07/19] monitor: move key_defs[] table and introduce two help functions Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 08/19] qapi: convert sendkey Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 09/19] qapi: Fix potential NULL pointer segfault Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 10/19] json-parser: " Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 11/19] error: add error_setg() Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 12/19] console: vga_hw_screen_dump_ptr: take Error argument Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 13/19] qapi: convert screendump Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 14/19] vga: ppm_save(): add error handling Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 15/19] omap_lcdc: rename ppm_save() to omap_ppm_save() Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 16/19] omap_lcdc: omap_ppm_save(): add error handling Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 17/19] g364fb: g364fb_screen_dump(): " Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 18/19] tcx: tcx24_screen_dump(): " Luiz Capitulino
2012-09-05 18:58 ` [Qemu-devel] [PATCH 19/19] tcx: tcx_screen_dump(): " Luiz Capitulino
2012-09-10 13:18 ` [Qemu-devel] [PULL 00/19]: QMP queue Aurelien Jarno
  -- strict thread matches above, loose matches on Subject: below --
2011-10-27 19:01 Luiz Capitulino
2011-10-31 16:52 ` Anthony Liguori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.