[RFC] dix: Re-introduce rescaling on motion events for extended event reporting

Peter Hutterer mailinglists at who-t.net
Tue Dec 18 15:08:06 PST 2007


Magnus Vigerlöf wrote:
> Since the work to correct this is postponed for some time I propose
> an interim solution where we get back the scaling so devices can
> register any values on X&Y and not be tied to the changing values of
> the screen size.
> 
> The patch below is tested with a Wacom tablet and works well with my
> Volito 2 both as a pointer on the desktop and as a pressure-sensitive,
> high-resolution pen in Gimp. At the same time my synaptic touchpad and
> USB mouse worked as before.
> 
> This time I haven't introduced any interface changes. The values that
> should be reported for the device are the same as in xserver 1.3,
> including the max-values on X&Y. The drivers that has been adapted to
> cope with the current situation will continue to work as the max-value
> registered by the driver is used in the scaling.


one thing: in the proposed patch, pDev->valuator->lastx/lasty are set
before the call to miPointerSetPosition. lastx/lasty of the VCP however
afterwards.
miPSP may change x/y if there was a screen switch. so you may end up
with different coordinates here.

could this be a problem? I've looked at the code several times but I'm
still unsure.

aside from that, I'd say its fine.

> The only worry I have with this patch is the check for if we should
> scale or not. The devices I have in my system that shouldn't scale all
> have '-1' as max and this is what's used to detect this situation. Is
> that safe?

this should be fine. I vaguely remember the server relying on -1
somewhere as well. although I don't know where that was anymore or
whether it was just a feverish nightmare.

> [1] https://bugs.freedesktop.org/show_bug.cgi?id=10324
> 
> ---
>  dix/getevents.c |   54 +++++++++++++++++++++++++++++++++++++++++-------------
>  1 files changed, 41 insertions(+), 13 deletions(-)
> 
> diff --git a/dix/getevents.c b/dix/getevents.c
> index 6e840d4..d562e18 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -528,6 +528,7 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
>      DeviceIntPtr cp = inputInfo.pointer;
>      int x = 0, y = 0;
>      Bool coreOnly = (pDev == inputInfo.pointer);
> +    ScreenPtr scr = miPointerGetScreen(pDev);
>  
>      /* Sanity checks. */
>      if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
> @@ -593,15 +594,33 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
>                                valuators);
>  
>          if (pDev->coreEvents) {
> -            if (first_valuator == 0 && num_valuators >= 1)
> -                x = cp->valuator->lastx + valuators[0];
> +            /* Get and convert the core pointer coordinate space into
> +             * device coordinates. Use the device coords if it translates
> +             * into the same position as the core to preserve relative sub-
> +             * pixel movements from the device. */
> +            int max = pDev->valuator->axes[0].max_value;
> +            if(max > 0) {
> +                x = pDev->valuator->lastx;
> +                if((int)((float)(x)*scr->width/(max+1)) != cp->valuator->lastx)
> +                    x = (int)((float)(cp->valuator->lastx)*(max+1)/scr->width);
> +            }
>              else
>                  x = cp->valuator->lastx;
>  
> -            if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
> -                y = cp->valuator->lasty + valuators[1 - first_valuator];
> +            max = pDev->valuator->axes[1].max_value;
> +            if(max > 0) {
> +                y = pDev->valuator->lasty;
> +                if((int)((float)(y)*scr->height/(max+1)) != cp->valuator->lasty)
> +                    y = (int)((float)(cp->valuator->lasty)*(max+1)/scr->height);
> +            }
>              else
>                  y = cp->valuator->lasty;
> +
> +            /* Add relative movement */
> +            if (first_valuator == 0 && num_valuators >= 1)
> +                x += valuators[0];
> +            if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
> +                y += valuators[1 - first_valuator];
>          }
>          else {
>              if (first_valuator == 0 && num_valuators >= 1)
> @@ -620,11 +639,6 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
>      clipAxis(pDev, 0, &x);
>      clipAxis(pDev, 1, &y);
>  
> -    /* This takes care of crossing screens for us, as well as clipping
> -     * to the current screen.  Right now, we only have one history buffer,
> -     * so we don't set this for both the device and core.*/
> -    miPointerSetPosition(pDev, &x, &y, ms);
> -
>      /* Drop x and y back into the valuators list, if they were originally
>       * present. */
>      if (first_valuator == 0 && num_valuators >= 1)
> @@ -634,12 +648,26 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
>  
>      updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
>  
> +    pDev->valuator->lastx = x;
> +    pDev->valuator->lasty = y;
> +    /* Convert the dev coord back to screen coord if we're
> +     * sending core events */
> +    if (pDev->coreEvents) {
> +        if(pDev->valuator->axes[0].max_value > 0)
> +            x = (int)((float)(x)*scr->width/(pDev->valuator->axes[0].max_value+1));
> +        if(pDev->valuator->axes[1].max_value > 0)
> +            y = (int)((float)(y)*scr->height/(pDev->valuator->axes[1].max_value+1));
> +    }
> +
> +    /* This takes care of crossing screens for us, as well as clipping
> +     * to the current screen.  Right now, we only have one history buffer,
> +     * so we don't set this for both the device and core.*/
> +    miPointerSetPosition(pDev, &x, &y, ms);
> +
>      if (pDev->coreEvents) {
>          cp->valuator->lastx = x;
>          cp->valuator->lasty = y;
>      }
> -    pDev->valuator->lastx = x;
> -    pDev->valuator->lasty = y;
>  
>      /* for some reason inputInfo.pointer does not have coreEvents set */
>      if (coreOnly || pDev->coreEvents) {
> @@ -677,8 +705,8 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
>              kbp->detail = pDev->button->map[buttons];
>          }
>  
> -        kbp->root_x = x;
> -        kbp->root_y = y;
> +        kbp->root_x = pDev->valuator->lastx;
> +        kbp->root_y = pDev->valuator->lasty;
>  
>          events++;
>          if (num_valuators) {






More information about the xorg mailing list