qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] new SDL keyboard shortcuts to start and stop VM


From: Luiz Capitulino
Subject: Re: [Qemu-devel] [PATCH] new SDL keyboard shortcuts to start and stop VM
Date: Thu, 22 Oct 2009 12:40:36 -0200

On Wed, 21 Oct 2009 19:35:03 +0100
Jamie Lokier <address@hidden> wrote:

> Mulyadi Santosa wrote:
> > On Wed, Oct 21, 2009 at 11:24 PM, Glauber Costa <address@hidden> wrote:
> > > You can provide a monitor command to do that
> > >
> > > something in the lines of:
> > > - add_macro <key> <command_list>
> > > - remove_macro <key>
> > > - list_macros
> > 
> > Please CMIIW, "command_list" here refers to at least one of monitor
> > commands, right? meaning, i.e one could do:
> > add_macro ctrl_alt_shift_s "stop"
> > 
> > or extend that so it does:
> > add_macro ctrl_alt_shift_s "stop print $pc"
> > 
> > so, it stops the VM followed by printing program counter.
> 
> If the monitor accepted ";" as a command separator, to put multiple
> commands on a single line, <command_list> could just be a quoted
> string which is processed as a line.

 Why is ";" needed?

> If we're going to have keyboard macros, it would be nice and probably
> very easy to have monitor macros too - monitor commands which expand
> to a line in the same way.
> 
> The number of times I've typed things like send_key control-alt-del
> and would have appreciated a "cad" macro...

 Yeah, I agree.

 When testing migration, for example, I have to type 'migrate -d tcp:0:4444'
several times... Maybe there's a smarter way to do this, but the monitor
macros idea seems interesting to me.

> Syntax idea comes to mind is:
> 
>     - Add ";" as command separator.

 Not difficult, but not trivial.

>     - add_macro <name> <command-string>
>     - remove_macro <name>
>     - list_macros

 Why not macro_add?

> 
>     - add_key key <key> <command-string>
>     - remove_key <key> <command-string>
>     - list_keys

 What's key?

 Anyway, below there's a patch with an initial implementation. I've
implemented it using the "old" monitor style because I didn't want
to think about the right "object model" for this yet..

 If people think this is interesting I will work on a serious
implementation for submission.

 Ah, it doesn't have macro_del and if we use QObjects we can
consider saving its json representation in file so that we can
have macro_load.

commit e7fa305f82f4f99168166bda437e86d3a6343064
Author: Luiz Capitulino <address@hidden>
Date:   Thu Oct 22 12:26:06 2009 -0200

    monitor: Add macro support
    
    This is a buggy, untested, initial implementation, which only supports
    "macro_add" and "macro_list".
    
    Example:
    
    (qemu) macro_add mi "migrate -d tcp:localhost:4444"
    
    Signed-off-by: Luiz Capitulino <address@hidden>

diff --git a/monitor.c b/monitor.c
index 2566f4a..f8e2844 100644
--- a/monitor.c
+++ b/monitor.c
@@ -107,6 +107,15 @@ struct Monitor {
     QLIST_ENTRY(Monitor) entry;
 };
 
+typedef struct MonitorMacro {
+    QTAILQ_ENTRY(MonitorMacro) entry;
+    const char *name;
+    const char *command_line;
+} MonitorMacro;
+
+static QTAILQ_HEAD(monitor_macros, MonitorMacro) monitor_macros = 
+    QTAILQ_HEAD_INITIALIZER(monitor_macros);
+
 static QLIST_HEAD(mon_list, Monitor) mon_list;
 
 static const mon_cmd_t mon_cmds[];
@@ -1909,6 +1918,25 @@ static void do_closefd(Monitor *mon, const QDict *qdict)
                    fdname);
 }
 
+static void do_macro_add(Monitor *mon, const QDict *qdict)
+{
+    MonitorMacro *macro;
+
+    macro = qemu_mallocz(sizeof(*macro));
+    macro->name = qemu_strdup(qdict_get_str(qdict, "name"));
+    macro->command_line = qemu_strdup(qdict_get_str(qdict, "command"));
+
+    QTAILQ_INSERT_TAIL(&monitor_macros, macro, entry);
+}
+
+static void do_macro_list(Monitor *mon, const QDict *qdict)
+{
+    MonitorMacro *macro;
+
+    QTAILQ_FOREACH(macro, &monitor_macros, entry)
+        monitor_printf(mon, "%s: \"%s\"\n", macro->name, macro->command_line);
+}
+
 static void do_loadvm(Monitor *mon, const QDict *qdict)
 {
     int saved_vm_running  = vm_running;
@@ -2902,6 +2930,45 @@ static char *key_get_info(const char *type, char **key)
     return ++p;
 }
 
+static const mon_cmd_t *find_command(const char *cmdname)
+{
+    const mon_cmd_t *cmd;
+
+    /* find the command */
+    for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
+        if (compare_cmd(cmdname, cmd->name))
+            return cmd;
+    }
+
+    return NULL;
+}
+
+static const mon_cmd_t *find_macro(char *cmdname, size_t len, const char **pos)
+{
+    const char *p;
+    MonitorMacro *macro;
+    const mon_cmd_t *cmd;
+
+    QTAILQ_FOREACH(macro, &monitor_macros, entry) {
+        if (strcmp(macro->name, cmdname) == 0)
+            break;
+    }
+
+    if (!macro)
+        return NULL;
+
+    p = get_command_name(macro->command_line, cmdname, len);
+    if (!p)
+        return NULL;
+
+    cmd = find_command(cmdname);
+    if (!cmd)
+        return NULL;
+
+    *pos = p;
+    return cmd;
+}
+
 static int default_fmt_format = 'x';
 static int default_fmt_size = 4;
 
@@ -2927,15 +2994,13 @@ static const mon_cmd_t *monitor_parse_command(Monitor 
*mon,
     if (!p)
         return NULL;
 
-    /* find the command */
-    for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
-        if (compare_cmd(cmdname, cmd->name))
-            break;
-    }
-
-    if (cmd->name == NULL) {
-        monitor_printf(mon, "unknown command: '%s'\n", cmdname);
-        return NULL;
+    cmd = find_macro(cmdname, sizeof(cmdname), &p);
+    if (!cmd) {
+        cmd = find_command(cmdname);
+        if (!cmd) {
+            monitor_printf(mon, "unknown command: '%s'\n", cmdname);
+            return NULL;
+        }
     }
 
     /* parse the parameters */
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 29999c6..37561be 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -1031,6 +1031,30 @@ Close the file descriptor previously assigned to 
@var{fdname} using the
 used by another monitor command.
 ETEXI
 
+    {
+        .name       = "macro_add",
+        .args_type  = "name:s,command:s",
+        .params     = "name command",
+        .help       = "add a new monitor macro",
+        .mhandler.cmd = do_macro_add,
+    },
+
+STEXI
address@hidden macro_add @var{name} @var{command}
+ETEXI
+
+    {
+        .name       = "macro_list",
+        .args_type  = "",
+        .params     = "",
+        .help       = "list monitor macros",
+        .mhandler.cmd = do_macro_list,
+    },
+
+STEXI
address@hidden macro_list
+ETEXI
+
 STEXI
 @end table
 ETEXI




reply via email to

[Prev in Thread] Current Thread [Next in Thread]