diff mbox

[20/42] input: mouse: add graphic_rotate support

Message ID 1390903055-479-21-git-send-email-kraxel@redhat.com
State New
Headers show

Commit Message

Gerd Hoffmann Jan. 28, 2014, 9:57 a.m. UTC
Transform absolute mouse events according to graphic_rotate.

Legacy input code does it for both absolute and relative events,
but the logic is broken for relative coordinates, so this is
most likely not used anyway.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/input.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

Comments

Paolo Bonzini Jan. 31, 2014, 10:23 p.m. UTC | #1
Il 28/01/2014 10:57, Gerd Hoffmann ha scritto:
> Transform absolute mouse events according to graphic_rotate.
>
> Legacy input code does it for both absolute and relative events,
> but the logic is broken for relative coordinates, so this is
> most likely not used anyway.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  ui/input.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
>
> diff --git a/ui/input.c b/ui/input.c
> index a02172e..2c4d4d6 100644
> --- a/ui/input.c
> +++ b/ui/input.c
> @@ -50,6 +50,33 @@ qemu_input_find_handler(uint32_t mask)
>      return NULL;
>  }
>
> +static void qemu_input_transform_abs_rotate(InputEvent *evt)
> +{
> +    switch (graphic_rotate) {
> +    case 90:
> +        if (evt->abs->axis == INPUT_AXIS_X) {
> +            evt->abs->axis = INPUT_AXIS_Y;
> +        }
> +        if (evt->abs->axis == INPUT_AXIS_Y) {

Need else here, same for "case 270".

> +            evt->abs->axis = INPUT_AXIS_X;
> +            evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis;

->value here, not ->axis.

It looks like doing it right for relative is easy:

     if (graphic_rotate == 0) {
         return;
     }
     if (move->axis != INPUT_AXIS_X && move->axis != INPUT_AXIS_Y) {
         return;
     }
     if ((graphic_rotate <= 180 && move->axis == INPUT_AXIS_X) ||
         (graphic_rotate >= 180 && move->axis == INPUT_AXIS_Y)) {
          if (kind == INPUT_EVENT_KIND_ABS) {
              move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
          } else {
              move->value = -move->value;
          }
     }
     if (graphic_rotate == 90 || graphic_rotate == 270) {
         move->axis ^= INPUT_AXIS_X ^ INPUT_AXIS_Y;
     }

...

     if (evt->kind == INPUT_EVENT_KIND_ABS) {
         qemu_input_transform_rotate(evt->kind, &evt->abs);
     } else if (evt->kind == INPUT_EVENT_KIND_REL) {
         qemu_input_transform_rotate(evt->kind, &evt->rel);
     }

Paolo

> +        }
> +        break;
> +    case 180:
> +        evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis;
> +        break;
> +    case 270:
> +        if (evt->abs->axis == INPUT_AXIS_X) {
> +            evt->abs->axis = INPUT_AXIS_Y;
> +            evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis;
> +        }
> +        if (evt->abs->axis == INPUT_AXIS_Y) {
> +            evt->abs->axis = INPUT_AXIS_X;
> +        }
> +        break;
> +    }
> +}
> +
>  void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
>  {
>      QemuInputHandlerState *s;
> @@ -58,6 +85,12 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
>          return;
>      }
>
> +    /* pre processing */
> +    if (graphic_rotate && (evt->kind == INPUT_EVENT_KIND_ABS)) {
> +            qemu_input_transform_abs_rotate(evt);
> +    }
> +
> +    /* send event */
>      s = qemu_input_find_handler(1 << evt->kind);
>      s->handler->event(s->dev, src, evt);
>      s->events++;
>
Gerd Hoffmann Feb. 3, 2014, 9:42 a.m. UTC | #2
Hi,

