diff mbox

add command to position mouse pointer in absolute mode

Message ID 20140605232528.GA2566@amt.cnet
State New
Headers show

Commit Message

Marcelo Tosatti June 5, 2014, 11:25 p.m. UTC
Add monitor command to change mouse cursor position when input 
device is in absolute mode.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

---
 hmp-commands.hx |   22 +++++++++++++++++++---
 monitor.c       |   35 ++++++++++++++++++++++++++++++++++-
 2 files changed, 53 insertions(+), 4 deletions(-)

Comments

Gerd Hoffmann June 10, 2014, 8:25 a.m. UTC | #1
Hi,

> +        .name       = "mouse_move_abs",
> +        .args_type  = "dx_str:s,dy_str:s,dz_str:s?",
> +        .params     = "dx dy [dz]",
> +        .help       = "send mouse move events (absolute coordinates)",
> +        .mhandler.cmd = do_mouse_move_abs,
> +    },
> +
> +STEXI
> +@item mouse_move_abs @var{dx} @var{dy} [@var{dz}]

I think we should drop the dz parameter (you still can send mouse wheel
events via mouse_move 0 0 dz), and add a optional console parameter
instead ...

> +static void do_mouse_move_abs(Monitor *mon, const QDict *qdict)
> +{
> +    int dx, dy, dz, button;
> +    const char *dx_str = qdict_get_str(qdict, "dx_str");
> +    const char *dy_str = qdict_get_str(qdict, "dy_str");
> +    const char *dz_str = qdict_get_try_str(qdict, "dz_str");
> +    int weight, height;

... then pick the console here (if specified):

   QemuConsole *con = NULL;
   if (qdict_get_try_str(qdict, "console")) {
      con = qemu_console_lookup_by_index(...)

That's a new hmp-only command tough.  IIRC there is (or was?) a policy
that no new hmp-only commands are allowed.  Luiz?


A completely different approach would be a qmp command allowing to send
any input event.  Given that the new input layer already uses qapi-types
internally this should be pretty straight forward to do (see InputEvent
in qapi-schema.json).


cheers,
  Gerd
Marcelo Tosatti June 10, 2014, 11:48 a.m. UTC | #2
On Tue, Jun 10, 2014 at 10:25:47AM +0200, Gerd Hoffmann wrote:
>   Hi,
> 
> > +        .name       = "mouse_move_abs",
> > +        .args_type  = "dx_str:s,dy_str:s,dz_str:s?",
> > +        .params     = "dx dy [dz]",
> > +        .help       = "send mouse move events (absolute coordinates)",
> > +        .mhandler.cmd = do_mouse_move_abs,
> > +    },
> > +
> > +STEXI
> > +@item mouse_move_abs @var{dx} @var{dy} [@var{dz}]
> 
> I think we should drop the dz parameter (you still can send mouse wheel
> events via mouse_move 0 0 dz), and add a optional console parameter
> instead ...
> 
> > +static void do_mouse_move_abs(Monitor *mon, const QDict *qdict)
> > +{
> > +    int dx, dy, dz, button;
> > +    const char *dx_str = qdict_get_str(qdict, "dx_str");
> > +    const char *dy_str = qdict_get_str(qdict, "dy_str");
> > +    const char *dz_str = qdict_get_try_str(qdict, "dz_str");
> > +    int weight, height;
> 
> ... then pick the console here (if specified):
> 
>    QemuConsole *con = NULL;
>    if (qdict_get_try_str(qdict, "console")) {
>       con = qemu_console_lookup_by_index(...)
> 
> That's a new hmp-only command tough.  IIRC there is (or was?) a policy
> that no new hmp-only commands are allowed.  Luiz?
> 
> 
> A completely different approach would be a qmp command allowing to send
> any input event.  Given that the new input layer already uses qapi-types
> internally this should be pretty straight forward to do (see InputEvent
> in qapi-schema.json).

I was just adding a new parameter to sendkey to allow "press"/"release"
behaviour, which is not accepted ATM. 
Will go for a new QMP command, then, thanks.
Marcelo Tosatti June 10, 2014, 11:53 a.m. UTC | #3
On Tue, Jun 10, 2014 at 08:48:23AM -0300, Marcelo Tosatti wrote:
> On Tue, Jun 10, 2014 at 10:25:47AM +0200, Gerd Hoffmann wrote:
> >   Hi,
> > 
> > > +        .name       = "mouse_move_abs",
> > > +        .args_type  = "dx_str:s,dy_str:s,dz_str:s?",
> > > +        .params     = "dx dy [dz]",
> > > +        .help       = "send mouse move events (absolute coordinates)",
> > > +        .mhandler.cmd = do_mouse_move_abs,
> > > +    },
> > > +
> > > +STEXI
> > > +@item mouse_move_abs @var{dx} @var{dy} [@var{dz}]
> > 
> > I think we should drop the dz parameter (you still can send mouse wheel
> > events via mouse_move 0 0 dz), and add a optional console parameter
> > instead ...
> > 
> > > +static void do_mouse_move_abs(Monitor *mon, const QDict *qdict)
> > > +{
> > > +    int dx, dy, dz, button;
> > > +    const char *dx_str = qdict_get_str(qdict, "dx_str");
> > > +    const char *dy_str = qdict_get_str(qdict, "dy_str");
> > > +    const char *dz_str = qdict_get_try_str(qdict, "dz_str");
> > > +    int weight, height;
> > 
> > ... then pick the console here (if specified):
> > 
> >    QemuConsole *con = NULL;
> >    if (qdict_get_try_str(qdict, "console")) {
> >       con = qemu_console_lookup_by_index(...)
> > 
> > That's a new hmp-only command tough.  IIRC there is (or was?) a policy
> > that no new hmp-only commands are allowed.  Luiz?
> > 
> > 
> > A completely different approach would be a qmp command allowing to send
> > any input event.  Given that the new input layer already uses qapi-types
> > internally this should be pretty straight forward to do (see InputEvent
> > in qapi-schema.json).
> 
> I was just adding a new parameter to sendkey to allow "press"/"release"
> behaviour, which is not accepted ATM. 
> Will go for a new QMP command, then, thanks.
> 

You want console parameter to be console index? Is that visible via
monitor?
Gerd Hoffmann June 10, 2014, 12:19 p.m. UTC | #4
Hi,

> You want console parameter to be console index? Is that visible via
> monitor?

The consoles are visible in the qom tree,
under /backend/console[$index].  They have a device link and head
property, so you can figure which console belongs to which device and
display.

I think using a console index is fine.  Luiz, agree?  Other/better
suggestions?

I think the command should take a list of events.  Send all events to
the guest via qemu_input_event_send, finally call qemu_input_event_sync.

cheers,
  Gerd
Eric Blake June 10, 2014, 12:38 p.m. UTC | #5
On 06/10/2014 02:25 AM, Gerd Hoffmann wrote:

>    QemuConsole *con = NULL;
>    if (qdict_get_try_str(qdict, "console")) {
>       con = qemu_console_lookup_by_index(...)
> 
> That's a new hmp-only command tough.  IIRC there is (or was?) a policy
> that no new hmp-only commands are allowed.  Luiz?

Correct - please expose this through QMP.
Markus Armbruster June 12, 2014, 7:12 a.m. UTC | #6
Gerd Hoffmann <kraxel@redhat.com> writes:

>   Hi,
>
>> +        .name       = "mouse_move_abs",
>> +        .args_type  = "dx_str:s,dy_str:s,dz_str:s?",
>> +        .params     = "dx dy [dz]",
>> +        .help       = "send mouse move events (absolute coordinates)",
>> +        .mhandler.cmd = do_mouse_move_abs,
>> +    },
>> +
>> +STEXI
>> +@item mouse_move_abs @var{dx} @var{dy} [@var{dz}]
>
> I think we should drop the dz parameter (you still can send mouse wheel
> events via mouse_move 0 0 dz), and add a optional console parameter
> instead ...
>
>> +static void do_mouse_move_abs(Monitor *mon, const QDict *qdict)
>> +{
>> +    int dx, dy, dz, button;
>> +    const char *dx_str = qdict_get_str(qdict, "dx_str");
>> +    const char *dy_str = qdict_get_str(qdict, "dy_str");
>> +    const char *dz_str = qdict_get_try_str(qdict, "dz_str");
>> +    int weight, height;
>
> ... then pick the console here (if specified):
>
>    QemuConsole *con = NULL;
>    if (qdict_get_try_str(qdict, "console")) {
>       con = qemu_console_lookup_by_index(...)
>
> That's a new hmp-only command tough.  IIRC there is (or was?) a policy
> that no new hmp-only commands are allowed.  Luiz?

HMP-only commands are okay only when the functionality they provide does
not make sense in QMP.

For anything else, we need a QMP command first.  The command proper is
generally a thin wrapper around an equivalent internal C function.  If
an HMP command is desired, it should call that C function.

[...]
diff mbox

Patch

Index: qemu/hmp-commands.hx
===================================================================
--- qemu.orig/hmp-commands.hx	2014-06-05 20:21:32.310919549 -0300
+++ qemu/hmp-commands.hx	2014-06-05 20:21:44.582879764 -0300
@@ -703,18 +703,34 @@ 
         .name       = "mouse_move",
         .args_type  = "dx_str:s,dy_str:s,dz_str:s?",
         .params     = "dx dy [dz]",
-        .help       = "send mouse move events",
-        .mhandler.cmd = do_mouse_move,
+        .help       = "send mouse move events (relative coordinates)",
+        .mhandler.cmd = do_mouse_move_rel,
     },
 
 STEXI
 @item mouse_move @var{dx} @var{dy} [@var{dz}]
 @findex mouse_move
-Move the active mouse to the specified coordinates @var{dx} @var{dy}
+Move the active mouse to the specified relative coordinates @var{dx} @var{dy}
 with optional scroll axis @var{dz}.
 ETEXI
 
     {
+        .name       = "mouse_move_abs",
+        .args_type  = "dx_str:s,dy_str:s,dz_str:s?",
+        .params     = "dx dy [dz]",
+        .help       = "send mouse move events (absolute coordinates)",
+        .mhandler.cmd = do_mouse_move_abs,
+    },
+
+STEXI
+@item mouse_move_abs @var{dx} @var{dy} [@var{dz}]
+@findex mouse_move_abs
+Move the active mouse to the specified absolute coordinates @var{dx} @var{dy}
+with optional scroll axis @var{dz}.
+ETEXI
+
+
+    {
         .name       = "mouse_button",
         .args_type  = "button_state:i",
         .params     = "state",
Index: qemu/monitor.c
===================================================================
--- qemu.orig/monitor.c	2014-06-05 20:21:32.313919539 -0300
+++ qemu/monitor.c	2014-06-05 20:21:44.583879761 -0300
@@ -1436,7 +1436,7 @@ 
 
 static int mouse_button_state;
 
-static void do_mouse_move(Monitor *mon, const QDict *qdict)
+static void do_mouse_move_rel(Monitor *mon, const QDict *qdict)
 {
     int dx, dy, dz, button;
     const char *dx_str = qdict_get_str(qdict, "dx_str");
@@ -1450,6 +1450,39 @@ 
 
     if (dz_str) {
         dz = strtol(dz_str, NULL, 0);
+        if (dz != 0) {
+            button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
+            qemu_input_queue_btn(NULL, button, true);
+            qemu_input_event_sync();
+            qemu_input_queue_btn(NULL, button, false);
+        }
+    }
+    qemu_input_event_sync();
+}
+
+static void do_mouse_move_abs(Monitor *mon, const QDict *qdict)
+{
+    int dx, dy, dz, button;
+    const char *dx_str = qdict_get_str(qdict, "dx_str");
+    const char *dy_str = qdict_get_str(qdict, "dy_str");
+    const char *dz_str = qdict_get_try_str(qdict, "dz_str");
+    int weight, height;
+
+    weight = qemu_console_get_width(NULL, 0);
+    height = qemu_console_get_height(NULL, 0);
+
+    if (!height || !weight) {
+        monitor_printf(mon, "failed to retrieve active console size\n");
+        return;
+    }
+
+    dx = strtol(dx_str, NULL, 0);
+    dy = strtol(dy_str, NULL, 0);
+    qemu_input_queue_abs(NULL, INPUT_AXIS_X, dx, weight);
+    qemu_input_queue_abs(NULL, INPUT_AXIS_Y, dy, height);
+
+    if (dz_str) {
+        dz = strtol(dz_str, NULL, 0);
         if (dz != 0) {
             button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
             qemu_input_queue_btn(NULL, button, true);