> > +    switch (graphic_rotate) {
> > +    case 90:
> > +        if (evt->abs->axis == INPUT_AXIS_X) {
> > +            evt->abs->axis = INPUT_AXIS_Y;
> > +        }
> > +        if (evt->abs->axis == INPUT_AXIS_Y) {
> 
> Need else here, same for "case 270".

Why?

> > +            evt->abs->axis = INPUT_AXIS_X;
> > +            evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis;
> 
> ->value here, not ->axis.

Oops, indeed.

> It looks like doing it right for relative is easy:

But what is the point when this isn't used anyway?

> 
>      if (graphic_rotate == 0) {
>          return;
>      }
>      if (move->axis != INPUT_AXIS_X && move->axis != INPUT_AXIS_Y) {
>          return;
>      }
>      if ((graphic_rotate <= 180 && move->axis == INPUT_AXIS_X) ||
>          (graphic_rotate >= 180 && move->axis == INPUT_AXIS_Y)) {
>           if (kind == INPUT_EVENT_KIND_ABS) {
>               move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
>           } else {
>               move->value = -move->value;
>           }
>      }
>      if (graphic_rotate == 90 || graphic_rotate == 270) {
>          move->axis ^= INPUT_AXIS_X ^ INPUT_AXIS_Y;
>      }

Saves a few lines but it's a bit harder to figure what is going on ...

cheers,
  Gerd
Paolo Bonzini Feb. 3, 2014, 9:45 a.m. UTC | #3
Il 03/02/2014 10:42, Gerd Hoffmann ha scritto:
>   Hi,
>
>>> +    switch (graphic_rotate) {
>>> +    case 90:
>>> +        if (evt->abs->axis == INPUT_AXIS_X) {
>>> +            evt->abs->axis = INPUT_AXIS_Y;
>>> +        }
>>> +        if (evt->abs->axis == INPUT_AXIS_Y) {
>>
>> Need else here, same for "case 270".
>
> Why?

Because otherwise both axes become X.  When the first if triggers the 
axis changes to Y, and then it becomes X again. :)

>>> +            evt->abs->axis = INPUT_AXIS_X;
>>> +            evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis;
>>
>> ->value here, not ->axis.
>
> Oops, indeed.
>
>> It looks like doing it right for relative is easy:
>
> But what is the point when this isn't used anyway?

In what sense it is not used?  Because you do not have e.g. a USB 
controller in the only machines that support graphic_rotate?

Paolo

>>
>>      if (graphic_rotate == 0) {
>>          return;
>>      }
>>      if (move->axis != INPUT_AXIS_X && move->axis != INPUT_AXIS_Y) {
>>          return;
>>      }
>>      if ((graphic_rotate <= 180 && move->axis == INPUT_AXIS_X) ||
>>          (graphic_rotate >= 180 && move->axis == INPUT_AXIS_Y)) {
>>           if (kind == INPUT_EVENT_KIND_ABS) {
>>               move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
>>           } else {
>>               move->value = -move->value;
>>           }
>>      }
>>      if (graphic_rotate == 90 || graphic_rotate == 270) {
>>          move->axis ^= INPUT_AXIS_X ^ INPUT_AXIS_Y;
>>      }
>
> Saves a few lines but it's a bit harder to figure what is going on ...
>
> cheers,
>   Gerd
>
>
Gerd Hoffmann Feb. 3, 2014, 9:53 a.m. UTC | #4
Hi,

> >> It looks like doing it right for relative is easy:
> >
> > But what is the point when this isn't used anyway?
> 
> In what sense it is not used?

Old code is obviously broken for the relative case.

Seems to be used by hw/arm/spitz.c, which probably
emulates a absolute pointing device.  Machine type
name contains 'PDA', so I guess a touch screen ...

cheers,
  Gerd
diff mbox

Patch

diff --git a/ui/input.c b/ui/input.c
index a02172e..2c4d4d6 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -50,6 +50,33 @@  qemu_input_find_handler(uint32_t mask)
     return NULL;
 }
 
+static void qemu_input_transform_abs_rotate(InputEvent *evt)
+{
+    switch (graphic_rotate) {
+    case 90:
+        if (evt->abs->axis == INPUT_AXIS_X) {
+            evt->abs->axis = INPUT_AXIS_Y;
+        }
+        if (evt->abs->axis == INPUT_AXIS_Y) {
+            evt->abs->axis = INPUT_AXIS_X;
+            evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis;
+        }
+        break;
+    case 180:
+        evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis;
+        break;
+    case 270:
+        if (evt->abs->axis == INPUT_AXIS_X) {
+            evt->abs->axis = INPUT_AXIS_Y;
+            evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis;
+        }
+        if (evt->abs->axis == INPUT_AXIS_Y) {
+            evt->abs->axis = INPUT_AXIS_X;
+        }
+        break;
+    }
+}
+
 void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
 {
     QemuInputHandlerState *s;
@@ -58,6 +85,12 @@  void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
         return;
     }
 
+    /* pre processing */
+    if (graphic_rotate && (evt->kind == INPUT_EVENT_KIND_ABS)) {
+            qemu_input_transform_abs_rotate(evt);
+    }
+
+    /* send event */
     s = qemu_input_find_handler(1 << evt->kind);
     s->handler->event(s->dev, src, evt);
     s->events++;